Skip to content

Commit 661f450

Browse files
fix(ui): client side doc data not updating after save (#9340)
### What? When a document is saved the data from useDocumentInfo was stale. ### Why? Previously we would refresh the entire document by calling the form-state endpoint, we no longer do that. ### How? Adds a new variable accessible from useDocumentInfo, `savedDocumentData`, that is updated when the document is successfully saved and defaults to initialData.
1 parent 69b7a11 commit 661f450

File tree

4 files changed

+59
-33
lines changed

4 files changed

+59
-33
lines changed

packages/ui/src/elements/Upload/index.tsx

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
'use client'
22
import type { FormState, SanitizedCollectionConfig, UploadEdits } from 'payload'
33

4-
import { isImage, reduceFieldsToValues } from 'payload/shared'
4+
import { isImage } from 'payload/shared'
55
import React, { useCallback, useEffect, useRef, useState } from 'react'
66
import { toast } from 'sonner'
77

88
import { FieldError } from '../../fields/FieldError/index.js'
99
import { fieldBaseClass } from '../../fields/shared/index.js'
10-
import { useForm } from '../../forms/Form/index.js'
10+
import { useForm, useFormProcessing } from '../../forms/Form/index.js'
1111
import { useField } from '../../forms/useField/index.js'
1212
import { useDocumentInfo } from '../../providers/DocumentInfo/index.js'
1313
import { EditDepthProvider } from '../../providers/EditDepth/index.js'
@@ -94,15 +94,15 @@ export const Upload: React.FC<UploadProps> = (props) => {
9494
const { t } = useTranslation()
9595
const { setModified } = useForm()
9696
const { resetUploadEdits, updateUploadEdits, uploadEdits } = useUploadEdits()
97-
const { docPermissions } = useDocumentInfo()
97+
const { docPermissions, savedDocumentData } = useDocumentInfo()
98+
const isFormSubmitting = useFormProcessing()
9899
const { errorMessage, setValue, showError, value } = useField<File>({
99100
path: 'file',
100101
validate,
101102
})
102103

103-
const [doc, setDoc] = useState(reduceFieldsToValues(initialState || {}, true))
104104
const [fileSrc, setFileSrc] = useState<null | string>(null)
105-
const [replacingFile, setReplacingFile] = useState(false)
105+
const [removedFile, setRemovedFile] = useState(false)
106106
const [filename, setFilename] = useState<string>(value?.name || '')
107107
const [showUrlInput, setShowUrlInput] = useState(false)
108108
const [fileUrl, setFileUrl] = useState<string>('')
@@ -156,11 +156,10 @@ export const Upload: React.FC<UploadProps> = (props) => {
156156
)
157157

158158
const handleFileRemoval = useCallback(() => {
159-
setReplacingFile(true)
159+
setRemovedFile(true)
160160
handleFileChange(null)
161161
setFileSrc('')
162162
setFileUrl('')
163-
setDoc({})
164163
resetUploadEdits()
165164
setShowUrlInput(false)
166165
}, [handleFileChange, resetUploadEdits])
@@ -192,11 +191,10 @@ export const Upload: React.FC<UploadProps> = (props) => {
192191
}
193192

194193
useEffect(() => {
195-
setDoc(reduceFieldsToValues(initialState || {}, true))
196194
if (initialState?.file?.value instanceof File) {
197195
setFileSrc(URL.createObjectURL(initialState.file.value))
196+
setRemovedFile(false)
198197
}
199-
setReplacingFile(false)
200198
}, [initialState])
201199

202200
useEffect(() => {
@@ -205,6 +203,12 @@ export const Upload: React.FC<UploadProps> = (props) => {
205203
}
206204
}, [showUrlInput])
207205

206+
useEffect(() => {
207+
if (isFormSubmitting) {
208+
setRemovedFile(false)
209+
}
210+
}, [isFormSubmitting])
211+
208212
const canRemoveUpload =
209213
docPermissions?.update && 'delete' in docPermissions && docPermissions?.delete
210214

@@ -222,19 +226,19 @@ export const Upload: React.FC<UploadProps> = (props) => {
222226
return (
223227
<div className={[fieldBaseClass, baseClass].filter(Boolean).join(' ')}>
224228
<FieldError message={errorMessage} showError={showError} />
225-
{doc.filename && !replacingFile && (
229+
{savedDocumentData && savedDocumentData.filename && !removedFile && (
226230
<FileDetails
227231
collectionSlug={collectionSlug}
228232
customUploadActions={customActions}
229-
doc={doc}
233+
doc={savedDocumentData}
230234
enableAdjustments={showCrop || showFocalPoint}
231235
handleRemove={canRemoveUpload ? handleFileRemoval : undefined}
232236
hasImageSizes={hasImageSizes}
233-
imageCacheTag={doc.updatedAt}
237+
imageCacheTag={savedDocumentData.updatedAt}
234238
uploadConfig={uploadConfig}
235239
/>
236240
)}
237-
{(!doc.filename || replacingFile) && (
241+
{(!savedDocumentData?.filename || removedFile) && (
238242
<div className={`${baseClass}__upload`}>
239243
{!value && !showUrlInput && (
240244
<Dropzone onChange={handleFileSelection}>
@@ -339,7 +343,7 @@ export const Upload: React.FC<UploadProps> = (props) => {
339343
<UploadActions
340344
customActions={customActions}
341345
enableAdjustments={showCrop || showFocalPoint}
342-
enablePreviewSizes={hasImageSizes && doc.filename && !replacingFile}
346+
enablePreviewSizes={hasImageSizes && savedDocumentData?.filename && !removedFile}
343347
mimeType={value.type}
344348
/>
345349
</div>
@@ -356,17 +360,17 @@ export const Upload: React.FC<UploadProps> = (props) => {
356360
)}
357361
</div>
358362
)}
359-
{(value || doc.filename) && (
363+
{(value || savedDocumentData?.filename) && (
360364
<EditDepthProvider>
361365
<Drawer Header={null} slug={editDrawerSlug}>
362366
<EditUpload
363-
fileName={value?.name || doc?.filename}
364-
fileSrc={doc?.url || fileSrc}
365-
imageCacheTag={doc.updatedAt}
367+
fileName={value?.name || savedDocumentData?.filename}
368+
fileSrc={savedDocumentData?.url || fileSrc}
369+
imageCacheTag={savedDocumentData?.updatedAt}
366370
initialCrop={uploadEdits?.crop ?? undefined}
367371
initialFocalPoint={{
368-
x: uploadEdits?.focalPoint?.x || doc.focalX || 50,
369-
y: uploadEdits?.focalPoint?.y || doc.focalY || 50,
372+
x: uploadEdits?.focalPoint?.x || savedDocumentData?.focalX || 50,
373+
y: uploadEdits?.focalPoint?.y || savedDocumentData?.focalY || 50,
370374
}}
371375
onSave={onEditsSave}
372376
showCrop={showCrop}
@@ -375,14 +379,18 @@ export const Upload: React.FC<UploadProps> = (props) => {
375379
</Drawer>
376380
</EditDepthProvider>
377381
)}
378-
{doc && hasImageSizes && (
382+
{savedDocumentData && hasImageSizes && (
379383
<Drawer
380384
className={`${baseClass}__previewDrawer`}
381385
hoverTitle
382386
slug={sizePreviewSlug}
383-
title={t('upload:sizesFor', { label: doc?.filename })}
387+
title={t('upload:sizesFor', { label: savedDocumentData.filename })}
384388
>
385-
<PreviewSizes doc={doc} imageCacheTag={doc.updatedAt} uploadConfig={uploadConfig} />
389+
<PreviewSizes
390+
doc={savedDocumentData}
391+
imageCacheTag={savedDocumentData.updatedAt}
392+
uploadConfig={uploadConfig}
393+
/>
386394
</Drawer>
387395
)}
388396
</div>

packages/ui/src/providers/DocumentInfo/index.tsx

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const DocumentInfo: React.FC<
4242
hasPublishedDoc: hasPublishedDocFromProps,
4343
hasPublishPermission: hasPublishPermissionFromProps,
4444
hasSavePermission: hasSavePermissionFromProps,
45-
initialData: data,
45+
initialData,
4646
initialState,
4747
isLocked: isLockedFromProps,
4848
lastUpdateTime: lastUpdateTimeFromProps,
@@ -84,7 +84,7 @@ const DocumentInfo: React.FC<
8484
const [documentTitle, setDocumentTitle] = useState(() =>
8585
formatDocTitle({
8686
collectionConfig,
87-
data: { ...data, id },
87+
data: { ...(initialData || {}), id },
8888
dateFormat,
8989
fallback: id?.toString(),
9090
globalConfig,
@@ -105,8 +105,9 @@ const DocumentInfo: React.FC<
105105
const [documentIsLocked, setDocumentIsLocked] = useState<boolean | undefined>(isLockedFromProps)
106106
const [currentEditor, setCurrentEditor] = useState<ClientUser | null>(currentEditorFromProps)
107107
const [lastUpdateTime, setLastUpdateTime] = useState<number>(lastUpdateTimeFromProps)
108+
const [savedDocumentData, setSavedDocumentData] = useState(initialData)
108109

109-
const isInitializing = initialState === undefined || data === undefined
110+
const isInitializing = initialState === undefined || initialData === undefined
110111

111112
const { getPreference, setPreference } = usePreferences()
112113
const { code: locale } = useLocale()
@@ -251,18 +252,25 @@ const DocumentInfo: React.FC<
251252
}
252253
}, [collectionConfig, globalConfig, versionCount])
253254

255+
const updateSavedDocumentData = React.useCallback<DocumentInfoContext['updateSavedDocumentData']>(
256+
(json) => {
257+
setSavedDocumentData(json)
258+
},
259+
[],
260+
)
261+
254262
useEffect(() => {
255263
setDocumentTitle(
256264
formatDocTitle({
257265
collectionConfig,
258-
data: { ...data, id },
266+
data: { ...savedDocumentData, id },
259267
dateFormat,
260268
fallback: id?.toString(),
261269
globalConfig,
262270
i18n,
263271
}),
264272
)
265-
}, [collectionConfig, globalConfig, data, dateFormat, i18n, id])
273+
}, [collectionConfig, globalConfig, savedDocumentData, dateFormat, i18n, id])
266274

267275
// clean on unmount
268276
useEffect(() => {
@@ -306,12 +314,13 @@ const DocumentInfo: React.FC<
306314
hasPublishPermission,
307315
hasSavePermission,
308316
incrementVersionCount,
309-
initialData: data,
317+
initialData,
310318
initialState,
311319
isInitializing,
312320
lastUpdateTime,
313321
mostRecentVersionIsAutosaved,
314322
preferencesKey,
323+
savedDocumentData,
315324
setCurrentEditor,
316325
setDocFieldPreferences,
317326
setDocumentIsLocked,
@@ -324,6 +333,7 @@ const DocumentInfo: React.FC<
324333
unlockDocument,
325334
unpublishedVersionCount,
326335
updateDocumentEditor,
336+
updateSavedDocumentData,
327337
versionCount,
328338
}
329339

packages/ui/src/providers/DocumentInfo/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export type DocumentInfoContext = {
5757
lastUpdateTime?: number
5858
mostRecentVersionIsAutosaved: boolean
5959
preferencesKey?: string
60+
savedDocumentData?: Data
6061
setCurrentEditor?: React.Dispatch<React.SetStateAction<ClientUser>>
6162
setDocFieldPreferences: (
6263
field: string,
@@ -72,5 +73,6 @@ export type DocumentInfoContext = {
7273
unlockDocument: (docId: number | string, slug: string) => Promise<void>
7374
unpublishedVersionCount: number
7475
updateDocumentEditor: (docId: number | string, slug: string, user: ClientUser) => Promise<void>
76+
updateSavedDocumentData: (data: Data) => void
7577
versionCount: number
7678
} & DocumentInfoProps

packages/ui/src/views/Edit/index.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,18 @@ export const DefaultEditView: React.FC<ClientSideEditViewProps> = ({
7171
hasPublishPermission,
7272
hasSavePermission,
7373
incrementVersionCount,
74-
initialData: data,
7574
initialState,
7675
isEditing,
7776
isInitializing,
7877
lastUpdateTime,
7978
redirectAfterDelete,
8079
redirectAfterDuplicate,
80+
savedDocumentData,
8181
setCurrentEditor,
8282
setDocumentIsLocked,
8383
unlockDocument,
8484
updateDocumentEditor,
85+
updateSavedDocumentData,
8586
} = useDocumentInfo()
8687

8788
const {
@@ -212,6 +213,10 @@ export const DefaultEditView: React.FC<ClientSideEditViewProps> = ({
212213

213214
incrementVersionCount()
214215

216+
if (typeof updateSavedDocumentData === 'function') {
217+
void updateSavedDocumentData(json?.doc || {})
218+
}
219+
215220
if (typeof onSaveFromContext === 'function') {
216221
void onSaveFromContext({
217222
...json,
@@ -238,6 +243,7 @@ export const DefaultEditView: React.FC<ClientSideEditViewProps> = ({
238243
await getDocPermissions(json)
239244
},
240245
[
246+
updateSavedDocumentData,
241247
reportUpdate,
242248
id,
243249
entitySlug,
@@ -479,7 +485,7 @@ export const DefaultEditView: React.FC<ClientSideEditViewProps> = ({
479485
SaveButton,
480486
SaveDraftButton,
481487
}}
482-
data={data}
488+
data={savedDocumentData}
483489
disableActions={disableActions}
484490
disableCreate={disableCreate}
485491
hasPublishPermission={hasPublishPermission}
@@ -521,15 +527,15 @@ export const DefaultEditView: React.FC<ClientSideEditViewProps> = ({
521527
className={`${baseClass}__auth`}
522528
collectionSlug={collectionConfig.slug}
523529
disableLocalStrategy={collectionConfig.auth?.disableLocalStrategy}
524-
email={data?.email}
530+
email={savedDocumentData?.email}
525531
loginWithUsername={auth?.loginWithUsername}
526532
operation={operation}
527533
readOnly={!hasSavePermission}
528534
requirePassword={!id}
529535
setSchemaPathSegments={setSchemaPathSegments}
530536
setValidateBeforeSubmit={setValidateBeforeSubmit}
531537
useAPIKey={auth.useAPIKey}
532-
username={data?.username}
538+
username={savedDocumentData?.username}
533539
verify={auth.verify}
534540
/>
535541
)}

0 commit comments

Comments
 (0)