@@ -7,6 +7,7 @@ import type {
7
7
ClientGlobalConfig ,
8
8
ClientUser ,
9
9
Data ,
10
+ FormState ,
10
11
LivePreviewConfig ,
11
12
} from 'payload'
12
13
@@ -25,21 +26,25 @@ import {
25
26
useDocumentDrawerContext ,
26
27
useDocumentEvents ,
27
28
useDocumentInfo ,
29
+ useEditDepth ,
28
30
useServerFunctions ,
29
31
useTranslation ,
32
+ useUploadEdits ,
30
33
} from '@payloadcms/ui'
31
34
import {
32
35
abortAndIgnore ,
36
+ formatAdminURL ,
37
+ handleAbortRef ,
33
38
handleBackToDashboard ,
34
39
handleGoBack ,
35
40
handleTakeOver ,
36
41
} from '@payloadcms/ui/shared'
37
- import { useRouter } from 'next/navigation.js'
42
+ import { useRouter , useSearchParams } from 'next/navigation.js'
38
43
import React , { Fragment , useCallback , useEffect , useRef , useState } from 'react'
39
44
40
45
import { useLivePreviewContext } from './Context/context.js'
41
- import { LivePreviewProvider } from './Context/index.js'
42
46
import './index.scss'
47
+ import { LivePreviewProvider } from './Context/index.js'
43
48
import { LivePreview } from './Preview/index.js'
44
49
import { usePopupWindow } from './usePopupWindow.js'
45
50
@@ -75,10 +80,12 @@ const PreviewView: React.FC<Props> = ({
75
80
disableLeaveWithoutSaving,
76
81
docPermissions,
77
82
documentIsLocked,
83
+ getDocPermissions,
78
84
getDocPreferences,
79
85
globalSlug,
80
86
hasPublishPermission,
81
87
hasSavePermission,
88
+ incrementVersionCount,
82
89
initialData,
83
90
initialState,
84
91
isEditing,
@@ -88,11 +95,10 @@ const PreviewView: React.FC<Props> = ({
88
95
setDocumentIsLocked,
89
96
unlockDocument,
90
97
updateDocumentEditor,
98
+ updateSavedDocumentData,
91
99
} = useDocumentInfo ( )
92
100
93
- const { getFormState } = useServerFunctions ( )
94
-
95
- const { onSave : onSaveFromProps } = useDocumentDrawerContext ( )
101
+ const { onSave : onSaveFromContext } = useDocumentDrawerContext ( )
96
102
97
103
const operation = id ? 'update' : 'create'
98
104
@@ -103,13 +109,21 @@ const PreviewView: React.FC<Props> = ({
103
109
} ,
104
110
} = useConfig ( )
105
111
const router = useRouter ( )
112
+ const params = useSearchParams ( )
113
+ const locale = params . get ( 'locale' )
106
114
const { t } = useTranslation ( )
107
115
const { previewWindowType } = useLivePreviewContext ( )
108
116
const { refreshCookieAsync, user } = useAuth ( )
109
117
const { reportUpdate } = useDocumentEvents ( )
118
+ const { resetUploadEdits } = useUploadEdits ( )
119
+ const { getFormState } = useServerFunctions ( )
110
120
111
121
const docConfig = collectionConfig || globalConfig
112
122
123
+ const entitySlug = collectionConfig ?. slug || globalConfig ?. slug
124
+
125
+ const depth = useEditDepth ( )
126
+
113
127
const lockDocumentsProp = docConfig ?. lockDocuments !== undefined ? docConfig ?. lockDocuments : true
114
128
const isLockingEnabled = lockDocumentsProp !== false
115
129
@@ -118,10 +132,19 @@ const PreviewView: React.FC<Props> = ({
118
132
typeof lockDocumentsProp === 'object' ? lockDocumentsProp . duration : lockDurationDefault
119
133
const lockDurationInMilliseconds = lockDuration * 1000
120
134
135
+ const autosaveEnabled = Boolean (
136
+ ( collectionConfig ?. versions ?. drafts && collectionConfig ?. versions ?. drafts ?. autosave ) ||
137
+ ( globalConfig ?. versions ?. drafts && globalConfig ?. versions ?. drafts ?. autosave ) ,
138
+ )
139
+
140
+ const preventLeaveWithoutSaving =
141
+ typeof disableLeaveWithoutSaving !== 'undefined' ? ! disableLeaveWithoutSaving : ! autosaveEnabled
142
+
121
143
const [ isReadOnlyForIncomingUser , setIsReadOnlyForIncomingUser ] = useState ( false )
122
144
const [ showTakeOverModal , setShowTakeOverModal ] = useState ( false )
123
145
124
- const formStateAbortControllerRef = useRef ( new AbortController ( ) )
146
+ const abortOnChangeRef = useRef < AbortController > ( null )
147
+ const abortOnSaveRef = useRef < AbortController > ( null )
125
148
126
149
const [ editSessionStartTime , setEditSessionStartTime ] = useState ( Date . now ( ) )
127
150
@@ -140,10 +163,12 @@ const PreviewView: React.FC<Props> = ({
140
163
} )
141
164
142
165
const onSave = useCallback (
143
- ( json ) => {
166
+ async ( json ) : Promise < FormState > => {
167
+ const controller = handleAbortRef ( abortOnSaveRef )
168
+
144
169
reportUpdate ( {
145
170
id,
146
- entitySlug : collectionSlug ,
171
+ entitySlug,
147
172
updatedAt : json ?. result ?. updatedAt || new Date ( ) . toISOString ( ) ,
148
173
} )
149
174
@@ -153,38 +178,91 @@ const PreviewView: React.FC<Props> = ({
153
178
void refreshCookieAsync ( )
154
179
}
155
180
156
- // Unlock the document after save
157
- if ( ( id || globalSlug ) && isLockingEnabled ) {
158
- setDocumentIsLocked ( false )
181
+ incrementVersionCount ( )
182
+
183
+ if ( typeof updateSavedDocumentData === 'function' ) {
184
+ void updateSavedDocumentData ( json ?. doc || { } )
159
185
}
160
186
161
- if ( typeof onSaveFromProps === 'function' ) {
162
- void onSaveFromProps ( {
187
+ if ( typeof onSaveFromContext === 'function' ) {
188
+ void onSaveFromContext ( {
163
189
...json ,
164
190
operation : id ? 'update' : 'create' ,
165
191
} )
166
192
}
193
+
194
+ if ( ! isEditing && depth < 2 ) {
195
+ // Redirect to the same locale if it's been set
196
+ const redirectRoute = formatAdminURL ( {
197
+ adminRoute,
198
+ path : `/collections/${ collectionSlug } /${ json ?. doc ?. id } ${ locale ? `?locale=${ locale } ` : '' } ` ,
199
+ } )
200
+ router . push ( redirectRoute )
201
+ } else {
202
+ resetUploadEdits ( )
203
+ }
204
+
205
+ await getDocPermissions ( json )
206
+
207
+ if ( ( id || globalSlug ) && ! autosaveEnabled ) {
208
+ const docPreferences = await getDocPreferences ( )
209
+
210
+ const { state } = await getFormState ( {
211
+ id,
212
+ collectionSlug,
213
+ data : json ?. doc || json ?. result ,
214
+ docPermissions,
215
+ docPreferences,
216
+ globalSlug,
217
+ operation,
218
+ renderAllFields : true ,
219
+ returnLockStatus : false ,
220
+ schemaPath : entitySlug ,
221
+ signal : controller . signal ,
222
+ } )
223
+
224
+ // Unlock the document after save
225
+ if ( isLockingEnabled ) {
226
+ setDocumentIsLocked ( false )
227
+ }
228
+
229
+ abortOnSaveRef . current = null
230
+
231
+ return state
232
+ }
167
233
} ,
168
234
[
235
+ adminRoute ,
169
236
collectionSlug ,
237
+ depth ,
238
+ docPermissions ,
239
+ entitySlug ,
240
+ getDocPermissions ,
241
+ getDocPreferences ,
242
+ getFormState ,
170
243
globalSlug ,
171
244
id ,
245
+ incrementVersionCount ,
246
+ isEditing ,
172
247
isLockingEnabled ,
173
- onSaveFromProps ,
248
+ locale ,
249
+ onSaveFromContext ,
250
+ operation ,
174
251
refreshCookieAsync ,
175
252
reportUpdate ,
253
+ resetUploadEdits ,
254
+ router ,
176
255
setDocumentIsLocked ,
256
+ updateSavedDocumentData ,
177
257
user ,
178
258
userSlug ,
259
+ autosaveEnabled ,
179
260
] ,
180
261
)
181
262
182
263
const onChange : FormProps [ 'onChange' ] [ 0 ] = useCallback (
183
264
async ( { formState : prevFormState } ) => {
184
- abortAndIgnore ( formStateAbortControllerRef . current )
185
-
186
- const controller = new AbortController ( )
187
- formStateAbortControllerRef . current = controller
265
+ const controller = handleAbortRef ( abortOnChangeRef )
188
266
189
267
const currentTime = Date . now ( )
190
268
const timeSinceLastUpdate = currentTime - editSessionStartTime
@@ -242,6 +320,8 @@ const PreviewView: React.FC<Props> = ({
242
320
}
243
321
}
244
322
323
+ abortOnChangeRef . current = null
324
+
245
325
return state
246
326
} ,
247
327
[
@@ -308,8 +388,12 @@ const PreviewView: React.FC<Props> = ({
308
388
] )
309
389
310
390
useEffect ( ( ) => {
391
+ const abortOnChange = abortOnChangeRef . current
392
+ const abortOnSave = abortOnSaveRef . current
393
+
311
394
return ( ) => {
312
- abortAndIgnore ( formStateAbortControllerRef . current )
395
+ abortAndIgnore ( abortOnChange )
396
+ abortAndIgnore ( abortOnSave )
313
397
}
314
398
} )
315
399
@@ -372,12 +456,7 @@ const PreviewView: React.FC<Props> = ({
372
456
} }
373
457
/>
374
458
) }
375
- { ( ( collectionConfig &&
376
- ! ( collectionConfig . versions ?. drafts && collectionConfig . versions ?. drafts ?. autosave ) ) ||
377
- ( globalConfig &&
378
- ! ( globalConfig . versions ?. drafts && globalConfig . versions ?. drafts ?. autosave ) ) ) &&
379
- ! disableLeaveWithoutSaving &&
380
- ! isReadOnlyForIncomingUser && < LeaveWithoutSaving /> }
459
+ { ! isReadOnlyForIncomingUser && preventLeaveWithoutSaving && < LeaveWithoutSaving /> }
381
460
< SetDocumentStepNav
382
461
collectionSlug = { collectionSlug }
383
462
globalLabel = { globalConfig ?. label }
0 commit comments