@payloadcms/ui 3.0.0-beta.67 → 3.0.0-beta.68
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 +44 -28
- package/dist/elements/Autosave/index.js.map +1 -1
- package/dist/elements/Upload/index.d.ts.map +1 -1
- package/dist/elements/Upload/index.js +1 -1
- package/dist/elements/Upload/index.js.map +1 -1
- package/dist/elements/withMergedProps/index.js +8 -2
- package/dist/elements/withMergedProps/index.js.map +1 -1
- package/dist/exports/client/index.js +6 -6
- package/dist/exports/client/index.js.map +4 -4
- package/dist/exports/shared/index.js +2 -2
- package/dist/exports/shared/index.js.map +3 -3
- package/dist/forms/Form/fieldReducer.d.ts.map +1 -1
- package/dist/forms/Form/fieldReducer.js +6 -3
- package/dist/forms/Form/fieldReducer.js.map +1 -1
- package/dist/providers/Auth/index.d.ts.map +1 -1
- package/dist/providers/Auth/index.js +2 -39
- package/dist/providers/Auth/index.js.map +1 -1
- package/dist/providers/DocumentInfo/index.d.ts.map +1 -1
- package/dist/providers/DocumentInfo/index.js +20 -14
- package/dist/providers/DocumentInfo/index.js.map +1 -1
- package/package.json +4 -4
|
@@ -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;AAGzE,OAAO,KAAsC,MAAM,OAAO,CAAA;AAiB1D,OAAO,cAAc,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;AAiB1D,OAAO,cAAc,CAAA;AAMrB,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,CAqOpC,CAAA"}
|
|
@@ -14,6 +14,8 @@ import { formatTimeToNow } from '../../utilities/formatDate.js';
|
|
|
14
14
|
import { reduceFieldsToValuesWithValidation } from '../../utilities/reduceFieldsToValuesWithValidation.js';
|
|
15
15
|
import './index.scss';
|
|
16
16
|
const baseClass = 'autosave';
|
|
17
|
+
// The minimum time the saving state should be shown
|
|
18
|
+
const minimumAnimationTime = 1000;
|
|
17
19
|
export const Autosave = ({ id, collection, global: globalDoc, publishedDocUpdatedAt })=>{
|
|
18
20
|
const { routes: { api }, serverURL } = useConfig();
|
|
19
21
|
const { docConfig, getVersions, versions } = useDocumentInfo();
|
|
@@ -47,13 +49,16 @@ export const Autosave = ({ id, collection, global: globalDoc, publishedDocUpdate
|
|
|
47
49
|
// Store locale in ref so the autosave func
|
|
48
50
|
// can always retrieve the most to date locale
|
|
49
51
|
localeRef.current = locale;
|
|
50
|
-
console.log(modifiedRef.current, modified);
|
|
51
52
|
// When debounced fields change, autosave
|
|
52
53
|
useEffect(()=>{
|
|
53
54
|
const abortController = new AbortController();
|
|
54
55
|
let autosaveTimeout = undefined;
|
|
56
|
+
// We need to log the time in order to figure out if we need to trigger the state off later
|
|
57
|
+
let startTimestamp = undefined;
|
|
58
|
+
let endTimestamp = undefined;
|
|
55
59
|
const autosave = ()=>{
|
|
56
60
|
if (modified) {
|
|
61
|
+
startTimestamp = new Date().getTime();
|
|
57
62
|
setSaving(true);
|
|
58
63
|
let url;
|
|
59
64
|
let method;
|
|
@@ -69,37 +74,40 @@ export const Autosave = ({ id, collection, global: globalDoc, publishedDocUpdate
|
|
|
69
74
|
method = 'POST';
|
|
70
75
|
}
|
|
71
76
|
if (url) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
77
|
+
if (modifiedRef.current) {
|
|
78
|
+
const { data, valid } = {
|
|
79
|
+
...reduceFieldsToValuesWithValidation(fieldRef.current, true)
|
|
80
|
+
};
|
|
81
|
+
data._status = 'draft';
|
|
82
|
+
const skipSubmission = submitted && !valid && versionsConfig?.drafts && versionsConfig?.drafts?.validate;
|
|
83
|
+
if (!skipSubmission) {
|
|
84
|
+
void fetch(url, {
|
|
85
|
+
body: JSON.stringify(data),
|
|
86
|
+
credentials: 'include',
|
|
87
|
+
headers: {
|
|
88
|
+
'Accept-Language': i18n.language,
|
|
89
|
+
'Content-Type': 'application/json'
|
|
90
|
+
},
|
|
91
|
+
method,
|
|
92
|
+
signal: abortController.signal
|
|
93
|
+
}).then((res)=>{
|
|
94
|
+
const newDate = new Date();
|
|
95
|
+
// We need to log the time in order to figure out if we need to trigger the state off later
|
|
96
|
+
endTimestamp = newDate.getTime();
|
|
90
97
|
if (res.status === 200) {
|
|
91
|
-
const newDate = new Date();
|
|
92
98
|
setLastSaved(newDate.getTime());
|
|
93
|
-
setModified(false);
|
|
94
99
|
reportUpdate({
|
|
95
100
|
id,
|
|
96
101
|
entitySlug,
|
|
97
102
|
updatedAt: newDate.toISOString()
|
|
98
103
|
});
|
|
104
|
+
setModified(false);
|
|
99
105
|
void getVersions();
|
|
106
|
+
} else {
|
|
107
|
+
return res.json();
|
|
100
108
|
}
|
|
101
|
-
|
|
102
|
-
|
|
109
|
+
}).then((json)=>{
|
|
110
|
+
if (versionsConfig?.drafts && versionsConfig?.drafts?.validate && json.errors) {
|
|
103
111
|
if (Array.isArray(json.errors)) {
|
|
104
112
|
const [fieldErrors, nonFieldErrors] = json.errors.reduce(([fieldErrs, nonFieldErrs], err)=>{
|
|
105
113
|
const newFieldErrs = [];
|
|
@@ -142,16 +150,24 @@ export const Autosave = ({ id, collection, global: globalDoc, publishedDocUpdate
|
|
|
142
150
|
return;
|
|
143
151
|
}
|
|
144
152
|
}
|
|
145
|
-
}
|
|
153
|
+
}).then(()=>{
|
|
154
|
+
// If request was faster than minimum animation time, animate the difference
|
|
155
|
+
if (endTimestamp - startTimestamp < minimumAnimationTime) {
|
|
156
|
+
autosaveTimeout = setTimeout(()=>{
|
|
157
|
+
setSaving(false);
|
|
158
|
+
}, minimumAnimationTime - (endTimestamp - startTimestamp));
|
|
159
|
+
} else {
|
|
160
|
+
setSaving(false);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
146
163
|
}
|
|
147
|
-
|
|
148
|
-
}, 1000);
|
|
164
|
+
}
|
|
149
165
|
}
|
|
150
166
|
}
|
|
151
167
|
};
|
|
152
168
|
void autosave();
|
|
153
169
|
return ()=>{
|
|
154
|
-
clearTimeout(autosaveTimeout);
|
|
170
|
+
if (autosaveTimeout) clearTimeout(autosaveTimeout);
|
|
155
171
|
if (abortController.signal) abortController.abort();
|
|
156
172
|
setSaving(false);
|
|
157
173
|
};
|
|
@@ -187,7 +203,7 @@ export const Autosave = ({ id, collection, global: globalDoc, publishedDocUpdate
|
|
|
187
203
|
className: baseClass,
|
|
188
204
|
children: [
|
|
189
205
|
saving && t('general:saving'),
|
|
190
|
-
!saving && lastSaved && /*#__PURE__*/ _jsx(React.Fragment, {
|
|
206
|
+
!saving && Boolean(lastSaved) && /*#__PURE__*/ _jsx(React.Fragment, {
|
|
191
207
|
children: t('version:lastSavedAgo', {
|
|
192
208
|
distance: formatTimeToNow({
|
|
193
209
|
date: lastSaved,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"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 { 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 { formatTimeToNow } from '../../utilities/formatDate.js'\nimport { reduceFieldsToValuesWithValidation } from '../../utilities/reduceFieldsToValuesWithValidation.js'\nimport './index.scss'\n\nconst baseClass = 'autosave'\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> = ({\n id,\n collection,\n global: globalDoc,\n publishedDocUpdatedAt,\n}) => {\n const {\n routes: { api },\n serverURL,\n } = useConfig()\n const { docConfig, getVersions, versions } = useDocumentInfo()\n const { reportUpdate } = useDocumentEvents()\n const { dispatchFields, setModified, setSubmitted } = useForm()\n const submitted = useFormSubmitted()\n const versionsConfig = docConfig?.versions\n\n const [fields] = useAllFormFields()\n const formModified = 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 const [saving, setSaving] = useState(false)\n const [lastSaved, setLastSaved] = useState<number>()\n const debouncedFields = useDebounce(fields, interval)\n const modified = useDebounce(formModified, 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 console.log(modifiedRef.current, modified)\n // When debounced fields change, autosave\n useEffect(() => {\n const abortController = new AbortController()\n let autosaveTimeout = undefined\n\n const autosave = () => {\n if (modified) {\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 autosaveTimeout = setTimeout(async () => {\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 const 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 signal: abortController.signal,\n })\n\n if (res.status === 200) {\n const newDate = new Date()\n setLastSaved(newDate.getTime())\n setModified(false)\n reportUpdate({\n id,\n entitySlug,\n updatedAt: newDate.toISOString(),\n })\n void getVersions()\n }\n\n if (\n versionsConfig?.drafts &&\n versionsConfig?.drafts?.validate &&\n res.status === 400\n ) {\n const json = await res.json()\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 }\n }\n }\n\n setSaving(false)\n }, 1000)\n }\n }\n }\n\n void autosave()\n\n return () => {\n clearTimeout(autosaveTimeout)\n if (abortController.signal) abortController.abort()\n setSaving(false)\n }\n }, [\n api,\n collection,\n dispatchFields,\n getVersions,\n globalDoc,\n i18n,\n id,\n interval,\n modified,\n reportUpdate,\n serverURL,\n setSubmitted,\n setModified,\n versionsConfig?.drafts,\n debouncedFields,\n submitted,\n ])\n\n useEffect(() => {\n if (versions?.docs?.[0]) {\n setLastSaved(new Date(versions.docs[0].updatedAt).getTime())\n } else if (publishedDocUpdatedAt) {\n setLastSaved(new Date(publishedDocUpdatedAt).getTime())\n }\n }, [publishedDocUpdatedAt, versions])\n\n return (\n <div className={baseClass}>\n {saving && t('general:saving')}\n {!saving && lastSaved && (\n <React.Fragment>\n {t('version:lastSavedAgo', {\n distance: formatTimeToNow({ date: lastSaved, i18n }),\n })}\n </React.Fragment>\n )}\n </div>\n )\n}\n"],"names":["versionDefaults","React","useEffect","useRef","useState","toast","useAllFormFields","useForm","useFormModified","useFormSubmitted","useDebounce","useConfig","useDocumentEvents","useDocumentInfo","useLocale","useTranslation","formatTimeToNow","reduceFieldsToValuesWithValidation","baseClass","Autosave","id","collection","global","globalDoc","publishedDocUpdatedAt","routes","api","serverURL","docConfig","getVersions","versions","reportUpdate","dispatchFields","setModified","setSubmitted","submitted","versionsConfig","fields","formModified","code","locale","i18n","t","interval","autosaveInterval","drafts","autosave","saving","setSaving","lastSaved","setLastSaved","debouncedFields","modified","fieldRef","modifiedRef","localeRef","debouncedRef","current","console","log","abortController","AbortController","autosaveTimeout","undefined","url","method","entitySlug","slug","setTimeout","data","valid","_status","skipSubmission","validate","res","fetch","body","JSON","stringify","credentials","headers","language","signal","status","newDate","Date","getTime","updatedAt","toISOString","json","Array","isArray","errors","fieldErrors","nonFieldErrors","reduce","fieldErrs","nonFieldErrs","err","newFieldErrs","newNonFieldErrs","message","push","forEach","dataError","field","type","error","clearTimeout","abort","docs","div","className","Fragment","distance","date"],"mappings":"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"}
|
|
1
|
+
{"version":3,"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 { 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 { formatTimeToNow } from '../../utilities/formatDate.js'\nimport { reduceFieldsToValuesWithValidation } from '../../utilities/reduceFieldsToValuesWithValidation.js'\nimport './index.scss'\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> = ({\n id,\n collection,\n global: globalDoc,\n publishedDocUpdatedAt,\n}) => {\n const {\n routes: { api },\n serverURL,\n } = useConfig()\n const { docConfig, getVersions, versions } = useDocumentInfo()\n const { reportUpdate } = useDocumentEvents()\n const { dispatchFields, setModified, setSubmitted } = useForm()\n const submitted = useFormSubmitted()\n const versionsConfig = docConfig?.versions\n\n const [fields] = useAllFormFields()\n const formModified = 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 const [saving, setSaving] = useState(false)\n const [lastSaved, setLastSaved] = useState<number>()\n const debouncedFields = useDebounce(fields, interval)\n const modified = useDebounce(formModified, 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 // When debounced fields change, autosave\n useEffect(() => {\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 = () => {\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 void 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 setLastSaved(newDate.getTime())\n\n reportUpdate({\n id,\n entitySlug,\n updatedAt: newDate.toISOString(),\n })\n setModified(false)\n void getVersions()\n } else {\n return res.json()\n }\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 }\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 void autosave()\n\n return () => {\n if (autosaveTimeout) clearTimeout(autosaveTimeout)\n if (abortController.signal) abortController.abort()\n setSaving(false)\n }\n }, [\n api,\n collection,\n dispatchFields,\n getVersions,\n globalDoc,\n i18n,\n id,\n interval,\n modified,\n reportUpdate,\n serverURL,\n setSubmitted,\n setModified,\n versionsConfig?.drafts,\n debouncedFields,\n submitted,\n ])\n\n useEffect(() => {\n if (versions?.docs?.[0]) {\n setLastSaved(new Date(versions.docs[0].updatedAt).getTime())\n } else if (publishedDocUpdatedAt) {\n setLastSaved(new Date(publishedDocUpdatedAt).getTime())\n }\n }, [publishedDocUpdatedAt, versions])\n\n return (\n <div className={baseClass}>\n {saving && t('general:saving')}\n {!saving && Boolean(lastSaved) && (\n <React.Fragment>\n {t('version:lastSavedAgo', {\n distance: formatTimeToNow({ date: lastSaved, i18n }),\n })}\n </React.Fragment>\n )}\n </div>\n )\n}\n"],"names":["versionDefaults","React","useEffect","useRef","useState","toast","useAllFormFields","useForm","useFormModified","useFormSubmitted","useDebounce","useConfig","useDocumentEvents","useDocumentInfo","useLocale","useTranslation","formatTimeToNow","reduceFieldsToValuesWithValidation","baseClass","minimumAnimationTime","Autosave","id","collection","global","globalDoc","publishedDocUpdatedAt","routes","api","serverURL","docConfig","getVersions","versions","reportUpdate","dispatchFields","setModified","setSubmitted","submitted","versionsConfig","fields","formModified","code","locale","i18n","t","interval","autosaveInterval","drafts","autosave","saving","setSaving","lastSaved","setLastSaved","debouncedFields","modified","fieldRef","modifiedRef","localeRef","debouncedRef","current","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","json","errors","Array","isArray","fieldErrors","nonFieldErrors","reduce","fieldErrs","nonFieldErrs","err","newFieldErrs","newNonFieldErrs","message","push","forEach","dataError","field","type","error","setTimeout","clearTimeout","abort","docs","div","className","Boolean","Fragment","distance","date"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/Upload/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,yBAAyB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/Upload/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,yBAAyB,EAAe,MAAM,SAAS,CAAA;AAIhF,OAAO,KAAmD,MAAM,OAAO,CAAA;AAevE,OAAO,cAAc,CAAA;AAGrB,eAAO,MAAM,cAAc,gBAAgB,CAAA;AAC3C,eAAO,MAAM,eAAe,kBAAkB,CAAA;AAU9C,KAAK,iBAAiB,GAAG;IACvB,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,CAAA;IACjC,iBAAiB,EAAE,OAAO,CAAA;IAC1B,kBAAkB,EAAE,OAAO,CAAA;IAC3B,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,eAAO,MAAM,aAAa,wEAKvB,iBAAiB,sBA8BnB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,cAAc,EAAE,MAAM,CAAA;IACtB,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,CAAA;IACjC,YAAY,CAAC,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,KAAK,IAAI,CAAA;IAChC,YAAY,EAAE,yBAAyB,CAAC,QAAQ,CAAC,CAAA;CAClD,CAAA;AAED,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAwQxC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/elements/Upload/index.tsx"],"sourcesContent":["'use client'\nimport type { FormState, SanitizedCollectionConfig , UploadEdits } from 'payload'\n\nimport { useForm, useUploadEdits } from '@payloadcms/ui'\nimport { isImage, reduceFieldsToValues } from 'payload/shared'\nimport React, { useCallback, useEffect, useRef, useState } from 'react'\nimport { toast } from 'sonner'\n\nimport { FieldError } from '../../fields/FieldError/index.js'\nimport { fieldBaseClass } from '../../fields/shared/index.js'\nimport { useField } from '../../forms/useField/index.js'\nimport { useDocumentInfo } from '../../providers/DocumentInfo/index.js'\nimport { useTranslation } from '../../providers/Translation/index.js'\nimport { Button } from '../Button/index.js'\nimport { Drawer, DrawerToggler } from '../Drawer/index.js'\nimport { Dropzone } from '../Dropzone/index.js'\nimport { EditUpload } from '../EditUpload/index.js'\nimport { FileDetails } from '../FileDetails/index.js'\nimport { PreviewSizes } from '../PreviewSizes/index.js'\nimport { Thumbnail } from '../Thumbnail/index.js'\nimport './index.scss'\n\nconst baseClass = 'file-field'\nexport const editDrawerSlug = 'edit-upload'\nexport const sizePreviewSlug = 'preview-sizes'\n\nconst validate = (value) => {\n if (!value && value !== undefined) {\n return 'A file is required.'\n }\n\n return true\n}\n\ntype UploadActionsArgs = {\n customActions?: React.ReactNode[]\n enableAdjustments: boolean\n enablePreviewSizes: boolean\n mimeType: string\n}\n\nexport const UploadActions = ({\n customActions,\n enableAdjustments,\n enablePreviewSizes,\n mimeType,\n}: UploadActionsArgs) => {\n const { t } = useTranslation()\n\n const fileTypeIsAdjustable = isImage(mimeType) && mimeType !== 'image/svg+xml'\n\n if (!fileTypeIsAdjustable && (!customActions || customActions.length === 0)) return null\n\n return (\n <div className={`${baseClass}__upload-actions`}>\n {fileTypeIsAdjustable && (\n <React.Fragment>\n {enablePreviewSizes && (\n <DrawerToggler className={`${baseClass}__previewSizes`} slug={sizePreviewSlug}>\n {t('upload:previewSizes')}\n </DrawerToggler>\n )}\n {enableAdjustments && (\n <DrawerToggler className={`${baseClass}__edit`} slug={editDrawerSlug}>\n {t('upload:editImage')}\n </DrawerToggler>\n )}\n </React.Fragment>\n )}\n\n {customActions &&\n customActions.map((CustomAction, i) => {\n return <React.Fragment key={i}>{CustomAction}</React.Fragment>\n })}\n </div>\n )\n}\n\nexport type UploadProps = {\n collectionSlug: string\n customActions?: React.ReactNode[]\n initialState?: FormState\n onChange?: (file?: File) => void\n uploadConfig: SanitizedCollectionConfig['upload']\n}\n\nexport const Upload: React.FC<UploadProps> = (props) => {\n const { collectionSlug, customActions, initialState, onChange, uploadConfig } = props\n\n const [replacingFile, setReplacingFile] = useState(false)\n const [fileSrc, setFileSrc] = useState<null | string>(null)\n const { t } = useTranslation()\n const { setModified } = useForm()\n const { resetUploadEdits, updateUploadEdits, uploadEdits } = useUploadEdits()\n const [doc, setDoc] = useState(reduceFieldsToValues(initialState || {}, true))\n const { docPermissions } = useDocumentInfo()\n const { errorMessage, setValue, showError, value } = useField<File>({\n path: 'file',\n validate,\n })\n\n const [showUrlInput, setShowUrlInput] = useState(false)\n const [fileUrl, setFileUrl] = useState<string>('')\n\n const cursorPositionRef = useRef(null)\n const urlInputRef = useRef<HTMLInputElement>(null)\n\n const handleFileChange = useCallback(\n (newFile: File) => {\n if (newFile instanceof File) {\n const fileReader = new FileReader()\n fileReader.onload = (e) => {\n const imgSrc = e.target?.result\n\n if (typeof imgSrc === 'string') {\n setFileSrc(imgSrc)\n }\n }\n fileReader.readAsDataURL(newFile)\n }\n\n setValue(newFile)\n setShowUrlInput(false)\n\n if (typeof onChange === 'function') {\n onChange(newFile)\n }\n },\n [onChange, setValue],\n )\n\n const handleFileNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const updatedFileName = e.target.value\n const cursorPosition = e.target.selectionStart\n\n cursorPositionRef.current = cursorPosition\n\n if (value) {\n const fileValue = value\n // Creating a new File object with updated properties\n const newFile = new File([fileValue], updatedFileName, { type: fileValue.type })\n handleFileChange(newFile)\n }\n }\n\n useEffect(() => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n const inputElement = document.querySelector(`.${baseClass}__filename`) as HTMLInputElement\n if (inputElement && cursorPositionRef.current !== null) {\n inputElement.setSelectionRange(cursorPositionRef.current, cursorPositionRef.current)\n }\n }, [value])\n\n const handleFileSelection = useCallback(\n (files: FileList) => {\n const fileToUpload = files?.[0]\n handleFileChange(fileToUpload)\n },\n [handleFileChange],\n )\n\n const handleFileRemoval = useCallback(() => {\n setReplacingFile(true)\n handleFileChange(null)\n setFileSrc('')\n setFileUrl('')\n setDoc({})\n resetUploadEdits()\n setShowUrlInput(false)\n }, [handleFileChange, resetUploadEdits])\n\n const onEditsSave = useCallback(\n (args: UploadEdits) => {\n setModified(true)\n updateUploadEdits(args)\n },\n [setModified, updateUploadEdits],\n )\n\n const handlePasteUrlClick = () => {\n setShowUrlInput((prev) => !prev)\n }\n\n const handleUrlSubmit = async () => {\n if (fileUrl) {\n try {\n const response = await fetch(fileUrl)\n const data = await response.blob()\n\n // Extract the file name from the URL\n const fileName = fileUrl.split('/').pop()\n\n // Create a new File object from the Blob data\n const file = new File([data], fileName, { type: data.type })\n handleFileChange(file)\n } catch (e) {\n toast.error(e.message)\n }\n }\n }\n\n useEffect(() => {\n setDoc(reduceFieldsToValues(initialState || {}, true))\n setReplacingFile(false)\n }, [initialState])\n\n useEffect(() => {\n if (showUrlInput && urlInputRef.current) {\n urlInputRef.current.focus() // Focus on the remote-url input field when showUrlInput is true\n }\n }, [showUrlInput])\n\n const canRemoveUpload =\n docPermissions?.update?.permission &&\n 'delete' in docPermissions &&\n docPermissions?.delete?.permission\n\n const hasImageSizes = uploadConfig?.imageSizes?.length > 0\n const hasResizeOptions = Boolean(uploadConfig?.resizeOptions)\n // Explicity check if set to true, default is undefined\n const focalPointEnabled = uploadConfig?.focalPoint === true\n\n const { crop: showCrop = true, focalPoint = true } = uploadConfig\n\n const showFocalPoint = focalPoint && (hasImageSizes || hasResizeOptions || focalPointEnabled)\n\n return (\n <div className={[fieldBaseClass, baseClass].filter(Boolean).join(' ')}>\n <FieldError message={errorMessage} showError={showError} />\n {doc.filename && !replacingFile && (\n <FileDetails\n collectionSlug={collectionSlug}\n customUploadActions={customActions}\n doc={doc}\n enableAdjustments={showCrop || showFocalPoint}\n handleRemove={canRemoveUpload ? handleFileRemoval : undefined}\n hasImageSizes={hasImageSizes}\n imageCacheTag={doc.updatedAt}\n uploadConfig={uploadConfig}\n />\n )}\n {(!doc.filename || replacingFile) && (\n <div className={`${baseClass}__upload`}>\n {!value && !showUrlInput && (\n <Dropzone\n className={`${baseClass}__dropzone`}\n mimeTypes={uploadConfig?.mimeTypes}\n onChange={handleFileSelection}\n onPasteUrlClick={handlePasteUrlClick}\n />\n )}\n {showUrlInput && (\n <React.Fragment>\n <div className={`${baseClass}__remote-file-wrap`}>\n {/* eslint-disable-next-line jsx-a11y/control-has-associated-label */}\n <input\n className={`${baseClass}__remote-file`}\n onChange={(e) => {\n setFileUrl(e.target.value)\n }}\n ref={urlInputRef}\n type=\"text\"\n value={fileUrl}\n />\n <div className={`${baseClass}__add-file-wrap`}>\n <button\n className={`${baseClass}__add-file`}\n onClick={handleUrlSubmit}\n type=\"button\"\n >\n {t('upload:addImage')}\n </button>\n </div>\n </div>\n <Button\n buttonStyle=\"icon-label\"\n className={`${baseClass}__remove`}\n icon=\"x\"\n iconStyle=\"with-border\"\n onClick={handleFileRemoval}\n round\n tooltip={t('general:cancel')}\n />\n </React.Fragment>\n )}\n {value && fileSrc && (\n <React.Fragment>\n <div className={`${baseClass}__thumbnail-wrap`}>\n <Thumbnail\n collectionSlug={collectionSlug}\n fileSrc={isImage(value.type) ? fileSrc : null}\n />\n </div>\n <div className={`${baseClass}__file-adjustments`}>\n {/* eslint-disable-next-line jsx-a11y/control-has-associated-label */}\n <input\n className={`${baseClass}__filename`}\n onChange={handleFileNameChange}\n type=\"text\"\n value={value.name}\n />\n <UploadActions\n customActions={customActions}\n enableAdjustments={showCrop || showFocalPoint}\n enablePreviewSizes={hasImageSizes && doc.filename && !replacingFile}\n mimeType={value.type}\n />\n </div>\n <Button\n buttonStyle=\"icon-label\"\n className={`${baseClass}__remove`}\n icon=\"x\"\n iconStyle=\"with-border\"\n onClick={handleFileRemoval}\n round\n tooltip={t('general:cancel')}\n />\n </React.Fragment>\n )}\n </div>\n )}\n {(value || doc.filename) && (\n <Drawer Header={null} slug={editDrawerSlug}>\n <EditUpload\n fileName={value?.name || doc?.filename}\n fileSrc={doc?.url || fileSrc}\n imageCacheTag={doc.updatedAt}\n initialCrop={uploadEdits?.crop ?? undefined}\n initialFocalPoint={{\n x: uploadEdits?.focalPoint?.x || doc.focalX || 50,\n y: uploadEdits?.focalPoint?.y || doc.focalY || 50,\n }}\n onSave={onEditsSave}\n showCrop={showCrop}\n showFocalPoint={showFocalPoint}\n />\n </Drawer>\n )}\n {doc && hasImageSizes && (\n <Drawer\n className={`${baseClass}__previewDrawer`}\n hoverTitle\n slug={sizePreviewSlug}\n title={t('upload:sizesFor', { label: doc?.filename })}\n >\n <PreviewSizes doc={doc} imageCacheTag={doc.updatedAt} uploadConfig={uploadConfig} />\n </Drawer>\n )}\n </div>\n )\n}\n"],"names":["useForm","useUploadEdits","isImage","reduceFieldsToValues","React","useCallback","useEffect","useRef","useState","toast","FieldError","fieldBaseClass","useField","useDocumentInfo","useTranslation","Button","Drawer","DrawerToggler","Dropzone","EditUpload","FileDetails","PreviewSizes","Thumbnail","baseClass","editDrawerSlug","sizePreviewSlug","validate","value","undefined","UploadActions","customActions","enableAdjustments","enablePreviewSizes","mimeType","t","fileTypeIsAdjustable","length","div","className","Fragment","slug","map","CustomAction","i","Upload","props","collectionSlug","initialState","onChange","uploadConfig","replacingFile","setReplacingFile","fileSrc","setFileSrc","setModified","resetUploadEdits","updateUploadEdits","uploadEdits","doc","setDoc","docPermissions","errorMessage","setValue","showError","path","showUrlInput","setShowUrlInput","fileUrl","setFileUrl","cursorPositionRef","urlInputRef","handleFileChange","newFile","File","fileReader","FileReader","onload","e","imgSrc","target","result","readAsDataURL","handleFileNameChange","updatedFileName","cursorPosition","selectionStart","current","fileValue","type","inputElement","document","querySelector","setSelectionRange","handleFileSelection","files","fileToUpload","handleFileRemoval","onEditsSave","args","handlePasteUrlClick","prev","handleUrlSubmit","response","fetch","data","blob","fileName","split","pop","file","error","message","focus","canRemoveUpload","update","permission","delete","hasImageSizes","imageSizes","hasResizeOptions","Boolean","resizeOptions","focalPointEnabled","focalPoint","crop","showCrop","showFocalPoint","filter","join","filename","customUploadActions","handleRemove","imageCacheTag","updatedAt","mimeTypes","onPasteUrlClick","input","ref","button","onClick","buttonStyle","icon","iconStyle","round","tooltip","name","Header","url","initialCrop","initialFocalPoint","x","focalX","y","focalY","onSave","hoverTitle","title","label"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/elements/Upload/index.tsx"],"sourcesContent":["'use client'\nimport type { FormState, SanitizedCollectionConfig, UploadEdits } from 'payload'\n\nimport { useForm, useUploadEdits } from '@payloadcms/ui'\nimport { isImage, reduceFieldsToValues } from 'payload/shared'\nimport React, { useCallback, useEffect, useRef, useState } from 'react'\nimport { toast } from 'sonner'\n\nimport { FieldError } from '../../fields/FieldError/index.js'\nimport { fieldBaseClass } from '../../fields/shared/index.js'\nimport { useField } from '../../forms/useField/index.js'\nimport { useDocumentInfo } from '../../providers/DocumentInfo/index.js'\nimport { useTranslation } from '../../providers/Translation/index.js'\nimport { Button } from '../Button/index.js'\nimport { Drawer, DrawerToggler } from '../Drawer/index.js'\nimport { Dropzone } from '../Dropzone/index.js'\nimport { EditUpload } from '../EditUpload/index.js'\nimport { FileDetails } from '../FileDetails/index.js'\nimport { PreviewSizes } from '../PreviewSizes/index.js'\nimport { Thumbnail } from '../Thumbnail/index.js'\nimport './index.scss'\n\nconst baseClass = 'file-field'\nexport const editDrawerSlug = 'edit-upload'\nexport const sizePreviewSlug = 'preview-sizes'\n\nconst validate = (value) => {\n if (!value && value !== undefined) {\n return 'A file is required.'\n }\n\n return true\n}\n\ntype UploadActionsArgs = {\n customActions?: React.ReactNode[]\n enableAdjustments: boolean\n enablePreviewSizes: boolean\n mimeType: string\n}\n\nexport const UploadActions = ({\n customActions,\n enableAdjustments,\n enablePreviewSizes,\n mimeType,\n}: UploadActionsArgs) => {\n const { t } = useTranslation()\n\n const fileTypeIsAdjustable = isImage(mimeType) && mimeType !== 'image/svg+xml'\n\n if (!fileTypeIsAdjustable && (!customActions || customActions.length === 0)) return null\n\n return (\n <div className={`${baseClass}__upload-actions`}>\n {fileTypeIsAdjustable && (\n <React.Fragment>\n {enablePreviewSizes && (\n <DrawerToggler className={`${baseClass}__previewSizes`} slug={sizePreviewSlug}>\n {t('upload:previewSizes')}\n </DrawerToggler>\n )}\n {enableAdjustments && (\n <DrawerToggler className={`${baseClass}__edit`} slug={editDrawerSlug}>\n {t('upload:editImage')}\n </DrawerToggler>\n )}\n </React.Fragment>\n )}\n\n {customActions &&\n customActions.map((CustomAction, i) => {\n return <React.Fragment key={i}>{CustomAction}</React.Fragment>\n })}\n </div>\n )\n}\n\nexport type UploadProps = {\n collectionSlug: string\n customActions?: React.ReactNode[]\n initialState?: FormState\n onChange?: (file?: File) => void\n uploadConfig: SanitizedCollectionConfig['upload']\n}\n\nexport const Upload: React.FC<UploadProps> = (props) => {\n const { collectionSlug, customActions, initialState, onChange, uploadConfig } = props\n\n const [replacingFile, setReplacingFile] = useState(false)\n const [fileSrc, setFileSrc] = useState<null | string>(null)\n const { t } = useTranslation()\n const { setModified } = useForm()\n const { resetUploadEdits, updateUploadEdits, uploadEdits } = useUploadEdits()\n const [doc, setDoc] = useState(reduceFieldsToValues(initialState || {}, true))\n const { docPermissions } = useDocumentInfo()\n const { errorMessage, setValue, showError, value } = useField<File>({\n path: 'file',\n validate,\n })\n\n const [showUrlInput, setShowUrlInput] = useState(false)\n const [fileUrl, setFileUrl] = useState<string>('')\n\n const cursorPositionRef = useRef(null)\n const urlInputRef = useRef<HTMLInputElement>(null)\n\n const handleFileChange = useCallback(\n (newFile: File) => {\n if (newFile instanceof File) {\n const fileReader = new FileReader()\n fileReader.onload = (e) => {\n const imgSrc = e.target?.result\n\n if (typeof imgSrc === 'string') {\n setFileSrc(imgSrc)\n }\n }\n fileReader.readAsDataURL(newFile)\n }\n\n setValue(newFile)\n setShowUrlInput(false)\n\n if (typeof onChange === 'function') {\n onChange(newFile)\n }\n },\n [onChange, setValue],\n )\n\n const handleFileNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const updatedFileName = e.target.value\n const cursorPosition = e.target.selectionStart\n\n cursorPositionRef.current = cursorPosition\n\n if (value) {\n const fileValue = value\n // Creating a new File object with updated properties\n const newFile = new File([fileValue], updatedFileName, { type: fileValue.type })\n handleFileChange(newFile)\n }\n }\n\n useEffect(() => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n const inputElement = document.querySelector(`.${baseClass}__filename`) as HTMLInputElement\n if (inputElement && cursorPositionRef.current !== null) {\n inputElement.setSelectionRange(cursorPositionRef.current, cursorPositionRef.current)\n }\n }, [value])\n\n const handleFileSelection = useCallback(\n (files: FileList) => {\n const fileToUpload = files?.[0]\n handleFileChange(fileToUpload)\n },\n [handleFileChange],\n )\n\n const handleFileRemoval = useCallback(() => {\n setReplacingFile(true)\n handleFileChange(null)\n setFileSrc('')\n setFileUrl('')\n setDoc({})\n resetUploadEdits()\n setShowUrlInput(false)\n }, [handleFileChange, resetUploadEdits])\n\n const onEditsSave = useCallback(\n (args: UploadEdits) => {\n setModified(true)\n updateUploadEdits(args)\n },\n [setModified, updateUploadEdits],\n )\n\n const handlePasteUrlClick = () => {\n setShowUrlInput((prev) => !prev)\n }\n\n const handleUrlSubmit = async () => {\n if (fileUrl) {\n try {\n const response = await fetch(fileUrl)\n const data = await response.blob()\n\n // Extract the file name from the URL\n const fileName = fileUrl.split('/').pop()\n\n // Create a new File object from the Blob data\n const file = new File([data], fileName, { type: data.type })\n handleFileChange(file)\n } catch (e) {\n toast.error(e.message)\n }\n }\n }\n\n useEffect(() => {\n setDoc(reduceFieldsToValues(initialState || {}, true))\n setReplacingFile(false)\n }, [initialState])\n\n useEffect(() => {\n if (showUrlInput && urlInputRef.current) {\n urlInputRef.current.focus() // Focus on the remote-url input field when showUrlInput is true\n }\n }, [showUrlInput])\n\n const canRemoveUpload =\n docPermissions?.update?.permission &&\n 'delete' in docPermissions &&\n docPermissions?.delete?.permission\n\n const hasImageSizes = uploadConfig?.imageSizes?.length > 0\n const hasResizeOptions = Boolean(uploadConfig?.resizeOptions)\n // Explicity check if set to true, default is undefined\n const focalPointEnabled = uploadConfig?.focalPoint === true\n\n const { crop: showCrop = true, focalPoint = true } = uploadConfig\n\n const showFocalPoint = focalPoint && (hasImageSizes || hasResizeOptions || focalPointEnabled)\n\n return (\n <div className={[fieldBaseClass, baseClass].filter(Boolean).join(' ')}>\n <FieldError message={errorMessage} showError={showError} />\n {doc.filename && !replacingFile && (\n <FileDetails\n collectionSlug={collectionSlug}\n customUploadActions={customActions}\n doc={doc}\n enableAdjustments={showCrop || showFocalPoint}\n handleRemove={canRemoveUpload ? handleFileRemoval : undefined}\n hasImageSizes={hasImageSizes}\n imageCacheTag={doc.updatedAt}\n uploadConfig={uploadConfig}\n />\n )}\n {(!doc.filename || replacingFile) && (\n <div className={`${baseClass}__upload`}>\n {!value && !showUrlInput && (\n <Dropzone\n className={`${baseClass}__dropzone`}\n mimeTypes={uploadConfig?.mimeTypes}\n onChange={handleFileSelection}\n onPasteUrlClick={handlePasteUrlClick}\n />\n )}\n {showUrlInput && (\n <React.Fragment>\n <div className={`${baseClass}__remote-file-wrap`}>\n {/* eslint-disable-next-line jsx-a11y/control-has-associated-label */}\n <input\n className={`${baseClass}__remote-file`}\n onChange={(e) => {\n setFileUrl(e.target.value)\n }}\n ref={urlInputRef}\n type=\"text\"\n value={fileUrl}\n />\n <div className={`${baseClass}__add-file-wrap`}>\n <button\n className={`${baseClass}__add-file`}\n onClick={handleUrlSubmit}\n type=\"button\"\n >\n {t('upload:addFile')}\n </button>\n </div>\n </div>\n <Button\n buttonStyle=\"icon-label\"\n className={`${baseClass}__remove`}\n icon=\"x\"\n iconStyle=\"with-border\"\n onClick={handleFileRemoval}\n round\n tooltip={t('general:cancel')}\n />\n </React.Fragment>\n )}\n {value && fileSrc && (\n <React.Fragment>\n <div className={`${baseClass}__thumbnail-wrap`}>\n <Thumbnail\n collectionSlug={collectionSlug}\n fileSrc={isImage(value.type) ? fileSrc : null}\n />\n </div>\n <div className={`${baseClass}__file-adjustments`}>\n {/* eslint-disable-next-line jsx-a11y/control-has-associated-label */}\n <input\n className={`${baseClass}__filename`}\n onChange={handleFileNameChange}\n type=\"text\"\n value={value.name}\n />\n <UploadActions\n customActions={customActions}\n enableAdjustments={showCrop || showFocalPoint}\n enablePreviewSizes={hasImageSizes && doc.filename && !replacingFile}\n mimeType={value.type}\n />\n </div>\n <Button\n buttonStyle=\"icon-label\"\n className={`${baseClass}__remove`}\n icon=\"x\"\n iconStyle=\"with-border\"\n onClick={handleFileRemoval}\n round\n tooltip={t('general:cancel')}\n />\n </React.Fragment>\n )}\n </div>\n )}\n {(value || doc.filename) && (\n <Drawer Header={null} slug={editDrawerSlug}>\n <EditUpload\n fileName={value?.name || doc?.filename}\n fileSrc={doc?.url || fileSrc}\n imageCacheTag={doc.updatedAt}\n initialCrop={uploadEdits?.crop ?? undefined}\n initialFocalPoint={{\n x: uploadEdits?.focalPoint?.x || doc.focalX || 50,\n y: uploadEdits?.focalPoint?.y || doc.focalY || 50,\n }}\n onSave={onEditsSave}\n showCrop={showCrop}\n showFocalPoint={showFocalPoint}\n />\n </Drawer>\n )}\n {doc && hasImageSizes && (\n <Drawer\n className={`${baseClass}__previewDrawer`}\n hoverTitle\n slug={sizePreviewSlug}\n title={t('upload:sizesFor', { label: doc?.filename })}\n >\n <PreviewSizes doc={doc} imageCacheTag={doc.updatedAt} uploadConfig={uploadConfig} />\n </Drawer>\n )}\n </div>\n )\n}\n"],"names":["useForm","useUploadEdits","isImage","reduceFieldsToValues","React","useCallback","useEffect","useRef","useState","toast","FieldError","fieldBaseClass","useField","useDocumentInfo","useTranslation","Button","Drawer","DrawerToggler","Dropzone","EditUpload","FileDetails","PreviewSizes","Thumbnail","baseClass","editDrawerSlug","sizePreviewSlug","validate","value","undefined","UploadActions","customActions","enableAdjustments","enablePreviewSizes","mimeType","t","fileTypeIsAdjustable","length","div","className","Fragment","slug","map","CustomAction","i","Upload","props","collectionSlug","initialState","onChange","uploadConfig","replacingFile","setReplacingFile","fileSrc","setFileSrc","setModified","resetUploadEdits","updateUploadEdits","uploadEdits","doc","setDoc","docPermissions","errorMessage","setValue","showError","path","showUrlInput","setShowUrlInput","fileUrl","setFileUrl","cursorPositionRef","urlInputRef","handleFileChange","newFile","File","fileReader","FileReader","onload","e","imgSrc","target","result","readAsDataURL","handleFileNameChange","updatedFileName","cursorPosition","selectionStart","current","fileValue","type","inputElement","document","querySelector","setSelectionRange","handleFileSelection","files","fileToUpload","handleFileRemoval","onEditsSave","args","handlePasteUrlClick","prev","handleUrlSubmit","response","fetch","data","blob","fileName","split","pop","file","error","message","focus","canRemoveUpload","update","permission","delete","hasImageSizes","imageSizes","hasResizeOptions","Boolean","resizeOptions","focalPointEnabled","focalPoint","crop","showCrop","showFocalPoint","filter","join","filename","customUploadActions","handleRemove","imageCacheTag","updatedAt","mimeTypes","onPasteUrlClick","input","ref","button","onClick","buttonStyle","icon","iconStyle","round","tooltip","name","Header","url","initialCrop","initialFocalPoint","x","focalX","y","focalY","onSave","hoverTitle","title","label"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { isReactServerComponentOrFunction, serverProps } from 'payload/shared';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
/**
|
|
5
5
|
* Creates a higher-order component (HOC) that merges predefined properties (`toMergeIntoProps`)
|
|
@@ -28,7 +28,7 @@ import React from 'react';
|
|
|
28
28
|
}
|
|
29
29
|
// A wrapper around the args.Component to inject the args.toMergeArgs as props, which are merged with the passed props
|
|
30
30
|
const MergedPropsComponent = (passedProps)=>{
|
|
31
|
-
const mergedProps =
|
|
31
|
+
const mergedProps = simpleMergeProps(passedProps, toMergeIntoProps);
|
|
32
32
|
if (sanitizeServerOnlyProps) {
|
|
33
33
|
serverProps.forEach((prop)=>{
|
|
34
34
|
delete mergedProps[prop];
|
|
@@ -40,5 +40,11 @@ import React from 'react';
|
|
|
40
40
|
};
|
|
41
41
|
return MergedPropsComponent;
|
|
42
42
|
}
|
|
43
|
+
function simpleMergeProps(props, toMerge) {
|
|
44
|
+
return {
|
|
45
|
+
...props,
|
|
46
|
+
...toMerge
|
|
47
|
+
};
|
|
48
|
+
}
|
|
43
49
|
|
|
44
50
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/elements/withMergedProps/index.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../../src/elements/withMergedProps/index.tsx"],"sourcesContent":["import { isReactServerComponentOrFunction, serverProps } from 'payload/shared'\nimport React from 'react'\n\n/**\n * Creates a higher-order component (HOC) that merges predefined properties (`toMergeIntoProps`)\n * with any properties passed to the resulting component.\n *\n * Use this when you want to pre-specify some props for a component, while also allowing users to\n * pass in their own props. The HOC ensures the passed props and predefined props are combined before\n * rendering the original component.\n *\n * @example\n * const PredefinedComponent = getMergedPropsComponent({\n * Component: OriginalComponent,\n * toMergeIntoProps: { someExtraValue: 5 }\n * });\n * // Using <PredefinedComponent customProp=\"value\" /> will result in\n * // <OriginalComponent customProp=\"value\" someExtraValue={5} />\n *\n * @returns A higher-order component with combined properties.\n *\n * @param Component - The original component to wrap.\n * @param sanitizeServerOnlyProps - If true, server-only props will be removed from the merged props. @default true if the component is not a server component, false otherwise.\n * @param toMergeIntoProps - The properties to merge into the passed props.\n */\nexport function withMergedProps<ToMergeIntoProps, CompleteReturnProps>({\n Component,\n sanitizeServerOnlyProps,\n toMergeIntoProps,\n}: {\n Component: React.FC<CompleteReturnProps>\n sanitizeServerOnlyProps?: boolean\n toMergeIntoProps: ToMergeIntoProps\n}): React.FC<CompleteReturnProps> {\n if (sanitizeServerOnlyProps === undefined) {\n sanitizeServerOnlyProps = !isReactServerComponentOrFunction(Component)\n }\n // A wrapper around the args.Component to inject the args.toMergeArgs as props, which are merged with the passed props\n const MergedPropsComponent: React.FC<CompleteReturnProps> = (passedProps) => {\n const mergedProps = simpleMergeProps(passedProps, toMergeIntoProps) as CompleteReturnProps\n\n if (sanitizeServerOnlyProps) {\n serverProps.forEach((prop) => {\n delete mergedProps[prop]\n })\n }\n\n return <Component {...mergedProps} />\n }\n\n return MergedPropsComponent\n}\n\nfunction simpleMergeProps(props, toMerge) {\n return { ...props, ...toMerge }\n}\n"],"names":["isReactServerComponentOrFunction","serverProps","React","withMergedProps","Component","sanitizeServerOnlyProps","toMergeIntoProps","undefined","MergedPropsComponent","passedProps","mergedProps","simpleMergeProps","forEach","prop","props","toMerge"],"mappings":";AAAA,SAASA,gCAAgC,EAAEC,WAAW,QAAQ,iBAAgB;AAC9E,OAAOC,WAAW,QAAO;AAEzB;;;;;;;;;;;;;;;;;;;;;CAqBC,GACD,OAAO,SAASC,gBAAuD,EACrEC,SAAS,EACTC,uBAAuB,EACvBC,gBAAgB,EAKjB;IACC,IAAID,4BAA4BE,WAAW;QACzCF,0BAA0B,CAACL,iCAAiCI;IAC9D;IACA,sHAAsH;IACtH,MAAMI,uBAAsD,CAACC;QAC3D,MAAMC,cAAcC,iBAAiBF,aAAaH;QAElD,IAAID,yBAAyB;YAC3BJ,YAAYW,OAAO,CAAC,CAACC;gBACnB,OAAOH,WAAW,CAACG,KAAK;YAC1B;QACF;QAEA,qBAAO,KAACT;YAAW,GAAGM,WAAW;;IACnC;IAEA,OAAOF;AACT;AAEA,SAASG,iBAAiBG,KAAK,EAAEC,OAAO;IACtC,OAAO;QAAE,GAAGD,KAAK;QAAE,GAAGC,OAAO;IAAC;AAChC"}
|