diff --git a/packages/ui/src/elements/Upload/index.tsx b/packages/ui/src/elements/Upload/index.tsx index e96d46d5b..686a2ac73 100644 --- a/packages/ui/src/elements/Upload/index.tsx +++ b/packages/ui/src/elements/Upload/index.tsx @@ -1,13 +1,13 @@ 'use client' import type { FormState, SanitizedCollectionConfig, UploadEdits } from 'payload' -import { isImage, reduceFieldsToValues } from 'payload/shared' +import { isImage } from 'payload/shared' import React, { useCallback, useEffect, useRef, useState } from 'react' import { toast } from 'sonner' import { FieldError } from '../../fields/FieldError/index.js' import { fieldBaseClass } from '../../fields/shared/index.js' -import { useForm } from '../../forms/Form/index.js' +import { useForm, useFormProcessing } from '../../forms/Form/index.js' import { useField } from '../../forms/useField/index.js' import { useDocumentInfo } from '../../providers/DocumentInfo/index.js' import { EditDepthProvider } from '../../providers/EditDepth/index.js' @@ -94,15 +94,15 @@ export const Upload: React.FC = (props) => { const { t } = useTranslation() const { setModified } = useForm() const { resetUploadEdits, updateUploadEdits, uploadEdits } = useUploadEdits() - const { docPermissions } = useDocumentInfo() + const { docPermissions, savedDocumentData } = useDocumentInfo() + const isFormSubmitting = useFormProcessing() const { errorMessage, setValue, showError, value } = useField({ path: 'file', validate, }) - const [doc, setDoc] = useState(reduceFieldsToValues(initialState || {}, true)) const [fileSrc, setFileSrc] = useState(null) - const [replacingFile, setReplacingFile] = useState(false) + const [removedFile, setRemovedFile] = useState(false) const [filename, setFilename] = useState(value?.name || '') const [showUrlInput, setShowUrlInput] = useState(false) const [fileUrl, setFileUrl] = useState('') @@ -156,11 +156,10 @@ export const Upload: React.FC = (props) => { ) const handleFileRemoval = useCallback(() => { - setReplacingFile(true) + setRemovedFile(true) handleFileChange(null) setFileSrc('') setFileUrl('') - setDoc({}) resetUploadEdits() setShowUrlInput(false) }, [handleFileChange, resetUploadEdits]) @@ -192,11 +191,10 @@ export const Upload: React.FC = (props) => { } useEffect(() => { - setDoc(reduceFieldsToValues(initialState || {}, true)) if (initialState?.file?.value instanceof File) { setFileSrc(URL.createObjectURL(initialState.file.value)) + setRemovedFile(false) } - setReplacingFile(false) }, [initialState]) useEffect(() => { @@ -205,6 +203,12 @@ export const Upload: React.FC = (props) => { } }, [showUrlInput]) + useEffect(() => { + if (isFormSubmitting) { + setRemovedFile(false) + } + }, [isFormSubmitting]) + const canRemoveUpload = docPermissions?.update && 'delete' in docPermissions && docPermissions?.delete @@ -222,19 +226,19 @@ export const Upload: React.FC = (props) => { return (
- {doc.filename && !replacingFile && ( + {savedDocumentData && savedDocumentData.filename && !removedFile && ( )} - {(!doc.filename || replacingFile) && ( + {(!savedDocumentData?.filename || removedFile) && (
{!value && !showUrlInput && ( @@ -339,7 +343,7 @@ export const Upload: React.FC = (props) => {
@@ -356,17 +360,17 @@ export const Upload: React.FC = (props) => { )}
)} - {(value || doc.filename) && ( + {(value || savedDocumentData?.filename) && ( = (props) => { )} - {doc && hasImageSizes && ( + {savedDocumentData && hasImageSizes && ( - + )} diff --git a/packages/ui/src/providers/DocumentInfo/index.tsx b/packages/ui/src/providers/DocumentInfo/index.tsx index fe717cc92..6d1faecbc 100644 --- a/packages/ui/src/providers/DocumentInfo/index.tsx +++ b/packages/ui/src/providers/DocumentInfo/index.tsx @@ -42,7 +42,7 @@ const DocumentInfo: React.FC< hasPublishedDoc: hasPublishedDocFromProps, hasPublishPermission: hasPublishPermissionFromProps, hasSavePermission: hasSavePermissionFromProps, - initialData: data, + initialData, initialState, isLocked: isLockedFromProps, lastUpdateTime: lastUpdateTimeFromProps, @@ -84,7 +84,7 @@ const DocumentInfo: React.FC< const [documentTitle, setDocumentTitle] = useState(() => formatDocTitle({ collectionConfig, - data: { ...data, id }, + data: { ...(initialData || {}), id }, dateFormat, fallback: id?.toString(), globalConfig, @@ -105,8 +105,9 @@ const DocumentInfo: React.FC< const [documentIsLocked, setDocumentIsLocked] = useState(isLockedFromProps) const [currentEditor, setCurrentEditor] = useState(currentEditorFromProps) const [lastUpdateTime, setLastUpdateTime] = useState(lastUpdateTimeFromProps) + const [savedDocumentData, setSavedDocumentData] = useState(initialData) - const isInitializing = initialState === undefined || data === undefined + const isInitializing = initialState === undefined || initialData === undefined const { getPreference, setPreference } = usePreferences() const { code: locale } = useLocale() @@ -251,18 +252,25 @@ const DocumentInfo: React.FC< } }, [collectionConfig, globalConfig, versionCount]) + const updateSavedDocumentData = React.useCallback( + (json) => { + setSavedDocumentData(json) + }, + [], + ) + useEffect(() => { setDocumentTitle( formatDocTitle({ collectionConfig, - data: { ...data, id }, + data: { ...savedDocumentData, id }, dateFormat, fallback: id?.toString(), globalConfig, i18n, }), ) - }, [collectionConfig, globalConfig, data, dateFormat, i18n, id]) + }, [collectionConfig, globalConfig, savedDocumentData, dateFormat, i18n, id]) // clean on unmount useEffect(() => { @@ -306,12 +314,13 @@ const DocumentInfo: React.FC< hasPublishPermission, hasSavePermission, incrementVersionCount, - initialData: data, + initialData, initialState, isInitializing, lastUpdateTime, mostRecentVersionIsAutosaved, preferencesKey, + savedDocumentData, setCurrentEditor, setDocFieldPreferences, setDocumentIsLocked, @@ -324,6 +333,7 @@ const DocumentInfo: React.FC< unlockDocument, unpublishedVersionCount, updateDocumentEditor, + updateSavedDocumentData, versionCount, } diff --git a/packages/ui/src/providers/DocumentInfo/types.ts b/packages/ui/src/providers/DocumentInfo/types.ts index 9116b70ea..f83fbcdd9 100644 --- a/packages/ui/src/providers/DocumentInfo/types.ts +++ b/packages/ui/src/providers/DocumentInfo/types.ts @@ -57,6 +57,7 @@ export type DocumentInfoContext = { lastUpdateTime?: number mostRecentVersionIsAutosaved: boolean preferencesKey?: string + savedDocumentData?: Data setCurrentEditor?: React.Dispatch> setDocFieldPreferences: ( field: string, @@ -72,5 +73,6 @@ export type DocumentInfoContext = { unlockDocument: (docId: number | string, slug: string) => Promise unpublishedVersionCount: number updateDocumentEditor: (docId: number | string, slug: string, user: ClientUser) => Promise + updateSavedDocumentData: (data: Data) => void versionCount: number } & DocumentInfoProps diff --git a/packages/ui/src/views/Edit/index.tsx b/packages/ui/src/views/Edit/index.tsx index 0c8fd84ba..b79b4b860 100644 --- a/packages/ui/src/views/Edit/index.tsx +++ b/packages/ui/src/views/Edit/index.tsx @@ -71,17 +71,18 @@ export const DefaultEditView: React.FC = ({ hasPublishPermission, hasSavePermission, incrementVersionCount, - initialData: data, initialState, isEditing, isInitializing, lastUpdateTime, redirectAfterDelete, redirectAfterDuplicate, + savedDocumentData, setCurrentEditor, setDocumentIsLocked, unlockDocument, updateDocumentEditor, + updateSavedDocumentData, } = useDocumentInfo() const { @@ -212,6 +213,10 @@ export const DefaultEditView: React.FC = ({ incrementVersionCount() + if (typeof updateSavedDocumentData === 'function') { + void updateSavedDocumentData(json?.doc || {}) + } + if (typeof onSaveFromContext === 'function') { void onSaveFromContext({ ...json, @@ -238,6 +243,7 @@ export const DefaultEditView: React.FC = ({ await getDocPermissions(json) }, [ + updateSavedDocumentData, reportUpdate, id, entitySlug, @@ -479,7 +485,7 @@ export const DefaultEditView: React.FC = ({ SaveButton, SaveDraftButton, }} - data={data} + data={savedDocumentData} disableActions={disableActions} disableCreate={disableCreate} hasPublishPermission={hasPublishPermission} @@ -521,7 +527,7 @@ export const DefaultEditView: React.FC = ({ className={`${baseClass}__auth`} collectionSlug={collectionConfig.slug} disableLocalStrategy={collectionConfig.auth?.disableLocalStrategy} - email={data?.email} + email={savedDocumentData?.email} loginWithUsername={auth?.loginWithUsername} operation={operation} readOnly={!hasSavePermission} @@ -529,7 +535,7 @@ export const DefaultEditView: React.FC = ({ setSchemaPathSegments={setSchemaPathSegments} setValidateBeforeSubmit={setValidateBeforeSubmit} useAPIKey={auth.useAPIKey} - username={data?.username} + username={savedDocumentData?.username} verify={auth.verify} /> )}