feat: bulk upload (#7800)

## Description

Adds bulk upload functionality to upload enabled configs.

You can disable the ability by defining `upload.bulkUpload: false` in
your upload enabled config.

- [x] I have read and understand the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository.

## Type of change

- [x] New feature (non-breaking change which adds functionality)

## Checklist:

- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] Existing test suite passes locally with my changes
- [ ] I have made corresponding changes to the documentation
This commit is contained in:
Jarrod Flesch
2024-08-21 17:44:34 -04:00
committed by GitHub
parent af0105ced5
commit 1ee19d3016
63 changed files with 1936 additions and 5 deletions

View File

@@ -0,0 +1,106 @@
import type { FormState } from 'payload'
export type State = {
activeIndex: number
forms: {
errorCount: number
formState: FormState
}[]
totalErrorCount: number
}
type Action =
| {
count: number
index: number
type: 'UPDATE_ERROR_COUNT'
}
| {
files: FileList
initialState: FormState | null
type: 'ADD_FORMS'
}
| {
index: number
type: 'REMOVE_FORM'
}
| {
index: number
type: 'SET_ACTIVE_INDEX'
}
| {
state: Partial<State>
type: 'REPLACE'
}
export function formsManagementReducer(state: State, action: Action): State {
switch (action.type) {
case 'REPLACE': {
return {
...state,
...action.state,
}
}
case 'SET_ACTIVE_INDEX': {
return {
...state,
activeIndex: action.index,
}
}
case 'ADD_FORMS': {
const newForms: State['forms'] = []
for (let i = 0; i < action.files.length; i++) {
newForms[i] = {
errorCount: 0,
formState: {
...(action.initialState || {}),
file: {
initialValue: action.files[i],
valid: true,
value: action.files[i],
},
},
}
}
return {
...state,
activeIndex: 0,
forms: [...newForms, ...state.forms],
}
}
case 'REMOVE_FORM': {
const remainingFormStates = [...state.forms]
const [removedForm] = remainingFormStates.splice(action.index, 1)
const affectedByShift = state.activeIndex >= action.index
const nextIndex =
state.activeIndex === action.index
? action.index
: affectedByShift
? state.activeIndex - 1
: state.activeIndex
const boundedActiveIndex = Math.min(remainingFormStates.length - 1, nextIndex)
return {
...state,
activeIndex: affectedByShift ? boundedActiveIndex : state.activeIndex,
forms: remainingFormStates,
totalErrorCount: state.totalErrorCount - removedForm.errorCount,
}
}
case 'UPDATE_ERROR_COUNT': {
const forms = [...state.forms]
forms[action.index].errorCount = action.count
return {
...state,
forms,
totalErrorCount: state.forms.reduce((acc, form) => acc + form.errorCount, 0),
}
}
default: {
return state
}
}
}