diff --git a/packages/ui/src/elements/BulkUpload/AddingFilesView/index.tsx b/packages/ui/src/elements/BulkUpload/AddingFilesView/index.tsx
index db59591822a..20a1952aca4 100644
--- a/packages/ui/src/elements/BulkUpload/AddingFilesView/index.tsx
+++ b/packages/ui/src/elements/BulkUpload/AddingFilesView/index.tsx
@@ -29,6 +29,8 @@ export function AddingFilesView() {
hasPublishPermission,
hasSavePermission,
hasSubmitted,
+ resetUploadEdits,
+ updateUploadEdits,
} = useFormsManager()
const activeForm = forms[activeIndex]
const { getEntityConfig } = useConfig()
@@ -67,7 +69,12 @@ export function AddingFilesView() {
versionCount={0}
>
-
+
) : null}
diff --git a/packages/ui/src/elements/BulkUpload/EditForm/index.tsx b/packages/ui/src/elements/BulkUpload/EditForm/index.tsx
index 7c186d498bf..f1c4da6c28a 100644
--- a/packages/ui/src/elements/BulkUpload/EditForm/index.tsx
+++ b/packages/ui/src/elements/BulkUpload/EditForm/index.tsx
@@ -16,11 +16,10 @@ import { useEditDepth } from '../../../providers/EditDepth/index.js'
import { OperationProvider } from '../../../providers/Operation/index.js'
import { useRouteTransition } from '../../../providers/RouteTransition/index.js'
import { useServerFunctions } from '../../../providers/ServerFunctions/index.js'
-import { useUploadEdits } from '../../../providers/UploadEdits/index.js'
import { abortAndIgnore, handleAbortRef } from '../../../utilities/abortAndIgnore.js'
import { useDocumentDrawerContext } from '../../DocumentDrawer/Provider.js'
import { DocumentFields } from '../../DocumentFields/index.js'
-import { Upload } from '../../Upload/index.js'
+import { Upload_v4 } from '../../Upload/index.js'
import { useFormsManager } from '../FormsManager/index.js'
import { BulkUploadProvider } from '../index.js'
import './index.scss'
@@ -31,7 +30,12 @@ const baseClass = 'collection-edit'
// When rendered within a drawer, props are empty
// This is solely to support custom edit views which get server-rendered
-export function EditForm({ submitted }: EditFormProps) {
+export function EditForm({
+ resetUploadEdits,
+ submitted,
+ updateUploadEdits,
+ uploadEdits,
+}: EditFormProps) {
const {
action,
collectionSlug: docSlug,
@@ -62,7 +66,6 @@ export function EditForm({ submitted }: EditFormProps) {
const depth = useEditDepth()
const params = useSearchParams()
const { reportUpdate } = useDocumentEvents()
- const { resetUploadEdits } = useUploadEdits()
const { startRouteTransition } = useRouteTransition()
const locale = params.get('locale')
@@ -161,10 +164,13 @@ export function EditForm({ submitted }: EditFormProps) {
BeforeFields={
{CustomUpload || (
-
)}
@@ -185,7 +191,7 @@ function GetFieldProxy() {
const { getFields } = useForm()
const { getFormDataRef } = useFormsManager()
- React.useEffect(() => {
+ useEffect(() => {
getFormDataRef.current = getFields
}, [getFields, getFormDataRef])
diff --git a/packages/ui/src/elements/BulkUpload/EditForm/types.ts b/packages/ui/src/elements/BulkUpload/EditForm/types.ts
index 19083a07103..d975483a955 100644
--- a/packages/ui/src/elements/BulkUpload/EditForm/types.ts
+++ b/packages/ui/src/elements/BulkUpload/EditForm/types.ts
@@ -1,3 +1,5 @@
+import type { UploadProps_v4 } from '../../Upload/index.js'
+
export type EditFormProps = {
readonly submitted?: boolean
-}
+} & Pick
diff --git a/packages/ui/src/elements/BulkUpload/FormsManager/index.tsx b/packages/ui/src/elements/BulkUpload/FormsManager/index.tsx
index 713e25d98da..21159e87665 100644
--- a/packages/ui/src/elements/BulkUpload/FormsManager/index.tsx
+++ b/packages/ui/src/elements/BulkUpload/FormsManager/index.tsx
@@ -1,6 +1,12 @@
'use client'
-import type { Data, DocumentSlots, FormState, SanitizedDocumentPermissions } from 'payload'
+import type {
+ Data,
+ DocumentSlots,
+ FormState,
+ SanitizedDocumentPermissions,
+ UploadEdits,
+} from 'payload'
import { useModal } from '@faceless-ui/modal'
import { isImage } from 'payload/shared'
@@ -41,6 +47,7 @@ type FormsManagerContext = {
readonly hasSubmitted: boolean
readonly isInitializing: boolean
readonly removeFile: (index: number) => void
+ readonly resetUploadEdits?: () => void
readonly saveAllDocs: ({ overrides }?: { overrides?: Record }) => Promise
readonly setActiveIndex: (index: number) => void
readonly setFormTotalErrorCount: ({
@@ -52,6 +59,7 @@ type FormsManagerContext = {
}) => void
readonly thumbnailUrls: string[]
readonly totalErrorCount?: number
+ readonly updateUploadEdits: (args: UploadEdits) => void
}
const Context = React.createContext({
@@ -73,6 +81,7 @@ const Context = React.createContext({
setFormTotalErrorCount: () => {},
thumbnailUrls: [],
totalErrorCount: 0,
+ updateUploadEdits: () => {},
})
const initialState: State = {
@@ -242,6 +251,7 @@ export function FormsManagerProvider({ children }: FormsManagerProps) {
return {
errorCount: form.errorCount,
formState: currentFormsData,
+ uploadEdits: form.uploadEdits,
}
}
return form
@@ -295,6 +305,7 @@ export function FormsManagerProvider({ children }: FormsManagerProps) {
currentForms[activeIndex] = {
errorCount: currentForms[activeIndex].errorCount,
formState: currentFormsData,
+ uploadEdits: currentForms[activeIndex].uploadEdits,
}
const newDocs = []
@@ -306,7 +317,16 @@ export function FormsManagerProvider({ children }: FormsManagerProps) {
setLoadingText(t('general:uploadingBulk', { current: i + 1, total: currentForms.length }))
- const req = await fetch(actionURL, {
+ const actionURLWithParams = `${actionURL}${qs.stringify(
+ {
+ uploadEdits: form?.uploadEdits || undefined,
+ },
+ {
+ addQueryPrefix: true,
+ },
+ )}`
+
+ const req = await fetch(actionURLWithParams, {
body: await createFormData(
form.formState,
overrides,
@@ -478,6 +498,31 @@ export function FormsManagerProvider({ children }: FormsManagerProps) {
[collectionSlug, docPermissions, forms, getFormState, hasSubmitted],
)
+ const updateUploadEdits = React.useCallback(
+ (uploadEdits) => {
+ dispatch({
+ type: 'UPDATE_FORM',
+ errorCount: forms[activeIndex].errorCount,
+ formState: forms[activeIndex].formState,
+ index: activeIndex,
+ uploadEdits,
+ })
+ },
+ [activeIndex, forms],
+ )
+
+ const resetUploadEdits = React.useCallback(() => {
+ dispatch({
+ type: 'REPLACE',
+ state: {
+ forms: forms.map((form) => ({
+ ...form,
+ uploadEdits: {},
+ })),
+ },
+ })
+ }, [forms])
+
React.useEffect(() => {
if (!collectionSlug) {
return
@@ -529,11 +574,13 @@ export function FormsManagerProvider({ children }: FormsManagerProps) {
hasSubmitted,
isInitializing,
removeFile,
+ resetUploadEdits,
saveAllDocs,
setActiveIndex,
setFormTotalErrorCount,
thumbnailUrls: renderedThumbnails,
totalErrorCount,
+ updateUploadEdits,
}}
>
{isUploading && (
diff --git a/packages/ui/src/elements/BulkUpload/FormsManager/reducer.ts b/packages/ui/src/elements/BulkUpload/FormsManager/reducer.ts
index 8d2662709f1..cbbe28a9f75 100644
--- a/packages/ui/src/elements/BulkUpload/FormsManager/reducer.ts
+++ b/packages/ui/src/elements/BulkUpload/FormsManager/reducer.ts
@@ -1,10 +1,11 @@
-import type { FormState } from 'payload'
+import type { FormState, UploadEdits } from 'payload'
export type State = {
activeIndex: number
forms: {
errorCount: number
formState: FormState
+ uploadEdits?: UploadEdits
}[]
totalErrorCount: number
}
@@ -21,6 +22,7 @@ type Action =
index: number
type: 'UPDATE_FORM'
updatedFields?: Record
+ uploadEdits?: UploadEdits
}
| {
files: FileList
@@ -55,6 +57,7 @@ export function formsManagementReducer(state: State, action: Action): State {
value: action.files[i],
},
},
+ uploadEdits: {},
}
}
@@ -117,6 +120,10 @@ export function formsManagementReducer(state: State, action: Action): State {
...updatedForms[action.index].formState,
...action.formState,
},
+ uploadEdits: {
+ ...updatedForms[action.index].uploadEdits,
+ ...action.uploadEdits,
+ },
}
return {
diff --git a/packages/ui/src/elements/Upload/index.tsx b/packages/ui/src/elements/Upload/index.tsx
index 9316ff3ba4f..1796d4d3b5c 100644
--- a/packages/ui/src/elements/Upload/index.tsx
+++ b/packages/ui/src/elements/Upload/index.tsx
@@ -19,9 +19,9 @@ import { Drawer, DrawerToggler } from '../Drawer/index.js'
import { Dropzone } from '../Dropzone/index.js'
import { EditUpload } from '../EditUpload/index.js'
import { FileDetails } from '../FileDetails/index.js'
-import './index.scss'
import { PreviewSizes } from '../PreviewSizes/index.js'
import { Thumbnail } from '../Thumbnail/index.js'
+import './index.scss'
const baseClass = 'file-field'
export const editDrawerSlug = 'edit-upload'
@@ -91,7 +91,34 @@ export type UploadProps = {
}
export const Upload: React.FC = (props) => {
- const { collectionSlug, customActions, initialState, onChange, uploadConfig } = props
+ const { resetUploadEdits, updateUploadEdits, uploadEdits } = useUploadEdits()
+ return (
+
+ )
+}
+
+export type UploadProps_v4 = {
+ readonly resetUploadEdits?: () => void
+ readonly updateUploadEdits?: (args: UploadEdits) => void
+ readonly uploadEdits?: UploadEdits
+} & UploadProps
+
+export const Upload_v4: React.FC = (props) => {
+ const {
+ collectionSlug,
+ customActions,
+ initialState,
+ onChange,
+ resetUploadEdits,
+ updateUploadEdits,
+ uploadConfig,
+ uploadEdits,
+ } = props
const {
config: {
@@ -102,7 +129,6 @@ export const Upload: React.FC = (props) => {
const { t } = useTranslation()
const { setModified } = useForm()
- const { resetUploadEdits, updateUploadEdits, uploadEdits } = useUploadEdits()
const { id, docPermissions, savedDocumentData, setUploadStatus } = useDocumentInfo()
const isFormSubmitting = useFormProcessing()
const { errorMessage, setValue, showError, value } = useField({
diff --git a/packages/ui/src/providers/UploadEdits/index.tsx b/packages/ui/src/providers/UploadEdits/index.tsx
index 3f45a0dc373..610b83223c2 100644
--- a/packages/ui/src/providers/UploadEdits/index.tsx
+++ b/packages/ui/src/providers/UploadEdits/index.tsx
@@ -3,20 +3,26 @@ import type { UploadEdits } from 'payload'
import React from 'react'
+export type UploadEditsProviderProps = {
+ children: React.ReactNode
+ initialUploadEdits?: UploadEdits
+}
export type UploadEditsContext = {
+ getUploadEdits: () => UploadEdits
resetUploadEdits: () => void
updateUploadEdits: (edits: UploadEdits) => void
uploadEdits: UploadEdits
}
const Context = React.createContext({
+ getUploadEdits: () => undefined,
resetUploadEdits: undefined,
updateUploadEdits: undefined,
uploadEdits: undefined,
})
-export const UploadEditsProvider = ({ children }) => {
- const [uploadEdits, setUploadEdits] = React.useState(undefined)
+export const UploadEditsProvider = ({ children, initialUploadEdits }: UploadEditsProviderProps) => {
+ const [uploadEdits, setUploadEdits] = React.useState(initialUploadEdits || {})
const resetUploadEdits = () => {
setUploadEdits({})
@@ -29,7 +35,13 @@ export const UploadEditsProvider = ({ children }) => {
}))
}
- return {children}
+ const getUploadEdits = () => uploadEdits
+
+ return (
+
+ {children}
+
+ )
}
export const useUploadEdits = (): UploadEditsContext => React.use(Context)
diff --git a/packages/ui/src/views/Edit/index.tsx b/packages/ui/src/views/Edit/index.tsx
index 78a054cb396..3abe9f8cbfd 100644
--- a/packages/ui/src/views/Edit/index.tsx
+++ b/packages/ui/src/views/Edit/index.tsx
@@ -325,6 +325,7 @@ export function DefaultEditView({
isLockingEnabled,
setDocumentIsLocked,
startRouteTransition,
+ redirectAfterCreate,
],
)