@payloadcms/ui 3.24.0-canary.a62d86f → 3.24.0-canary.d22403c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/elements/Autosave/index.d.ts.map +1 -1
- package/dist/elements/Autosave/index.js +108 -143
- package/dist/elements/Autosave/index.js.map +1 -1
- package/dist/elements/DeleteDocument/index.d.ts.map +1 -1
- package/dist/elements/DeleteDocument/index.js +80 -39
- package/dist/elements/DeleteDocument/index.js.map +1 -1
- package/dist/elements/DeleteDocument/index.scss +29 -0
- package/dist/elements/DeleteMany/index.d.ts.map +1 -1
- package/dist/elements/DeleteMany/index.js +44 -24
- package/dist/elements/DeleteMany/index.js.map +1 -1
- package/dist/elements/DeleteMany/index.scss +29 -0
- package/dist/elements/DuplicateDocument/index.d.ts +1 -0
- package/dist/elements/DuplicateDocument/index.d.ts.map +1 -1
- package/dist/elements/DuplicateDocument/index.js +54 -38
- package/dist/elements/DuplicateDocument/index.js.map +1 -1
- package/dist/elements/DuplicateDocument/index.scss +42 -0
- package/dist/elements/GenerateConfirmation/index.d.ts +2 -1
- package/dist/elements/GenerateConfirmation/index.d.ts.map +1 -1
- package/dist/elements/GenerateConfirmation/index.js +47 -28
- package/dist/elements/GenerateConfirmation/index.js.map +1 -1
- package/dist/elements/{ConfirmationModal → GenerateConfirmation}/index.scss +1 -1
- package/dist/elements/LeaveWithoutSaving/index.d.ts +1 -0
- package/dist/elements/LeaveWithoutSaving/index.d.ts.map +1 -1
- package/dist/elements/LeaveWithoutSaving/index.js +114 -63
- package/dist/elements/LeaveWithoutSaving/index.js.map +1 -1
- package/dist/elements/LeaveWithoutSaving/index.scss +39 -0
- package/dist/elements/ListControls/index.d.ts +0 -1
- package/dist/elements/ListControls/index.d.ts.map +1 -1
- package/dist/elements/ListControls/index.js +0 -14
- package/dist/elements/ListControls/index.js.map +1 -1
- package/dist/elements/ListControls/index.scss +0 -5
- package/dist/elements/PublishMany/index.d.ts +1 -0
- package/dist/elements/PublishMany/index.d.ts.map +1 -1
- package/dist/elements/PublishMany/index.js +46 -27
- package/dist/elements/PublishMany/index.js.map +1 -1
- package/dist/elements/PublishMany/index.scss +39 -0
- package/dist/elements/RelationshipTable/index.d.ts +2 -7
- package/dist/elements/RelationshipTable/index.d.ts.map +1 -1
- package/dist/elements/RelationshipTable/index.js +23 -69
- package/dist/elements/RelationshipTable/index.js.map +1 -1
- package/dist/elements/RelationshipTable/index.scss +0 -6
- package/dist/elements/Status/index.d.ts.map +1 -1
- package/dist/elements/Status/index.js +154 -179
- package/dist/elements/Status/index.js.map +1 -1
- package/dist/elements/Status/index.scss +41 -0
- package/dist/elements/StayLoggedIn/index.d.ts +1 -0
- package/dist/elements/StayLoggedIn/index.d.ts.map +1 -1
- package/dist/elements/StayLoggedIn/index.js +77 -53
- package/dist/elements/StayLoggedIn/index.js.map +1 -1
- package/dist/elements/StayLoggedIn/index.scss +40 -0
- package/dist/elements/TableColumns/index.d.ts +1 -1
- package/dist/elements/TableColumns/index.d.ts.map +1 -1
- package/dist/elements/TableColumns/index.js +3 -4
- package/dist/elements/TableColumns/index.js.map +1 -1
- package/dist/elements/UnpublishMany/index.d.ts +2 -1
- package/dist/elements/UnpublishMany/index.d.ts.map +1 -1
- package/dist/elements/UnpublishMany/index.js +43 -22
- package/dist/elements/UnpublishMany/index.js.map +1 -1
- package/dist/elements/UnpublishMany/index.scss +39 -0
- package/dist/exports/client/index.d.ts +0 -2
- package/dist/exports/client/index.d.ts.map +1 -1
- package/dist/exports/client/index.js +23 -23
- package/dist/exports/client/index.js.map +4 -4
- package/dist/fields/Join/index.d.ts.map +1 -1
- package/dist/fields/Join/index.js +3 -8
- package/dist/fields/Join/index.js.map +1 -1
- package/dist/fields/Select/Input.d.ts.map +1 -1
- package/dist/fields/Select/Input.js +0 -2
- package/dist/fields/Select/Input.js.map +1 -1
- package/dist/forms/Form/index.d.ts.map +1 -1
- package/dist/forms/Form/index.js +8 -19
- package/dist/forms/Form/index.js.map +1 -1
- package/dist/forms/Form/initContextState.d.ts.map +1 -1
- package/dist/forms/Form/initContextState.js +0 -2
- package/dist/forms/Form/initContextState.js.map +1 -1
- package/dist/forms/Form/types.d.ts +0 -6
- package/dist/forms/Form/types.d.ts.map +1 -1
- package/dist/forms/Form/types.js.map +1 -1
- package/dist/providers/Selection/index.d.ts.map +1 -1
- package/dist/providers/Selection/index.js +6 -5
- package/dist/providers/Selection/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/utilities/buildTableState.d.ts.map +1 -1
- package/dist/utilities/buildTableState.js +20 -72
- package/dist/utilities/buildTableState.js.map +1 -1
- package/dist/utilities/handleFormStateLocking.d.ts.map +1 -1
- package/dist/utilities/handleFormStateLocking.js +6 -3
- package/dist/utilities/handleFormStateLocking.js.map +1 -1
- package/dist/utilities/renderTable.d.ts +4 -6
- package/dist/utilities/renderTable.d.ts.map +1 -1
- package/dist/utilities/renderTable.js +17 -49
- package/dist/utilities/renderTable.js.map +1 -1
- package/dist/views/Edit/Auth/index.d.ts.map +1 -1
- package/dist/views/Edit/Auth/index.js +62 -61
- package/dist/views/Edit/Auth/index.js.map +1 -1
- package/dist/views/List/index.d.ts.map +1 -1
- package/dist/views/List/index.js +0 -2
- package/dist/views/List/index.js.map +1 -1
- package/package.json +4 -4
- package/dist/elements/ConfirmationModal/index.d.ts +0 -19
- package/dist/elements/ConfirmationModal/index.d.ts.map +0 -1
- package/dist/elements/ConfirmationModal/index.js +0 -143
- package/dist/elements/ConfirmationModal/index.js.map +0 -1
- package/dist/elements/TableColumns/buildPolymorphicColumnState.d.ts +0 -20
- package/dist/elements/TableColumns/buildPolymorphicColumnState.d.ts.map +0 -1
- package/dist/elements/TableColumns/buildPolymorphicColumnState.js +0 -200
- package/dist/elements/TableColumns/buildPolymorphicColumnState.js.map +0 -1
- package/dist/icons/Dots/index.d.ts +0 -7
- package/dist/icons/Dots/index.d.ts.map +0 -1
- package/dist/icons/Dots/index.js +0 -12
- package/dist/icons/Dots/index.js.map +0 -1
- package/dist/icons/Dots/index.scss +0 -27
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/Autosave/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/Autosave/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAGzE,OAAO,KAAsC,MAAM,OAAO,CAAA;AAgB1D,OAAO,cAAc,CAAA;AAQrB,MAAM,MAAM,KAAK,GAAG;IAClB,UAAU,CAAC,EAAE,sBAAsB,CAAA;IACnC,MAAM,CAAC,EAAE,kBAAkB,CAAA;IAC3B,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACpB,qBAAqB,EAAE,MAAM,CAAA;CAC9B,CAAA;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAkQpC,CAAA"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import React, { useDeferredValue, useEffect, useRef, useState } from 'react';
|
|
4
|
+
import { versionDefaults } from 'payload/shared';
|
|
5
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
7
6
|
import { toast } from 'sonner';
|
|
8
7
|
import { useAllFormFields, useForm, useFormModified, useFormSubmitted } from '../../forms/Form/context.js';
|
|
9
8
|
import { useDebounce } from '../../hooks/useDebounce.js';
|
|
@@ -12,11 +11,10 @@ import { useConfig } from '../../providers/Config/index.js';
|
|
|
12
11
|
import { useDocumentEvents } from '../../providers/DocumentEvents/index.js';
|
|
13
12
|
import { useDocumentInfo } from '../../providers/DocumentInfo/index.js';
|
|
14
13
|
import { useLocale } from '../../providers/Locale/index.js';
|
|
15
|
-
import './index.scss';
|
|
16
14
|
import { useTranslation } from '../../providers/Translation/index.js';
|
|
15
|
+
import './index.scss';
|
|
17
16
|
import { formatTimeToNow } from '../../utilities/formatDate.js';
|
|
18
17
|
import { reduceFieldsToValuesWithValidation } from '../../utilities/reduceFieldsToValuesWithValidation.js';
|
|
19
|
-
import { LeaveWithoutSaving } from '../LeaveWithoutSaving/index.js';
|
|
20
18
|
const baseClass = 'autosave';
|
|
21
19
|
// The minimum time the saving state should be shown
|
|
22
20
|
const minimumAnimationTime = 1000;
|
|
@@ -50,13 +48,12 @@ export const Autosave = ({
|
|
|
50
48
|
} = useDocumentEvents();
|
|
51
49
|
const {
|
|
52
50
|
dispatchFields,
|
|
53
|
-
isValid,
|
|
54
|
-
setIsValid,
|
|
55
51
|
setSubmitted
|
|
56
52
|
} = useForm();
|
|
53
|
+
const submitted = useFormSubmitted();
|
|
54
|
+
const versionsConfig = docConfig?.versions;
|
|
57
55
|
const [fields] = useAllFormFields();
|
|
58
56
|
const modified = useFormModified();
|
|
59
|
-
const submitted = useFormSubmitted();
|
|
60
57
|
const {
|
|
61
58
|
code: locale
|
|
62
59
|
} = useLocale();
|
|
@@ -64,23 +61,17 @@ export const Autosave = ({
|
|
|
64
61
|
i18n,
|
|
65
62
|
t
|
|
66
63
|
} = useTranslation();
|
|
67
|
-
const versionsConfig = docConfig?.versions;
|
|
68
64
|
let interval = versionDefaults.autosaveInterval;
|
|
69
65
|
if (versionsConfig.drafts && versionsConfig.drafts.autosave) {
|
|
70
66
|
interval = versionsConfig.drafts.autosave.interval;
|
|
71
67
|
}
|
|
72
|
-
const
|
|
73
|
-
const [_saving, setSaving] = useState(false);
|
|
74
|
-
const saving = useDeferredValue(_saving);
|
|
68
|
+
const [saving, setSaving] = useState(false);
|
|
75
69
|
const debouncedFields = useDebounce(fields, interval);
|
|
76
70
|
const fieldRef = useRef(fields);
|
|
77
71
|
const modifiedRef = useRef(modified);
|
|
78
72
|
const localeRef = useRef(locale);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
* Helps us prevent infinite loops when the queue is processing and the form is invalid
|
|
82
|
-
*/
|
|
83
|
-
const isValidRef = useRef(isValid);
|
|
73
|
+
const debouncedRef = useRef(debouncedFields);
|
|
74
|
+
debouncedRef.current = debouncedFields;
|
|
84
75
|
// Store fields in ref so the autosave func
|
|
85
76
|
// can always retrieve the most to date copies
|
|
86
77
|
// after the timeout has executed
|
|
@@ -96,13 +87,6 @@ export const Autosave = ({
|
|
|
96
87
|
if (isProcessingRef.current || queueRef.current.length === 0) {
|
|
97
88
|
return;
|
|
98
89
|
}
|
|
99
|
-
if (!isValidRef.current) {
|
|
100
|
-
// Clear queue so we don't end up in an infinite loop
|
|
101
|
-
queueRef.current = [];
|
|
102
|
-
// Reset internal validation state so queue processing can run again
|
|
103
|
-
isValidRef.current = true;
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
90
|
isProcessingRef.current = true;
|
|
107
91
|
const latestAction = queueRef.current[queueRef.current.length - 1];
|
|
108
92
|
queueRef.current = [];
|
|
@@ -115,22 +99,12 @@ export const Autosave = ({
|
|
|
115
99
|
}
|
|
116
100
|
}
|
|
117
101
|
}, []);
|
|
118
|
-
const autosaveTimeoutRef = useRef(null);
|
|
119
102
|
const handleAutosave = useEffectEvent(() => {
|
|
120
|
-
|
|
103
|
+
const abortController = new AbortController();
|
|
104
|
+
let autosaveTimeout = undefined;
|
|
121
105
|
// We need to log the time in order to figure out if we need to trigger the state off later
|
|
122
106
|
let startTimestamp = undefined;
|
|
123
107
|
let endTimestamp = undefined;
|
|
124
|
-
const hideIndicator = () => {
|
|
125
|
-
// If request was faster than minimum animation time, animate the difference
|
|
126
|
-
if (endTimestamp - startTimestamp < minimumAnimationTime) {
|
|
127
|
-
autosaveTimeoutRef.current = setTimeout(() => {
|
|
128
|
-
setSaving(false);
|
|
129
|
-
}, minimumAnimationTime - (endTimestamp - startTimestamp));
|
|
130
|
-
} else {
|
|
131
|
-
stopAutoSaveIndicator();
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
108
|
const autosave = async () => {
|
|
135
109
|
if (modified) {
|
|
136
110
|
startTimestamp = new Date().getTime();
|
|
@@ -153,86 +127,88 @@ export const Autosave = ({
|
|
|
153
127
|
const {
|
|
154
128
|
data,
|
|
155
129
|
valid
|
|
156
|
-
} =
|
|
130
|
+
} = {
|
|
131
|
+
...reduceFieldsToValuesWithValidation(fieldRef.current, true)
|
|
132
|
+
};
|
|
157
133
|
data._status = 'draft';
|
|
158
134
|
const skipSubmission = submitted && !valid && versionsConfig?.drafts && versionsConfig?.drafts?.validate;
|
|
159
|
-
if (!skipSubmission
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
reportUpdate({
|
|
180
|
-
id,
|
|
181
|
-
entitySlug,
|
|
182
|
-
updatedAt: newDate.toISOString()
|
|
183
|
-
});
|
|
184
|
-
if (!mostRecentVersionIsAutosaved) {
|
|
185
|
-
incrementVersionCount();
|
|
186
|
-
setMostRecentVersionIsAutosaved(true);
|
|
187
|
-
setUnpublishedVersionCount(prev => prev + 1);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
const json = await res.json();
|
|
191
|
-
if (versionsConfig?.drafts && versionsConfig?.drafts?.validate && json?.errors) {
|
|
192
|
-
if (Array.isArray(json.errors)) {
|
|
193
|
-
const [fieldErrors, nonFieldErrors] = json.errors.reduce(([fieldErrs, nonFieldErrs], err) => {
|
|
194
|
-
const newFieldErrs = [];
|
|
195
|
-
const newNonFieldErrs = [];
|
|
196
|
-
if (err?.message) {
|
|
197
|
-
newNonFieldErrs.push(err);
|
|
198
|
-
}
|
|
199
|
-
if (Array.isArray(err?.data)) {
|
|
200
|
-
err.data.forEach(dataError => {
|
|
201
|
-
if (dataError?.field) {
|
|
202
|
-
newFieldErrs.push(dataError);
|
|
203
|
-
} else {
|
|
204
|
-
newNonFieldErrs.push(dataError);
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
return [[...fieldErrs, ...newFieldErrs], [...nonFieldErrs, ...newNonFieldErrs]];
|
|
209
|
-
}, [[], []]);
|
|
210
|
-
dispatchFields({
|
|
211
|
-
type: 'ADD_SERVER_ERRORS',
|
|
212
|
-
errors: fieldErrors
|
|
135
|
+
if (!skipSubmission) {
|
|
136
|
+
await fetch(url, {
|
|
137
|
+
body: JSON.stringify(data),
|
|
138
|
+
credentials: 'include',
|
|
139
|
+
headers: {
|
|
140
|
+
'Accept-Language': i18n.language,
|
|
141
|
+
'Content-Type': 'application/json'
|
|
142
|
+
},
|
|
143
|
+
method,
|
|
144
|
+
signal: abortController.signal
|
|
145
|
+
}).then(res => {
|
|
146
|
+
const newDate = new Date();
|
|
147
|
+
// We need to log the time in order to figure out if we need to trigger the state off later
|
|
148
|
+
endTimestamp = newDate.getTime();
|
|
149
|
+
if (res.status === 200) {
|
|
150
|
+
setLastUpdateTime(newDate.getTime());
|
|
151
|
+
reportUpdate({
|
|
152
|
+
id,
|
|
153
|
+
entitySlug,
|
|
154
|
+
updatedAt: newDate.toISOString()
|
|
213
155
|
});
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
156
|
+
if (!mostRecentVersionIsAutosaved) {
|
|
157
|
+
incrementVersionCount();
|
|
158
|
+
setMostRecentVersionIsAutosaved(true);
|
|
159
|
+
setUnpublishedVersionCount(prev => prev + 1);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return res.json();
|
|
163
|
+
}).then(json => {
|
|
164
|
+
if (versionsConfig?.drafts && versionsConfig?.drafts?.validate && json?.errors) {
|
|
165
|
+
if (Array.isArray(json.errors)) {
|
|
166
|
+
const [fieldErrors, nonFieldErrors] = json.errors.reduce(([fieldErrs, nonFieldErrs], err) => {
|
|
167
|
+
const newFieldErrs = [];
|
|
168
|
+
const newNonFieldErrs = [];
|
|
169
|
+
if (err?.message) {
|
|
170
|
+
newNonFieldErrs.push(err);
|
|
171
|
+
}
|
|
172
|
+
if (Array.isArray(err?.data)) {
|
|
173
|
+
err.data.forEach(dataError => {
|
|
174
|
+
if (dataError?.field) {
|
|
175
|
+
newFieldErrs.push(dataError);
|
|
176
|
+
} else {
|
|
177
|
+
newNonFieldErrs.push(dataError);
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return [[...fieldErrs, ...newFieldErrs], [...nonFieldErrs, ...newNonFieldErrs]];
|
|
182
|
+
}, [[], []]);
|
|
183
|
+
dispatchFields({
|
|
184
|
+
type: 'ADD_SERVER_ERRORS',
|
|
185
|
+
errors: fieldErrors
|
|
186
|
+
});
|
|
187
|
+
nonFieldErrors.forEach(err_0 => {
|
|
188
|
+
toast.error(err_0.message || i18n.t('error:unknown'));
|
|
189
|
+
});
|
|
190
|
+
setSubmitted(true);
|
|
191
|
+
setSaving(false);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
} else {
|
|
195
|
+
// If it's not an error then we can update the document data inside the context
|
|
196
|
+
const document = json?.doc || json?.result;
|
|
197
|
+
// Manually update the data since this function doesn't fire the `submit` function from useForm
|
|
198
|
+
if (document) {
|
|
199
|
+
updateSavedDocumentData(document);
|
|
200
|
+
}
|
|
223
201
|
}
|
|
224
|
-
}
|
|
225
|
-
// If
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
updateSavedDocumentData(document);
|
|
202
|
+
}).then(() => {
|
|
203
|
+
// If request was faster than minimum animation time, animate the difference
|
|
204
|
+
if (endTimestamp - startTimestamp < minimumAnimationTime) {
|
|
205
|
+
autosaveTimeout = setTimeout(() => {
|
|
206
|
+
setSaving(false);
|
|
207
|
+
}, minimumAnimationTime - (endTimestamp - startTimestamp));
|
|
208
|
+
} else {
|
|
209
|
+
setSaving(false);
|
|
233
210
|
}
|
|
234
|
-
}
|
|
235
|
-
hideIndicator();
|
|
211
|
+
});
|
|
236
212
|
}
|
|
237
213
|
}
|
|
238
214
|
}
|
|
@@ -240,45 +216,34 @@ export const Autosave = ({
|
|
|
240
216
|
};
|
|
241
217
|
queueRef.current.push(autosave);
|
|
242
218
|
void processQueue();
|
|
219
|
+
return {
|
|
220
|
+
abortController,
|
|
221
|
+
autosaveTimeout
|
|
222
|
+
};
|
|
243
223
|
});
|
|
244
|
-
const didMount = useRef(false);
|
|
245
|
-
const previousDebouncedFieldValues = useRef(reduceFieldsToValues(debouncedFields));
|
|
246
224
|
// When debounced fields change, autosave
|
|
247
225
|
useEffect(() => {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
didMount.current = true;
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* Ensure autosave only runs if the form data changes, not every time the entire form state changes
|
|
257
|
-
*/
|
|
258
|
-
const debouncedFieldValues = reduceFieldsToValues(debouncedFields);
|
|
259
|
-
if (dequal(debouncedFieldValues, previousDebouncedFieldValues)) {
|
|
260
|
-
return;
|
|
261
|
-
}
|
|
262
|
-
previousDebouncedFieldValues.current = debouncedFieldValues;
|
|
263
|
-
handleAutosave();
|
|
264
|
-
}, [debouncedFields]);
|
|
265
|
-
/**
|
|
266
|
-
* If component unmounts, clear the autosave timeout
|
|
267
|
-
*/
|
|
268
|
-
useEffect(() => {
|
|
226
|
+
const {
|
|
227
|
+
abortController: abortController_0,
|
|
228
|
+
autosaveTimeout: autosaveTimeout_0
|
|
229
|
+
} = handleAutosave();
|
|
269
230
|
return () => {
|
|
270
|
-
|
|
231
|
+
if (autosaveTimeout_0) {
|
|
232
|
+
clearTimeout(autosaveTimeout_0);
|
|
233
|
+
}
|
|
234
|
+
if (abortController_0.signal) {
|
|
235
|
+
try {
|
|
236
|
+
abortController_0.abort('Autosave closed early.');
|
|
237
|
+
} catch (error) {
|
|
238
|
+
// swallow error
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
setSaving(false);
|
|
271
242
|
};
|
|
272
|
-
}, []);
|
|
273
|
-
const stopAutoSaveIndicator = useEffectEvent(() => {
|
|
274
|
-
if (autosaveTimeoutRef.current) {
|
|
275
|
-
clearTimeout(autosaveTimeoutRef.current);
|
|
276
|
-
}
|
|
277
|
-
setSaving(false);
|
|
278
|
-
});
|
|
243
|
+
}, [debouncedFields]);
|
|
279
244
|
return /*#__PURE__*/_jsxs("div", {
|
|
280
245
|
className: baseClass,
|
|
281
|
-
children: [
|
|
246
|
+
children: [saving && t('general:saving'), !saving && Boolean(lastUpdateTime) && /*#__PURE__*/_jsx(React.Fragment, {
|
|
282
247
|
children: t('version:lastSavedAgo', {
|
|
283
248
|
distance: formatTimeToNow({
|
|
284
249
|
date: lastUpdateTime,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["dequal","reduceFieldsToValues","versionDefaults","React","useDeferredValue","useEffect","useRef","useState","toast","useAllFormFields","useForm","useFormModified","useFormSubmitted","useDebounce","useEffectEvent","useConfig","useDocumentEvents","useDocumentInfo","useLocale","useTranslation","formatTimeToNow","reduceFieldsToValuesWithValidation","LeaveWithoutSaving","baseClass","minimumAnimationTime","Autosave","id","collection","global","globalDoc","config","routes","api","serverURL","docConfig","incrementVersionCount","lastUpdateTime","mostRecentVersionIsAutosaved","setLastUpdateTime","setMostRecentVersionIsAutosaved","setUnpublishedVersionCount","updateSavedDocumentData","queueRef","isProcessingRef","reportUpdate","dispatchFields","isValid","setIsValid","setSubmitted","fields","modified","submitted","code","locale","i18n","t","versionsConfig","versions","interval","autosaveInterval","drafts","autosave","validateOnDraft","Boolean","validate","_saving","setSaving","saving","debouncedFields","fieldRef","modifiedRef","localeRef","isValidRef","current","processQueue","useCallback","length","latestAction","autosaveTimeoutRef","handleAutosave","undefined","startTimestamp","endTimestamp","hideIndicator","setTimeout","stopAutoSaveIndicator","Date","getTime","url","method","entitySlug","slug","data","valid","_status","skipSubmission","res","fetch","body","JSON","stringify","credentials","headers","language","error","newDate","status","updatedAt","toISOString","prev","json","errors","Array","isArray","fieldErrors","nonFieldErrors","reduce","fieldErrs","nonFieldErrs","err","newFieldErrs","newNonFieldErrs","message","push","forEach","dataError","field","type","document","doc","result","didMount","previousDebouncedFieldValues","debouncedFieldValues","clearTimeout","_jsxs","className","_jsx","Fragment","distance","date"],"sources":["../../../src/elements/Autosave/index.tsx"],"sourcesContent":["'use client'\n// TODO: abstract the `next/navigation` dependency out from this component\nimport type { ClientCollectionConfig, ClientGlobalConfig } from 'payload'\n\nimport { dequal } from 'dequal/lite'\nimport { reduceFieldsToValues, versionDefaults } from 'payload/shared'\nimport React, { useDeferredValue, useEffect, useRef, useState } from 'react'\nimport { toast } from 'sonner'\n\nimport {\n useAllFormFields,\n useForm,\n useFormModified,\n useFormSubmitted,\n} from '../../forms/Form/context.js'\nimport { useDebounce } from '../../hooks/useDebounce.js'\nimport { useEffectEvent } from '../../hooks/useEffectEvent.js'\nimport { useConfig } from '../../providers/Config/index.js'\nimport { useDocumentEvents } from '../../providers/DocumentEvents/index.js'\nimport { useDocumentInfo } from '../../providers/DocumentInfo/index.js'\nimport { useLocale } from '../../providers/Locale/index.js'\nimport './index.scss'\nimport { useTranslation } from '../../providers/Translation/index.js'\nimport { formatTimeToNow } from '../../utilities/formatDate.js'\nimport { reduceFieldsToValuesWithValidation } from '../../utilities/reduceFieldsToValuesWithValidation.js'\nimport { LeaveWithoutSaving } from '../LeaveWithoutSaving/index.js'\n\nconst baseClass = 'autosave'\n// The minimum time the saving state should be shown\nconst minimumAnimationTime = 1000\n\nexport type Props = {\n collection?: ClientCollectionConfig\n global?: ClientGlobalConfig\n id?: number | string\n publishedDocUpdatedAt: string\n}\n\nexport const Autosave: React.FC<Props> = ({ id, collection, global: globalDoc }) => {\n const {\n config: {\n routes: { api },\n serverURL,\n },\n } = useConfig()\n const {\n docConfig,\n incrementVersionCount,\n lastUpdateTime,\n mostRecentVersionIsAutosaved,\n setLastUpdateTime,\n setMostRecentVersionIsAutosaved,\n setUnpublishedVersionCount,\n updateSavedDocumentData,\n } = useDocumentInfo()\n const queueRef = useRef([])\n const isProcessingRef = useRef(false)\n\n const { reportUpdate } = useDocumentEvents()\n const { dispatchFields, isValid, setIsValid, setSubmitted } = useForm()\n\n const [fields] = useAllFormFields()\n const modified = useFormModified()\n const submitted = useFormSubmitted()\n\n const { code: locale } = useLocale()\n const { i18n, t } = useTranslation()\n\n const versionsConfig = docConfig?.versions\n let interval = versionDefaults.autosaveInterval\n\n if (versionsConfig.drafts && versionsConfig.drafts.autosave) {\n interval = versionsConfig.drafts.autosave.interval\n }\n\n const validateOnDraft = Boolean(\n docConfig?.versions?.drafts && docConfig?.versions?.drafts.validate,\n )\n\n const [_saving, setSaving] = useState(false)\n const saving = useDeferredValue(_saving)\n const debouncedFields = useDebounce(fields, interval)\n const fieldRef = useRef(fields)\n const modifiedRef = useRef(modified)\n const localeRef = useRef(locale)\n /**\n * Track the validation internally so Autosave can determine when to run queue processing again\n * Helps us prevent infinite loops when the queue is processing and the form is invalid\n */\n const isValidRef = useRef(isValid)\n\n // Store fields in ref so the autosave func\n // can always retrieve the most to date copies\n // after the timeout has executed\n fieldRef.current = fields\n\n // Store modified in ref so the autosave func\n // can bail out if modified becomes false while\n // timing out during autosave\n modifiedRef.current = modified\n\n // Store locale in ref so the autosave func\n // can always retrieve the most to date locale\n localeRef.current = locale\n\n const processQueue = React.useCallback(async () => {\n if (isProcessingRef.current || queueRef.current.length === 0) {\n return\n }\n\n if (!isValidRef.current) {\n // Clear queue so we don't end up in an infinite loop\n queueRef.current = []\n // Reset internal validation state so queue processing can run again\n isValidRef.current = true\n return\n }\n isProcessingRef.current = true\n\n const latestAction = queueRef.current[queueRef.current.length - 1]\n queueRef.current = []\n\n try {\n await latestAction()\n } finally {\n isProcessingRef.current = false\n if (queueRef.current.length > 0) {\n await processQueue()\n }\n }\n }, [])\n\n const autosaveTimeoutRef = useRef<NodeJS.Timeout | null>(null)\n\n const handleAutosave = useEffectEvent(() => {\n autosaveTimeoutRef.current = undefined\n // We need to log the time in order to figure out if we need to trigger the state off later\n let startTimestamp = undefined\n let endTimestamp = undefined\n\n const hideIndicator = () => {\n // If request was faster than minimum animation time, animate the difference\n if (endTimestamp - startTimestamp < minimumAnimationTime) {\n autosaveTimeoutRef.current = setTimeout(\n () => {\n setSaving(false)\n },\n minimumAnimationTime - (endTimestamp - startTimestamp),\n )\n } else {\n stopAutoSaveIndicator()\n }\n }\n\n const autosave = async () => {\n if (modified) {\n startTimestamp = new Date().getTime()\n\n setSaving(true)\n\n let url: string\n let method: string\n let entitySlug: string\n\n if (collection && id) {\n entitySlug = collection.slug\n url = `${serverURL}${api}/${entitySlug}/${id}?draft=true&autosave=true&locale=${localeRef.current}`\n method = 'PATCH'\n }\n\n if (globalDoc) {\n entitySlug = globalDoc.slug\n url = `${serverURL}${api}/globals/${entitySlug}?draft=true&autosave=true&locale=${localeRef.current}`\n method = 'POST'\n }\n\n if (url) {\n if (modifiedRef.current) {\n const { data, valid } = reduceFieldsToValuesWithValidation(fieldRef.current, true)\n\n data._status = 'draft'\n\n const skipSubmission =\n submitted && !valid && versionsConfig?.drafts && versionsConfig?.drafts?.validate\n\n if (!skipSubmission && isValidRef.current) {\n let res\n try {\n res = await fetch(url, {\n body: JSON.stringify(data),\n credentials: 'include',\n headers: {\n 'Accept-Language': i18n.language,\n 'Content-Type': 'application/json',\n },\n method,\n })\n } catch (error) {\n // Swallow Error\n }\n\n const newDate = new Date()\n // We need to log the time in order to figure out if we need to trigger the state off later\n endTimestamp = newDate.getTime()\n\n if (res.status === 200) {\n setLastUpdateTime(newDate.getTime())\n\n reportUpdate({\n id,\n entitySlug,\n updatedAt: newDate.toISOString(),\n })\n\n if (!mostRecentVersionIsAutosaved) {\n incrementVersionCount()\n setMostRecentVersionIsAutosaved(true)\n setUnpublishedVersionCount((prev) => prev + 1)\n }\n }\n const json = await res.json()\n\n if (versionsConfig?.drafts && versionsConfig?.drafts?.validate && json?.errors) {\n if (Array.isArray(json.errors)) {\n const [fieldErrors, nonFieldErrors] = json.errors.reduce(\n ([fieldErrs, nonFieldErrs], err) => {\n const newFieldErrs = []\n const newNonFieldErrs = []\n\n if (err?.message) {\n newNonFieldErrs.push(err)\n }\n\n if (Array.isArray(err?.data)) {\n err.data.forEach((dataError) => {\n if (dataError?.field) {\n newFieldErrs.push(dataError)\n } else {\n newNonFieldErrs.push(dataError)\n }\n })\n }\n\n return [\n [...fieldErrs, ...newFieldErrs],\n [...nonFieldErrs, ...newNonFieldErrs],\n ]\n },\n [[], []],\n )\n\n dispatchFields({\n type: 'ADD_SERVER_ERRORS',\n errors: fieldErrors,\n })\n\n nonFieldErrors.forEach((err) => {\n toast.error(err.message || i18n.t('error:unknown'))\n })\n\n // Set valid to false internally so the queue doesn't process\n isValidRef.current = false\n setIsValid(false)\n setSubmitted(true)\n hideIndicator()\n return\n }\n } else {\n // If it's not an error then we can update the document data inside the context\n const document = json?.doc || json?.result\n\n // Manually update the data since this function doesn't fire the `submit` function from useForm\n if (document) {\n setIsValid(true)\n\n // Reset internal state allowing the queue to process\n isValidRef.current = true\n updateSavedDocumentData(document)\n }\n }\n\n hideIndicator()\n }\n }\n }\n }\n }\n\n queueRef.current.push(autosave)\n void processQueue()\n })\n\n const didMount = useRef(false)\n const previousDebouncedFieldValues = useRef(reduceFieldsToValues(debouncedFields))\n // When debounced fields change, autosave\n useEffect(() => {\n /**\n * Ensure autosave doesn't run on mount\n */\n if (!didMount.current) {\n didMount.current = true\n return\n }\n\n /**\n * Ensure autosave only runs if the form data changes, not every time the entire form state changes\n */\n const debouncedFieldValues = reduceFieldsToValues(debouncedFields)\n if (dequal(debouncedFieldValues, previousDebouncedFieldValues)) {\n return\n }\n\n previousDebouncedFieldValues.current = debouncedFieldValues\n\n handleAutosave()\n }, [debouncedFields])\n\n /**\n * If component unmounts, clear the autosave timeout\n */\n useEffect(() => {\n return () => {\n stopAutoSaveIndicator()\n }\n }, [])\n\n const stopAutoSaveIndicator = useEffectEvent(() => {\n if (autosaveTimeoutRef.current) {\n clearTimeout(autosaveTimeoutRef.current)\n }\n\n setSaving(false)\n })\n\n return (\n <div className={baseClass}>\n {validateOnDraft && !isValid && <LeaveWithoutSaving />}\n {saving && t('general:saving')}\n {!saving && Boolean(lastUpdateTime) && (\n <React.Fragment>\n {t('version:lastSavedAgo', {\n distance: formatTimeToNow({ date: lastUpdateTime, i18n }),\n })}\n </React.Fragment>\n )}\n </div>\n )\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"index.js","names":["versionDefaults","React","useEffect","useRef","useState","toast","useAllFormFields","useForm","useFormModified","useFormSubmitted","useDebounce","useEffectEvent","useConfig","useDocumentEvents","useDocumentInfo","useLocale","useTranslation","formatTimeToNow","reduceFieldsToValuesWithValidation","baseClass","minimumAnimationTime","Autosave","id","collection","global","globalDoc","config","routes","api","serverURL","docConfig","incrementVersionCount","lastUpdateTime","mostRecentVersionIsAutosaved","setLastUpdateTime","setMostRecentVersionIsAutosaved","setUnpublishedVersionCount","updateSavedDocumentData","queueRef","isProcessingRef","reportUpdate","dispatchFields","setSubmitted","submitted","versionsConfig","versions","fields","modified","code","locale","i18n","t","interval","autosaveInterval","drafts","autosave","saving","setSaving","debouncedFields","fieldRef","modifiedRef","localeRef","debouncedRef","current","processQueue","useCallback","length","latestAction","handleAutosave","abortController","AbortController","autosaveTimeout","undefined","startTimestamp","endTimestamp","Date","getTime","url","method","entitySlug","slug","data","valid","_status","skipSubmission","validate","fetch","body","JSON","stringify","credentials","headers","language","signal","then","res","newDate","status","updatedAt","toISOString","prev","json","errors","Array","isArray","fieldErrors","nonFieldErrors","reduce","fieldErrs","nonFieldErrs","err","newFieldErrs","newNonFieldErrs","message","push","forEach","dataError","field","type","error","document","doc","result","setTimeout","clearTimeout","abort","_jsxs","className","Boolean","_jsx","Fragment","distance","date"],"sources":["../../../src/elements/Autosave/index.tsx"],"sourcesContent":["'use client'\n// TODO: abstract the `next/navigation` dependency out from this component\nimport type { ClientCollectionConfig, ClientGlobalConfig } from 'payload'\n\nimport { versionDefaults } from 'payload/shared'\nimport React, { useEffect, useRef, useState } from 'react'\nimport { toast } from 'sonner'\n\nimport {\n useAllFormFields,\n useForm,\n useFormModified,\n useFormSubmitted,\n} from '../../forms/Form/context.js'\nimport { useDebounce } from '../../hooks/useDebounce.js'\nimport { useEffectEvent } from '../../hooks/useEffectEvent.js'\nimport { useConfig } from '../../providers/Config/index.js'\nimport { useDocumentEvents } from '../../providers/DocumentEvents/index.js'\nimport { useDocumentInfo } from '../../providers/DocumentInfo/index.js'\nimport { useLocale } from '../../providers/Locale/index.js'\nimport { useTranslation } from '../../providers/Translation/index.js'\nimport './index.scss'\nimport { formatTimeToNow } from '../../utilities/formatDate.js'\nimport { reduceFieldsToValuesWithValidation } from '../../utilities/reduceFieldsToValuesWithValidation.js'\n\nconst baseClass = 'autosave'\n// The minimum time the saving state should be shown\nconst minimumAnimationTime = 1000\n\nexport type Props = {\n collection?: ClientCollectionConfig\n global?: ClientGlobalConfig\n id?: number | string\n publishedDocUpdatedAt: string\n}\n\nexport const Autosave: React.FC<Props> = ({ id, collection, global: globalDoc }) => {\n const {\n config: {\n routes: { api },\n serverURL,\n },\n } = useConfig()\n const {\n docConfig,\n incrementVersionCount,\n lastUpdateTime,\n mostRecentVersionIsAutosaved,\n setLastUpdateTime,\n setMostRecentVersionIsAutosaved,\n setUnpublishedVersionCount,\n updateSavedDocumentData,\n } = useDocumentInfo()\n const queueRef = useRef([])\n const isProcessingRef = useRef(false)\n\n const { reportUpdate } = useDocumentEvents()\n const { dispatchFields, setSubmitted } = useForm()\n const submitted = useFormSubmitted()\n const versionsConfig = docConfig?.versions\n\n const [fields] = useAllFormFields()\n const modified = useFormModified()\n const { code: locale } = useLocale()\n const { i18n, t } = useTranslation()\n\n let interval = versionDefaults.autosaveInterval\n if (versionsConfig.drafts && versionsConfig.drafts.autosave) {\n interval = versionsConfig.drafts.autosave.interval\n }\n\n const [saving, setSaving] = useState(false)\n const debouncedFields = useDebounce(fields, interval)\n const fieldRef = useRef(fields)\n const modifiedRef = useRef(modified)\n const localeRef = useRef(locale)\n const debouncedRef = useRef(debouncedFields)\n\n debouncedRef.current = debouncedFields\n\n // Store fields in ref so the autosave func\n // can always retrieve the most to date copies\n // after the timeout has executed\n fieldRef.current = fields\n\n // Store modified in ref so the autosave func\n // can bail out if modified becomes false while\n // timing out during autosave\n modifiedRef.current = modified\n\n // Store locale in ref so the autosave func\n // can always retrieve the most to date locale\n localeRef.current = locale\n\n const processQueue = React.useCallback(async () => {\n if (isProcessingRef.current || queueRef.current.length === 0) {\n return\n }\n\n isProcessingRef.current = true\n const latestAction = queueRef.current[queueRef.current.length - 1]\n queueRef.current = []\n\n try {\n await latestAction()\n } finally {\n isProcessingRef.current = false\n if (queueRef.current.length > 0) {\n await processQueue()\n }\n }\n }, [])\n\n const handleAutosave = useEffectEvent(() => {\n const abortController = new AbortController()\n let autosaveTimeout = undefined\n // We need to log the time in order to figure out if we need to trigger the state off later\n let startTimestamp = undefined\n let endTimestamp = undefined\n\n const autosave = async () => {\n if (modified) {\n startTimestamp = new Date().getTime()\n\n setSaving(true)\n\n let url: string\n let method: string\n let entitySlug: string\n\n if (collection && id) {\n entitySlug = collection.slug\n url = `${serverURL}${api}/${entitySlug}/${id}?draft=true&autosave=true&locale=${localeRef.current}`\n method = 'PATCH'\n }\n\n if (globalDoc) {\n entitySlug = globalDoc.slug\n url = `${serverURL}${api}/globals/${entitySlug}?draft=true&autosave=true&locale=${localeRef.current}`\n method = 'POST'\n }\n\n if (url) {\n if (modifiedRef.current) {\n const { data, valid } = {\n ...reduceFieldsToValuesWithValidation(fieldRef.current, true),\n }\n data._status = 'draft'\n const skipSubmission =\n submitted && !valid && versionsConfig?.drafts && versionsConfig?.drafts?.validate\n\n if (!skipSubmission) {\n await fetch(url, {\n body: JSON.stringify(data),\n credentials: 'include',\n headers: {\n 'Accept-Language': i18n.language,\n 'Content-Type': 'application/json',\n },\n method,\n signal: abortController.signal,\n })\n .then((res) => {\n const newDate = new Date()\n // We need to log the time in order to figure out if we need to trigger the state off later\n endTimestamp = newDate.getTime()\n\n if (res.status === 200) {\n setLastUpdateTime(newDate.getTime())\n\n reportUpdate({\n id,\n entitySlug,\n updatedAt: newDate.toISOString(),\n })\n\n if (!mostRecentVersionIsAutosaved) {\n incrementVersionCount()\n setMostRecentVersionIsAutosaved(true)\n setUnpublishedVersionCount((prev) => prev + 1)\n }\n }\n\n return res.json()\n })\n .then((json) => {\n if (versionsConfig?.drafts && versionsConfig?.drafts?.validate && json?.errors) {\n if (Array.isArray(json.errors)) {\n const [fieldErrors, nonFieldErrors] = json.errors.reduce(\n ([fieldErrs, nonFieldErrs], err) => {\n const newFieldErrs = []\n const newNonFieldErrs = []\n\n if (err?.message) {\n newNonFieldErrs.push(err)\n }\n\n if (Array.isArray(err?.data)) {\n err.data.forEach((dataError) => {\n if (dataError?.field) {\n newFieldErrs.push(dataError)\n } else {\n newNonFieldErrs.push(dataError)\n }\n })\n }\n\n return [\n [...fieldErrs, ...newFieldErrs],\n [...nonFieldErrs, ...newNonFieldErrs],\n ]\n },\n [[], []],\n )\n\n dispatchFields({\n type: 'ADD_SERVER_ERRORS',\n errors: fieldErrors,\n })\n\n nonFieldErrors.forEach((err) => {\n toast.error(err.message || i18n.t('error:unknown'))\n })\n\n setSubmitted(true)\n setSaving(false)\n return\n }\n } else {\n // If it's not an error then we can update the document data inside the context\n const document = json?.doc || json?.result\n\n // Manually update the data since this function doesn't fire the `submit` function from useForm\n if (document) {\n updateSavedDocumentData(document)\n }\n }\n })\n .then(() => {\n // If request was faster than minimum animation time, animate the difference\n if (endTimestamp - startTimestamp < minimumAnimationTime) {\n autosaveTimeout = setTimeout(\n () => {\n setSaving(false)\n },\n minimumAnimationTime - (endTimestamp - startTimestamp),\n )\n } else {\n setSaving(false)\n }\n })\n }\n }\n }\n }\n }\n\n queueRef.current.push(autosave)\n void processQueue()\n\n return { abortController, autosaveTimeout }\n })\n\n // When debounced fields change, autosave\n useEffect(() => {\n const { abortController, autosaveTimeout } = handleAutosave()\n\n return () => {\n if (autosaveTimeout) {\n clearTimeout(autosaveTimeout)\n }\n if (abortController.signal) {\n try {\n abortController.abort('Autosave closed early.')\n } catch (error) {\n // swallow error\n }\n }\n setSaving(false)\n }\n }, [debouncedFields])\n\n return (\n <div className={baseClass}>\n {saving && t('general:saving')}\n {!saving && Boolean(lastUpdateTime) && (\n <React.Fragment>\n {t('version:lastSavedAgo', {\n distance: formatTimeToNow({ date: lastUpdateTime, i18n }),\n })}\n </React.Fragment>\n )}\n </div>\n )\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/DeleteDocument/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAA;AAKxD,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/DeleteDocument/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAA;AAKxD,OAAO,KAA2C,MAAM,OAAO,CAAA;AAG/D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAA;AAc9E,OAAO,cAAc,CAAA;AAIrB,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,cAAc,EAAE,yBAAyB,CAAC,MAAM,CAAC,CAAA;IAC1D,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,QAAQ,CAAC,EAAE,yBAAyB,CAAC,UAAU,CAAC,CAAA;IACzD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAA;IACtC,QAAQ,CAAC,aAAa,EAAE,yBAAyB,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAA;IACvE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,UAAU,EAAE,yBAAyB,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAA;CACtE,CAAA;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CA+L1C,CAAA"}
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
4
|
-
import { useModal } from '@faceless-ui/modal';
|
|
4
|
+
import { Modal, useModal } from '@faceless-ui/modal';
|
|
5
5
|
import { getTranslation } from '@payloadcms/translations';
|
|
6
6
|
import { useRouter } from 'next/navigation.js';
|
|
7
|
-
import React, { useCallback } from 'react';
|
|
7
|
+
import React, { useCallback, useEffect, useState } from 'react';
|
|
8
8
|
import { toast } from 'sonner';
|
|
9
9
|
import { useForm } from '../../forms/Form/context.js';
|
|
10
10
|
import { useConfig } from '../../providers/Config/index.js';
|
|
11
11
|
import { useDocumentInfo } from '../../providers/DocumentInfo/index.js';
|
|
12
|
+
import { useEditDepth } from '../../providers/EditDepth/index.js';
|
|
12
13
|
import { useRouteTransition } from '../../providers/RouteTransition/index.js';
|
|
13
14
|
import { useTranslation } from '../../providers/Translation/index.js';
|
|
14
15
|
import { requests } from '../../utilities/api.js';
|
|
15
16
|
import { formatAdminURL } from '../../utilities/formatAdminURL.js';
|
|
16
|
-
import {
|
|
17
|
+
import { Button } from '../Button/index.js';
|
|
18
|
+
import { drawerZBase } from '../Drawer/index.js';
|
|
17
19
|
import { PopupList } from '../Popup/index.js';
|
|
18
20
|
import { Translation } from '../Translation/index.js';
|
|
19
21
|
import './index.scss';
|
|
22
|
+
const baseClass = 'delete-document';
|
|
20
23
|
export const DeleteDocument = props => {
|
|
21
24
|
const {
|
|
22
25
|
id,
|
|
@@ -43,6 +46,11 @@ export const DeleteDocument = props => {
|
|
|
43
46
|
const {
|
|
44
47
|
setModified
|
|
45
48
|
} = useForm();
|
|
49
|
+
const [deleting, setDeleting] = useState(false);
|
|
50
|
+
const {
|
|
51
|
+
closeModal,
|
|
52
|
+
toggleModal
|
|
53
|
+
} = useModal();
|
|
46
54
|
const router = useRouter();
|
|
47
55
|
const {
|
|
48
56
|
i18n,
|
|
@@ -51,23 +59,25 @@ export const DeleteDocument = props => {
|
|
|
51
59
|
const {
|
|
52
60
|
title
|
|
53
61
|
} = useDocumentInfo();
|
|
62
|
+
const editDepth = useEditDepth();
|
|
54
63
|
const {
|
|
55
64
|
startRouteTransition
|
|
56
65
|
} = useRouteTransition();
|
|
57
|
-
const {
|
|
58
|
-
openModal
|
|
59
|
-
} = useModal();
|
|
60
66
|
const titleToRender = titleFromProps || title || id;
|
|
61
67
|
const modalSlug = `delete-${id}`;
|
|
62
68
|
const addDefaultError = useCallback(() => {
|
|
69
|
+
setDeleting(false);
|
|
63
70
|
toast.error(t('error:deletingTitle', {
|
|
64
71
|
title
|
|
65
72
|
}));
|
|
66
73
|
}, [t, title]);
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
return () => {
|
|
76
|
+
closeModal(modalSlug);
|
|
77
|
+
};
|
|
78
|
+
}, [closeModal, modalSlug]);
|
|
79
|
+
const handleDelete = useCallback(async () => {
|
|
80
|
+
setDeleting(true);
|
|
71
81
|
setModified(false);
|
|
72
82
|
try {
|
|
73
83
|
await requests.delete(`${serverURL}${api}/${collectionSlug}/${id}`, {
|
|
@@ -78,9 +88,9 @@ export const DeleteDocument = props => {
|
|
|
78
88
|
}).then(async res => {
|
|
79
89
|
try {
|
|
80
90
|
const json = await res.json();
|
|
81
|
-
setConfirming(false);
|
|
82
|
-
closeConfirmationModal();
|
|
83
91
|
if (res.status < 400) {
|
|
92
|
+
setDeleting(false);
|
|
93
|
+
toggleModal(modalSlug);
|
|
84
94
|
toast.success(t('general:titleDeleted', {
|
|
85
95
|
label: getTranslation(singularLabel, i18n),
|
|
86
96
|
title
|
|
@@ -97,52 +107,83 @@ export const DeleteDocument = props => {
|
|
|
97
107
|
collectionConfig
|
|
98
108
|
});
|
|
99
109
|
}
|
|
110
|
+
toggleModal(modalSlug);
|
|
100
111
|
return;
|
|
101
112
|
}
|
|
113
|
+
toggleModal(modalSlug);
|
|
102
114
|
if (json.errors) {
|
|
103
115
|
json.errors.forEach(error => toast.error(error.message));
|
|
104
116
|
} else {
|
|
105
117
|
addDefaultError();
|
|
106
118
|
}
|
|
107
119
|
return false;
|
|
108
|
-
} catch (
|
|
120
|
+
} catch (e_0) {
|
|
109
121
|
return addDefaultError();
|
|
110
122
|
}
|
|
111
123
|
});
|
|
112
|
-
} catch (
|
|
113
|
-
|
|
114
|
-
closeConfirmationModal();
|
|
115
|
-
return addDefaultError();
|
|
124
|
+
} catch (e) {
|
|
125
|
+
addDefaultError();
|
|
116
126
|
}
|
|
117
|
-
}, [setModified, serverURL, api, collectionSlug, id, t, singularLabel,
|
|
127
|
+
}, [setModified, serverURL, api, collectionSlug, id, toggleModal, modalSlug, t, singularLabel, i18n, title, router, adminRoute, addDefaultError, redirectAfterDelete, onDelete, collectionConfig, startRouteTransition]);
|
|
118
128
|
if (id) {
|
|
119
129
|
return /*#__PURE__*/_jsxs(React.Fragment, {
|
|
120
130
|
children: [/*#__PURE__*/_jsx(PopupList.Button, {
|
|
121
131
|
id: buttonId,
|
|
122
132
|
onClick: () => {
|
|
123
|
-
|
|
133
|
+
setDeleting(false);
|
|
134
|
+
toggleModal(modalSlug);
|
|
124
135
|
},
|
|
125
136
|
children: t('general:delete')
|
|
126
|
-
}), /*#__PURE__*/_jsx(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
137
|
+
}), /*#__PURE__*/_jsx(Modal, {
|
|
138
|
+
className: baseClass,
|
|
139
|
+
slug: modalSlug,
|
|
140
|
+
style: {
|
|
141
|
+
zIndex: drawerZBase + editDepth
|
|
142
|
+
},
|
|
143
|
+
children: /*#__PURE__*/_jsxs("div", {
|
|
144
|
+
className: `${baseClass}__wrapper`,
|
|
145
|
+
children: [/*#__PURE__*/_jsxs("div", {
|
|
146
|
+
className: `${baseClass}__content`,
|
|
147
|
+
children: [/*#__PURE__*/_jsx("h1", {
|
|
148
|
+
children: t('general:confirmDeletion')
|
|
149
|
+
}), /*#__PURE__*/_jsx("p", {
|
|
150
|
+
children: /*#__PURE__*/_jsx(Translation, {
|
|
151
|
+
elements: {
|
|
152
|
+
'1': ({
|
|
153
|
+
children
|
|
154
|
+
}) => /*#__PURE__*/_jsx("strong", {
|
|
155
|
+
children: children
|
|
156
|
+
})
|
|
157
|
+
},
|
|
158
|
+
i18nKey: "general:aboutToDelete",
|
|
159
|
+
t: t,
|
|
160
|
+
variables: {
|
|
161
|
+
label: getTranslation(singularLabel, i18n),
|
|
162
|
+
title: titleToRender
|
|
163
|
+
}
|
|
164
|
+
})
|
|
165
|
+
})]
|
|
166
|
+
}), /*#__PURE__*/_jsxs("div", {
|
|
167
|
+
className: `${baseClass}__controls`,
|
|
168
|
+
children: [/*#__PURE__*/_jsx(Button, {
|
|
169
|
+
buttonStyle: "secondary",
|
|
170
|
+
id: "confirm-cancel",
|
|
171
|
+
onClick: deleting ? undefined : () => toggleModal(modalSlug),
|
|
172
|
+
size: "large",
|
|
173
|
+
type: "button",
|
|
174
|
+
children: t('general:cancel')
|
|
175
|
+
}), /*#__PURE__*/_jsx(Button, {
|
|
176
|
+
id: "confirm-delete",
|
|
177
|
+
onClick: () => {
|
|
178
|
+
if (!deleting) {
|
|
179
|
+
void handleDelete();
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
size: "large",
|
|
183
|
+
children: deleting ? t('general:deleting') : t('general:confirm')
|
|
184
|
+
})]
|
|
185
|
+
})]
|
|
186
|
+
})
|
|
146
187
|
})]
|
|
147
188
|
});
|
|
148
189
|
}
|