@payloadcms/plugin-import-export 3.75.0 → 3.76.0-canary.0
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/components/ExportPreview/index.d.ts.map +1 -1
- package/dist/components/ExportPreview/index.js +30 -12
- package/dist/components/ExportPreview/index.js.map +1 -1
- package/dist/components/ExportPreview/index.scss +12 -0
- package/dist/components/ImportPreview/index.js +3 -15
- package/dist/components/ImportPreview/index.js.map +1 -1
- package/dist/export/createExport.d.ts +5 -0
- package/dist/export/createExport.d.ts.map +1 -1
- package/dist/export/createExport.js +36 -12
- package/dist/export/createExport.js.map +1 -1
- package/dist/export/getCreateExportCollectionTask.d.ts.map +1 -1
- package/dist/export/getCreateExportCollectionTask.js +3 -0
- package/dist/export/getCreateExportCollectionTask.js.map +1 -1
- package/dist/export/getExportCollection.d.ts.map +1 -1
- package/dist/export/getExportCollection.js +21 -1
- package/dist/export/getExportCollection.js.map +1 -1
- package/dist/export/getFields.d.ts.map +1 -1
- package/dist/export/getFields.js +7 -3
- package/dist/export/getFields.js.map +1 -1
- package/dist/export/handleDownload.d.ts.map +1 -1
- package/dist/export/handleDownload.js +18 -1
- package/dist/export/handleDownload.js.map +1 -1
- package/dist/export/handlePreview.d.ts.map +1 -1
- package/dist/export/handlePreview.js +32 -10
- package/dist/export/handlePreview.js.map +1 -1
- package/dist/exports/types.d.ts +1 -1
- package/dist/exports/types.d.ts.map +1 -1
- package/dist/exports/types.js.map +1 -1
- package/dist/import/batchProcessor.js +50 -53
- package/dist/import/batchProcessor.js.map +1 -1
- package/dist/import/createImport.d.ts +6 -1
- package/dist/import/createImport.d.ts.map +1 -1
- package/dist/import/createImport.js +5 -1
- package/dist/import/createImport.js.map +1 -1
- package/dist/import/getCreateImportCollectionTask.d.ts.map +1 -1
- package/dist/import/getCreateImportCollectionTask.js +3 -0
- package/dist/import/getCreateImportCollectionTask.js.map +1 -1
- package/dist/import/getImportCollection.d.ts.map +1 -1
- package/dist/import/getImportCollection.js +15 -0
- package/dist/import/getImportCollection.js.map +1 -1
- package/dist/import/handlePreview.d.ts.map +1 -1
- package/dist/import/handlePreview.js +11 -0
- package/dist/import/handlePreview.js.map +1 -1
- package/dist/index.d.ts +22 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -2
- package/dist/index.js.map +1 -1
- package/dist/translations/languages/ar.d.ts.map +1 -1
- package/dist/translations/languages/ar.js +3 -0
- package/dist/translations/languages/ar.js.map +1 -1
- package/dist/translations/languages/az.d.ts.map +1 -1
- package/dist/translations/languages/az.js +3 -0
- package/dist/translations/languages/az.js.map +1 -1
- package/dist/translations/languages/bg.d.ts.map +1 -1
- package/dist/translations/languages/bg.js +3 -0
- package/dist/translations/languages/bg.js.map +1 -1
- package/dist/translations/languages/bnBd.d.ts.map +1 -1
- package/dist/translations/languages/bnBd.js +22 -19
- package/dist/translations/languages/bnBd.js.map +1 -1
- package/dist/translations/languages/bnIn.d.ts.map +1 -1
- package/dist/translations/languages/bnIn.js +22 -19
- package/dist/translations/languages/bnIn.js.map +1 -1
- package/dist/translations/languages/ca.d.ts.map +1 -1
- package/dist/translations/languages/ca.js +3 -0
- package/dist/translations/languages/ca.js.map +1 -1
- package/dist/translations/languages/cs.d.ts.map +1 -1
- package/dist/translations/languages/cs.js +3 -0
- package/dist/translations/languages/cs.js.map +1 -1
- package/dist/translations/languages/da.d.ts.map +1 -1
- package/dist/translations/languages/da.js +3 -0
- package/dist/translations/languages/da.js.map +1 -1
- package/dist/translations/languages/de.d.ts.map +1 -1
- package/dist/translations/languages/de.js +3 -0
- package/dist/translations/languages/de.js.map +1 -1
- package/dist/translations/languages/en.d.ts +3 -0
- package/dist/translations/languages/en.d.ts.map +1 -1
- package/dist/translations/languages/en.js +3 -0
- package/dist/translations/languages/en.js.map +1 -1
- package/dist/translations/languages/es.d.ts.map +1 -1
- package/dist/translations/languages/es.js +3 -0
- package/dist/translations/languages/es.js.map +1 -1
- package/dist/translations/languages/et.d.ts.map +1 -1
- package/dist/translations/languages/et.js +3 -0
- package/dist/translations/languages/et.js.map +1 -1
- package/dist/translations/languages/fa.d.ts.map +1 -1
- package/dist/translations/languages/fa.js +3 -0
- package/dist/translations/languages/fa.js.map +1 -1
- package/dist/translations/languages/fr.d.ts.map +1 -1
- package/dist/translations/languages/fr.js +3 -0
- package/dist/translations/languages/fr.js.map +1 -1
- package/dist/translations/languages/he.d.ts.map +1 -1
- package/dist/translations/languages/he.js +3 -0
- package/dist/translations/languages/he.js.map +1 -1
- package/dist/translations/languages/hr.d.ts.map +1 -1
- package/dist/translations/languages/hr.js +3 -0
- package/dist/translations/languages/hr.js.map +1 -1
- package/dist/translations/languages/hu.d.ts.map +1 -1
- package/dist/translations/languages/hu.js +3 -0
- package/dist/translations/languages/hu.js.map +1 -1
- package/dist/translations/languages/hy.d.ts.map +1 -1
- package/dist/translations/languages/hy.js +3 -0
- package/dist/translations/languages/hy.js.map +1 -1
- package/dist/translations/languages/id.d.ts.map +1 -1
- package/dist/translations/languages/id.js +13 -10
- package/dist/translations/languages/id.js.map +1 -1
- package/dist/translations/languages/is.d.ts.map +1 -1
- package/dist/translations/languages/is.js +3 -0
- package/dist/translations/languages/is.js.map +1 -1
- package/dist/translations/languages/it.d.ts.map +1 -1
- package/dist/translations/languages/it.js +3 -0
- package/dist/translations/languages/it.js.map +1 -1
- package/dist/translations/languages/ja.d.ts.map +1 -1
- package/dist/translations/languages/ja.js +3 -0
- package/dist/translations/languages/ja.js.map +1 -1
- package/dist/translations/languages/ko.d.ts.map +1 -1
- package/dist/translations/languages/ko.js +3 -0
- package/dist/translations/languages/ko.js.map +1 -1
- package/dist/translations/languages/lt.d.ts.map +1 -1
- package/dist/translations/languages/lt.js +3 -0
- package/dist/translations/languages/lt.js.map +1 -1
- package/dist/translations/languages/lv.d.ts.map +1 -1
- package/dist/translations/languages/lv.js +16 -13
- package/dist/translations/languages/lv.js.map +1 -1
- package/dist/translations/languages/my.d.ts.map +1 -1
- package/dist/translations/languages/my.js +3 -0
- package/dist/translations/languages/my.js.map +1 -1
- package/dist/translations/languages/nb.d.ts.map +1 -1
- package/dist/translations/languages/nb.js +3 -0
- package/dist/translations/languages/nb.js.map +1 -1
- package/dist/translations/languages/nl.d.ts.map +1 -1
- package/dist/translations/languages/nl.js +3 -0
- package/dist/translations/languages/nl.js.map +1 -1
- package/dist/translations/languages/pl.d.ts.map +1 -1
- package/dist/translations/languages/pl.js +3 -0
- package/dist/translations/languages/pl.js.map +1 -1
- package/dist/translations/languages/pt.d.ts.map +1 -1
- package/dist/translations/languages/pt.js +3 -0
- package/dist/translations/languages/pt.js.map +1 -1
- package/dist/translations/languages/ro.d.ts.map +1 -1
- package/dist/translations/languages/ro.js +3 -0
- package/dist/translations/languages/ro.js.map +1 -1
- package/dist/translations/languages/rs.d.ts.map +1 -1
- package/dist/translations/languages/rs.js +3 -0
- package/dist/translations/languages/rs.js.map +1 -1
- package/dist/translations/languages/rsLatin.d.ts.map +1 -1
- package/dist/translations/languages/rsLatin.js +3 -0
- package/dist/translations/languages/rsLatin.js.map +1 -1
- package/dist/translations/languages/ru.d.ts.map +1 -1
- package/dist/translations/languages/ru.js +3 -0
- package/dist/translations/languages/ru.js.map +1 -1
- package/dist/translations/languages/sk.d.ts.map +1 -1
- package/dist/translations/languages/sk.js +3 -0
- package/dist/translations/languages/sk.js.map +1 -1
- package/dist/translations/languages/sl.d.ts.map +1 -1
- package/dist/translations/languages/sl.js +3 -0
- package/dist/translations/languages/sl.js.map +1 -1
- package/dist/translations/languages/sv.d.ts.map +1 -1
- package/dist/translations/languages/sv.js +3 -0
- package/dist/translations/languages/sv.js.map +1 -1
- package/dist/translations/languages/ta.d.ts.map +1 -1
- package/dist/translations/languages/ta.js +3 -0
- package/dist/translations/languages/ta.js.map +1 -1
- package/dist/translations/languages/th.d.ts.map +1 -1
- package/dist/translations/languages/th.js +3 -0
- package/dist/translations/languages/th.js.map +1 -1
- package/dist/translations/languages/tr.d.ts.map +1 -1
- package/dist/translations/languages/tr.js +3 -0
- package/dist/translations/languages/tr.js.map +1 -1
- package/dist/translations/languages/uk.d.ts.map +1 -1
- package/dist/translations/languages/uk.js +3 -0
- package/dist/translations/languages/uk.js.map +1 -1
- package/dist/translations/languages/vi.d.ts.map +1 -1
- package/dist/translations/languages/vi.js +3 -0
- package/dist/translations/languages/vi.js.map +1 -1
- package/dist/translations/languages/zh.d.ts.map +1 -1
- package/dist/translations/languages/zh.js +3 -0
- package/dist/translations/languages/zh.js.map +1 -1
- package/dist/translations/languages/zhTw.d.ts.map +1 -1
- package/dist/translations/languages/zhTw.js +3 -0
- package/dist/translations/languages/zhTw.js.map +1 -1
- package/dist/types.d.ts +44 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/buildDisabledFieldRegex.d.ts +11 -2
- package/dist/utilities/buildDisabledFieldRegex.d.ts.map +1 -1
- package/dist/utilities/buildDisabledFieldRegex.js +33 -7
- package/dist/utilities/buildDisabledFieldRegex.js.map +1 -1
- package/dist/utilities/buildDisabledFieldRegex.spec.js +64 -0
- package/dist/utilities/buildDisabledFieldRegex.spec.js.map +1 -0
- package/dist/utilities/collectTimezoneCompanionFields.d.ts +24 -0
- package/dist/utilities/collectTimezoneCompanionFields.d.ts.map +1 -0
- package/dist/utilities/collectTimezoneCompanionFields.js +89 -0
- package/dist/utilities/collectTimezoneCompanionFields.js.map +1 -0
- package/dist/utilities/collectTimezoneCompanionFields.spec.js +319 -0
- package/dist/utilities/collectTimezoneCompanionFields.spec.js.map +1 -0
- package/dist/utilities/fieldToRegex.d.ts +14 -0
- package/dist/utilities/fieldToRegex.d.ts.map +1 -0
- package/dist/utilities/fieldToRegex.js +34 -0
- package/dist/utilities/fieldToRegex.js.map +1 -0
- package/dist/utilities/fieldToRegex.spec.js +151 -0
- package/dist/utilities/fieldToRegex.spec.js.map +1 -0
- package/dist/utilities/flattenObject.d.ts +7 -1
- package/dist/utilities/flattenObject.d.ts.map +1 -1
- package/dist/utilities/flattenObject.js +30 -18
- package/dist/utilities/flattenObject.js.map +1 -1
- package/dist/utilities/getExportFieldFunctions.d.ts.map +1 -1
- package/dist/utilities/getExportFieldFunctions.js +7 -0
- package/dist/utilities/getExportFieldFunctions.js.map +1 -1
- package/dist/utilities/getImportFieldFunctions.d.ts.map +1 -1
- package/dist/utilities/getImportFieldFunctions.js +2 -16
- package/dist/utilities/getImportFieldFunctions.js.map +1 -1
- package/dist/utilities/getPluginCollections.d.ts +1 -0
- package/dist/utilities/getPluginCollections.d.ts.map +1 -1
- package/dist/utilities/getPluginCollections.js +43 -10
- package/dist/utilities/getPluginCollections.js.map +1 -1
- package/dist/utilities/getSchemaColumns.d.ts +8 -2
- package/dist/utilities/getSchemaColumns.d.ts.map +1 -1
- package/dist/utilities/getSchemaColumns.js +61 -27
- package/dist/utilities/getSchemaColumns.js.map +1 -1
- package/dist/utilities/parseCSV.d.ts.map +1 -1
- package/dist/utilities/parseCSV.js +4 -10
- package/dist/utilities/parseCSV.js.map +1 -1
- package/dist/utilities/resolveLimit.d.ts +15 -0
- package/dist/utilities/resolveLimit.d.ts.map +1 -0
- package/dist/utilities/resolveLimit.js +21 -0
- package/dist/utilities/resolveLimit.js.map +1 -0
- package/dist/utilities/unflattenObject.d.ts +13 -0
- package/dist/utilities/unflattenObject.d.ts.map +1 -1
- package/dist/utilities/unflattenObject.js +64 -65
- package/dist/utilities/unflattenObject.js.map +1 -1
- package/package.json +8 -8
- package/dist/utilities/getvalueAtPath.d.ts +0 -15
- package/dist/utilities/getvalueAtPath.d.ts.map +0 -1
- package/dist/utilities/getvalueAtPath.js +0 -49
- package/dist/utilities/getvalueAtPath.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ExportPreview/index.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAqD,MAAM,OAAO,CAAA;AASzE,OAAO,cAAc,CAAA;AAKrB,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ExportPreview/index.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAqD,MAAM,OAAO,CAAA;AASzE,OAAO,cAAc,CAAA;AAKrB,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAkRjC,CAAA"}
|
|
@@ -25,6 +25,7 @@ export const ExportPreview = ()=>{
|
|
|
25
25
|
});
|
|
26
26
|
const [dataToRender, setDataToRender] = useState([]);
|
|
27
27
|
const [exportTotalDocs, setExportTotalDocs] = useState(0);
|
|
28
|
+
const [maxLimit, setMaxLimit] = useState(undefined);
|
|
28
29
|
const [columns, setColumns] = useState([]);
|
|
29
30
|
const { i18n, t } = useTranslation();
|
|
30
31
|
// Preview pagination state (separate from export config)
|
|
@@ -98,7 +99,7 @@ export const ExportPreview = ()=>{
|
|
|
98
99
|
if (!res.ok) {
|
|
99
100
|
return;
|
|
100
101
|
}
|
|
101
|
-
const { columns: serverColumns, docs, exportTotalDocs: serverExportTotalDocs, hasNextPage, hasPrevPage, limit: responseLimit, page: responsePage, totalPages } = await res.json();
|
|
102
|
+
const { columns: serverColumns, docs, exportTotalDocs: serverExportTotalDocs, hasNextPage, hasPrevPage, limit: responseLimit, maxLimit: serverMaxLimit, page: responsePage, totalPages } = await res.json();
|
|
102
103
|
// For CSV: use server-provided columns (from getSchemaColumns) for consistent ordering
|
|
103
104
|
// For JSON: derive keys from docs
|
|
104
105
|
const allKeys = Array.from(new Set(docs.flatMap((doc)=>Object.keys(doc))));
|
|
@@ -128,6 +129,7 @@ export const ExportPreview = ()=>{
|
|
|
128
129
|
})
|
|
129
130
|
}));
|
|
130
131
|
setExportTotalDocs(serverExportTotalDocs);
|
|
132
|
+
setMaxLimit(serverMaxLimit);
|
|
131
133
|
setPaginationData({
|
|
132
134
|
hasNextPage,
|
|
133
135
|
hasPrevPage,
|
|
@@ -183,17 +185,33 @@ export const ExportPreview = ()=>{
|
|
|
183
185
|
t: t
|
|
184
186
|
})
|
|
185
187
|
}),
|
|
186
|
-
exportTotalDocs > 0 && !isPending && /*#__PURE__*/
|
|
187
|
-
className: `${baseClass}__export-
|
|
188
|
-
children:
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
188
|
+
exportTotalDocs > 0 && !isPending && /*#__PURE__*/ _jsxs("div", {
|
|
189
|
+
className: `${baseClass}__export-info`,
|
|
190
|
+
children: [
|
|
191
|
+
/*#__PURE__*/ _jsx("span", {
|
|
192
|
+
className: `${baseClass}__export-count`,
|
|
193
|
+
children: /*#__PURE__*/ _jsx(Translation, {
|
|
194
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
195
|
+
// @ts-expect-error
|
|
196
|
+
i18nKey: "plugin-import-export:documentsToExport",
|
|
197
|
+
t: t,
|
|
198
|
+
variables: {
|
|
199
|
+
count: exportTotalDocs
|
|
200
|
+
}
|
|
201
|
+
})
|
|
202
|
+
}),
|
|
203
|
+
typeof maxLimit === 'number' && maxLimit > 0 && typeof limit === 'number' && limit > maxLimit && /*#__PURE__*/ _jsx("span", {
|
|
204
|
+
className: `${baseClass}__limit-capped`,
|
|
205
|
+
children: /*#__PURE__*/ _jsx(Translation, {
|
|
206
|
+
// @ts-expect-error - plugin translations not typed
|
|
207
|
+
i18nKey: "plugin-import-export:limitCapped",
|
|
208
|
+
t: t,
|
|
209
|
+
variables: {
|
|
210
|
+
limit: maxLimit
|
|
211
|
+
}
|
|
212
|
+
})
|
|
213
|
+
})
|
|
214
|
+
]
|
|
197
215
|
})
|
|
198
216
|
]
|
|
199
217
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ExportPreview/index.tsx"],"sourcesContent":["'use client'\nimport type { Column } from '@payloadcms/ui'\nimport type { ClientField, PaginatedDocs, Where } from 'payload'\n\nimport { getTranslation } from '@payloadcms/translations'\nimport {\n CodeEditorLazy,\n Pagination,\n PerPage,\n Table,\n Translation,\n useConfig,\n useDebouncedEffect,\n useDocumentInfo,\n useFormFields,\n useTranslation,\n} from '@payloadcms/ui'\nimport React, { useEffect, useRef, useState, useTransition } from 'react'\n\nimport type {\n PluginImportExportTranslationKeys,\n PluginImportExportTranslations,\n} from '../../translations/index.js'\nimport type { ExportPreviewResponse } from '../../types.js'\n\nimport { DEFAULT_PREVIEW_LIMIT, PREVIEW_LIMIT_OPTIONS } from '../../constants.js'\nimport './index.scss'\nimport { useImportExport } from '../ImportExportProvider/index.js'\n\nconst baseClass = 'export-preview'\n\nexport const ExportPreview: React.FC = () => {\n const [isPending, startTransition] = useTransition()\n const { collection } = useImportExport()\n const {\n config,\n config: { routes },\n } = useConfig()\n const { collectionSlug } = useDocumentInfo()\n const { draft, fields, format, limit, locale, sort, where } = useFormFields(([fields]) => {\n return {\n draft: fields['drafts']?.value,\n fields: fields['fields']?.value,\n format: fields['format']?.value,\n limit: fields['limit']?.value as number,\n locale: fields['locale']?.value as string,\n sort: fields['sort']?.value as string,\n where: fields['where']?.value as Where,\n }\n })\n const [dataToRender, setDataToRender] = useState<any[]>([])\n const [exportTotalDocs, setExportTotalDocs] = useState<number>(0)\n const [columns, setColumns] = useState<Column[]>([])\n const { i18n, t } = useTranslation<\n PluginImportExportTranslations,\n PluginImportExportTranslationKeys\n >()\n\n // Preview pagination state (separate from export config)\n const [previewPage, setPreviewPage] = useState(1)\n const [previewLimit, setPreviewLimit] = useState(DEFAULT_PREVIEW_LIMIT)\n const [paginationData, setPaginationData] = useState<null | Pick<\n PaginatedDocs,\n 'hasNextPage' | 'hasPrevPage' | 'limit' | 'nextPage' | 'page' | 'prevPage' | 'totalPages'\n >>(null)\n\n // Track previous export config to reset preview page when it changes\n const prevExportConfigRef = useRef({ draft, fields, format, limit, locale, sort, where })\n\n // Reset preview page when export config changes\n useEffect(() => {\n const prevConfig = prevExportConfigRef.current\n const configChanged =\n prevConfig.draft !== draft ||\n prevConfig.limit !== limit ||\n prevConfig.locale !== locale ||\n prevConfig.sort !== sort ||\n JSON.stringify(prevConfig.fields) !== JSON.stringify(fields) ||\n JSON.stringify(prevConfig.where) !== JSON.stringify(where)\n\n if (configChanged) {\n setPreviewPage(1)\n prevExportConfigRef.current = { draft, fields, format, limit, locale, sort, where }\n }\n }, [draft, fields, format, limit, locale, sort, where])\n\n const targetCollectionSlug = typeof collection === 'string' && collection\n\n const isCSV = format === 'csv'\n\n useDebouncedEffect(\n () => {\n if (!collectionSlug || !targetCollectionSlug) {\n return\n }\n\n const abortController = new AbortController()\n\n const fetchData = async () => {\n try {\n const res = await fetch(`${routes.api}/${collectionSlug}/export-preview`, {\n body: JSON.stringify({\n collectionSlug: targetCollectionSlug,\n draft,\n fields,\n format,\n limit,\n locale,\n previewLimit,\n previewPage,\n sort,\n where,\n }),\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n method: 'POST',\n signal: abortController.signal,\n })\n\n if (!res.ok) {\n return\n }\n\n const {\n columns: serverColumns,\n docs,\n exportTotalDocs: serverExportTotalDocs,\n hasNextPage,\n hasPrevPage,\n limit: responseLimit,\n page: responsePage,\n totalPages,\n }: ExportPreviewResponse = await res.json()\n\n // For CSV: use server-provided columns (from getSchemaColumns) for consistent ordering\n // For JSON: derive keys from docs\n const allKeys = Array.from(new Set(docs.flatMap((doc) => Object.keys(doc))))\n\n // Use server columns if available (CSV format), otherwise fall back to data-derived keys\n const fieldKeys = serverColumns && serverColumns.length > 0 ? serverColumns : allKeys\n\n // Build columns based on field keys\n const newColumns: Column[] = fieldKeys.map((key) => ({\n accessor: key,\n active: true,\n field: { name: key } as ClientField,\n Heading: getTranslation(key, i18n),\n renderedCells: docs.map((doc: Record<string, unknown>) => {\n const val = doc[key]\n\n if (val === undefined || val === null) {\n return null\n }\n\n // Avoid ESLint warning by type-checking before calling String()\n if (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean') {\n return String(val)\n }\n\n if (Array.isArray(val)) {\n return val.map(String).join(', ')\n }\n\n return JSON.stringify(val)\n }),\n }))\n\n setExportTotalDocs(serverExportTotalDocs)\n setPaginationData({\n hasNextPage,\n hasPrevPage,\n limit: responseLimit,\n nextPage: responsePage + 1,\n page: responsePage,\n prevPage: responsePage - 1,\n totalPages,\n })\n setColumns(newColumns)\n setDataToRender(docs)\n } catch (error) {\n console.error('Error fetching preview data:', error)\n }\n }\n\n startTransition(async () => await fetchData())\n\n return () => {\n if (!abortController.signal.aborted) {\n abortController.abort('Component unmounted')\n }\n }\n },\n [\n collectionSlug,\n draft,\n fields,\n format,\n i18n,\n limit,\n locale,\n previewLimit,\n previewPage,\n sort,\n where,\n routes.api,\n targetCollectionSlug,\n ],\n 500,\n )\n\n const handlePageChange = (page: number) => {\n setPreviewPage(page)\n }\n\n const handlePerPageChange = (newLimit: number) => {\n setPreviewLimit(newLimit)\n setPreviewPage(1)\n }\n\n return (\n <div className={baseClass}>\n <div className={`${baseClass}__header`}>\n <h3>\n <Translation i18nKey=\"version:preview\" t={t} />\n </h3>\n {exportTotalDocs > 0 && !isPending && (\n <span className={`${baseClass}__export-count`}>\n <Translation\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n i18nKey=\"plugin-import-export:documentsToExport\"\n t={t}\n variables={{\n count: exportTotalDocs,\n }}\n />\n </span>\n )}\n </div>\n {isPending && !dataToRender && (\n <div className={`${baseClass}__loading`}>\n <Translation i18nKey=\"general:loading\" t={t} />\n </div>\n )}\n {dataToRender &&\n (isCSV ? (\n <Table columns={columns} data={dataToRender} />\n ) : (\n <CodeEditorLazy language=\"json\" readOnly value={JSON.stringify(dataToRender, null, 2)} />\n ))}\n {paginationData && exportTotalDocs > 0 && (\n <div className={`${baseClass}__pagination`}>\n {paginationData.totalPages > 1 && (\n <Pagination\n hasNextPage={paginationData.hasNextPage}\n hasPrevPage={paginationData.hasPrevPage}\n nextPage={paginationData.nextPage ?? undefined}\n numberOfNeighbors={1}\n onChange={handlePageChange}\n page={paginationData.page}\n prevPage={paginationData.prevPage ?? undefined}\n totalPages={paginationData.totalPages}\n />\n )}\n <span className={`${baseClass}__page-info`}>\n <Translation\n // @ts-expect-error - plugin translations not typed\n i18nKey=\"plugin-import-export:previewPageInfo\"\n t={t}\n variables={{\n end: Math.min((paginationData.page ?? 1) * previewLimit, exportTotalDocs),\n start: ((paginationData.page ?? 1) - 1) * previewLimit + 1,\n total: exportTotalDocs,\n }}\n />\n </span>\n <PerPage\n handleChange={handlePerPageChange}\n limit={previewLimit}\n limits={PREVIEW_LIMIT_OPTIONS}\n />\n </div>\n )}\n </div>\n )\n}\n"],"names":["getTranslation","CodeEditorLazy","Pagination","PerPage","Table","Translation","useConfig","useDebouncedEffect","useDocumentInfo","useFormFields","useTranslation","React","useEffect","useRef","useState","useTransition","DEFAULT_PREVIEW_LIMIT","PREVIEW_LIMIT_OPTIONS","useImportExport","baseClass","ExportPreview","isPending","startTransition","collection","config","routes","collectionSlug","draft","fields","format","limit","locale","sort","where","value","dataToRender","setDataToRender","exportTotalDocs","setExportTotalDocs","columns","setColumns","i18n","t","previewPage","setPreviewPage","previewLimit","setPreviewLimit","paginationData","setPaginationData","prevExportConfigRef","prevConfig","current","configChanged","JSON","stringify","targetCollectionSlug","isCSV","abortController","AbortController","fetchData","res","fetch","api","body","credentials","headers","method","signal","ok","serverColumns","docs","serverExportTotalDocs","hasNextPage","hasPrevPage","responseLimit","page","responsePage","totalPages","json","allKeys","Array","from","Set","flatMap","doc","Object","keys","fieldKeys","length","newColumns","map","key","accessor","active","field","name","Heading","renderedCells","val","undefined","String","isArray","join","nextPage","prevPage","error","console","aborted","abort","handlePageChange","handlePerPageChange","newLimit","div","className","h3","i18nKey","span","variables","count","data","language","readOnly","numberOfNeighbors","onChange","end","Math","min","start","total","handleChange","limits"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ExportPreview/index.tsx"],"sourcesContent":["'use client'\nimport type { Column } from '@payloadcms/ui'\nimport type { ClientField, PaginatedDocs, Where } from 'payload'\n\nimport { getTranslation } from '@payloadcms/translations'\nimport {\n CodeEditorLazy,\n Pagination,\n PerPage,\n Table,\n Translation,\n useConfig,\n useDebouncedEffect,\n useDocumentInfo,\n useFormFields,\n useTranslation,\n} from '@payloadcms/ui'\nimport React, { useEffect, useRef, useState, useTransition } from 'react'\n\nimport type {\n PluginImportExportTranslationKeys,\n PluginImportExportTranslations,\n} from '../../translations/index.js'\nimport type { ExportPreviewResponse } from '../../types.js'\n\nimport { DEFAULT_PREVIEW_LIMIT, PREVIEW_LIMIT_OPTIONS } from '../../constants.js'\nimport './index.scss'\nimport { useImportExport } from '../ImportExportProvider/index.js'\n\nconst baseClass = 'export-preview'\n\nexport const ExportPreview: React.FC = () => {\n const [isPending, startTransition] = useTransition()\n const { collection } = useImportExport()\n const {\n config,\n config: { routes },\n } = useConfig()\n const { collectionSlug } = useDocumentInfo()\n const { draft, fields, format, limit, locale, sort, where } = useFormFields(([fields]) => {\n return {\n draft: fields['drafts']?.value,\n fields: fields['fields']?.value,\n format: fields['format']?.value,\n limit: fields['limit']?.value as number,\n locale: fields['locale']?.value as string,\n sort: fields['sort']?.value as string,\n where: fields['where']?.value as Where,\n }\n })\n const [dataToRender, setDataToRender] = useState<any[]>([])\n const [exportTotalDocs, setExportTotalDocs] = useState<number>(0)\n const [maxLimit, setMaxLimit] = useState<number | undefined>(undefined)\n const [columns, setColumns] = useState<Column[]>([])\n const { i18n, t } = useTranslation<\n PluginImportExportTranslations,\n PluginImportExportTranslationKeys\n >()\n\n // Preview pagination state (separate from export config)\n const [previewPage, setPreviewPage] = useState(1)\n const [previewLimit, setPreviewLimit] = useState(DEFAULT_PREVIEW_LIMIT)\n const [paginationData, setPaginationData] = useState<null | Pick<\n PaginatedDocs,\n 'hasNextPage' | 'hasPrevPage' | 'limit' | 'nextPage' | 'page' | 'prevPage' | 'totalPages'\n >>(null)\n\n // Track previous export config to reset preview page when it changes\n const prevExportConfigRef = useRef({ draft, fields, format, limit, locale, sort, where })\n\n // Reset preview page when export config changes\n useEffect(() => {\n const prevConfig = prevExportConfigRef.current\n const configChanged =\n prevConfig.draft !== draft ||\n prevConfig.limit !== limit ||\n prevConfig.locale !== locale ||\n prevConfig.sort !== sort ||\n JSON.stringify(prevConfig.fields) !== JSON.stringify(fields) ||\n JSON.stringify(prevConfig.where) !== JSON.stringify(where)\n\n if (configChanged) {\n setPreviewPage(1)\n prevExportConfigRef.current = { draft, fields, format, limit, locale, sort, where }\n }\n }, [draft, fields, format, limit, locale, sort, where])\n\n const targetCollectionSlug = typeof collection === 'string' && collection\n\n const isCSV = format === 'csv'\n\n useDebouncedEffect(\n () => {\n if (!collectionSlug || !targetCollectionSlug) {\n return\n }\n\n const abortController = new AbortController()\n\n const fetchData = async () => {\n try {\n const res = await fetch(`${routes.api}/${collectionSlug}/export-preview`, {\n body: JSON.stringify({\n collectionSlug: targetCollectionSlug,\n draft,\n fields,\n format,\n limit,\n locale,\n previewLimit,\n previewPage,\n sort,\n where,\n }),\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n method: 'POST',\n signal: abortController.signal,\n })\n\n if (!res.ok) {\n return\n }\n\n const {\n columns: serverColumns,\n docs,\n exportTotalDocs: serverExportTotalDocs,\n hasNextPage,\n hasPrevPage,\n limit: responseLimit,\n maxLimit: serverMaxLimit,\n page: responsePage,\n totalPages,\n }: ExportPreviewResponse = await res.json()\n\n // For CSV: use server-provided columns (from getSchemaColumns) for consistent ordering\n // For JSON: derive keys from docs\n const allKeys = Array.from(new Set(docs.flatMap((doc) => Object.keys(doc))))\n\n // Use server columns if available (CSV format), otherwise fall back to data-derived keys\n const fieldKeys = serverColumns && serverColumns.length > 0 ? serverColumns : allKeys\n\n // Build columns based on field keys\n const newColumns: Column[] = fieldKeys.map((key) => ({\n accessor: key,\n active: true,\n field: { name: key } as ClientField,\n Heading: getTranslation(key, i18n),\n renderedCells: docs.map((doc: Record<string, unknown>) => {\n const val = doc[key]\n\n if (val === undefined || val === null) {\n return null\n }\n\n // Avoid ESLint warning by type-checking before calling String()\n if (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean') {\n return String(val)\n }\n\n if (Array.isArray(val)) {\n return val.map(String).join(', ')\n }\n\n return JSON.stringify(val)\n }),\n }))\n\n setExportTotalDocs(serverExportTotalDocs)\n setMaxLimit(serverMaxLimit)\n setPaginationData({\n hasNextPage,\n hasPrevPage,\n limit: responseLimit,\n nextPage: responsePage + 1,\n page: responsePage,\n prevPage: responsePage - 1,\n totalPages,\n })\n setColumns(newColumns)\n setDataToRender(docs)\n } catch (error) {\n console.error('Error fetching preview data:', error)\n }\n }\n\n startTransition(async () => await fetchData())\n\n return () => {\n if (!abortController.signal.aborted) {\n abortController.abort('Component unmounted')\n }\n }\n },\n [\n collectionSlug,\n draft,\n fields,\n format,\n i18n,\n limit,\n locale,\n previewLimit,\n previewPage,\n sort,\n where,\n routes.api,\n targetCollectionSlug,\n ],\n 500,\n )\n\n const handlePageChange = (page: number) => {\n setPreviewPage(page)\n }\n\n const handlePerPageChange = (newLimit: number) => {\n setPreviewLimit(newLimit)\n setPreviewPage(1)\n }\n\n return (\n <div className={baseClass}>\n <div className={`${baseClass}__header`}>\n <h3>\n <Translation i18nKey=\"version:preview\" t={t} />\n </h3>\n {exportTotalDocs > 0 && !isPending && (\n <div className={`${baseClass}__export-info`}>\n <span className={`${baseClass}__export-count`}>\n <Translation\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n i18nKey=\"plugin-import-export:documentsToExport\"\n t={t}\n variables={{\n count: exportTotalDocs,\n }}\n />\n </span>\n {typeof maxLimit === 'number' &&\n maxLimit > 0 &&\n typeof limit === 'number' &&\n limit > maxLimit && (\n <span className={`${baseClass}__limit-capped`}>\n <Translation\n // @ts-expect-error - plugin translations not typed\n i18nKey=\"plugin-import-export:limitCapped\"\n t={t}\n variables={{\n limit: maxLimit,\n }}\n />\n </span>\n )}\n </div>\n )}\n </div>\n {isPending && !dataToRender && (\n <div className={`${baseClass}__loading`}>\n <Translation i18nKey=\"general:loading\" t={t} />\n </div>\n )}\n {dataToRender &&\n (isCSV ? (\n <Table columns={columns} data={dataToRender} />\n ) : (\n <CodeEditorLazy language=\"json\" readOnly value={JSON.stringify(dataToRender, null, 2)} />\n ))}\n {paginationData && exportTotalDocs > 0 && (\n <div className={`${baseClass}__pagination`}>\n {paginationData.totalPages > 1 && (\n <Pagination\n hasNextPage={paginationData.hasNextPage}\n hasPrevPage={paginationData.hasPrevPage}\n nextPage={paginationData.nextPage ?? undefined}\n numberOfNeighbors={1}\n onChange={handlePageChange}\n page={paginationData.page}\n prevPage={paginationData.prevPage ?? undefined}\n totalPages={paginationData.totalPages}\n />\n )}\n <span className={`${baseClass}__page-info`}>\n <Translation\n // @ts-expect-error - plugin translations not typed\n i18nKey=\"plugin-import-export:previewPageInfo\"\n t={t}\n variables={{\n end: Math.min((paginationData.page ?? 1) * previewLimit, exportTotalDocs),\n start: ((paginationData.page ?? 1) - 1) * previewLimit + 1,\n total: exportTotalDocs,\n }}\n />\n </span>\n <PerPage\n handleChange={handlePerPageChange}\n limit={previewLimit}\n limits={PREVIEW_LIMIT_OPTIONS}\n />\n </div>\n )}\n </div>\n )\n}\n"],"names":["getTranslation","CodeEditorLazy","Pagination","PerPage","Table","Translation","useConfig","useDebouncedEffect","useDocumentInfo","useFormFields","useTranslation","React","useEffect","useRef","useState","useTransition","DEFAULT_PREVIEW_LIMIT","PREVIEW_LIMIT_OPTIONS","useImportExport","baseClass","ExportPreview","isPending","startTransition","collection","config","routes","collectionSlug","draft","fields","format","limit","locale","sort","where","value","dataToRender","setDataToRender","exportTotalDocs","setExportTotalDocs","maxLimit","setMaxLimit","undefined","columns","setColumns","i18n","t","previewPage","setPreviewPage","previewLimit","setPreviewLimit","paginationData","setPaginationData","prevExportConfigRef","prevConfig","current","configChanged","JSON","stringify","targetCollectionSlug","isCSV","abortController","AbortController","fetchData","res","fetch","api","body","credentials","headers","method","signal","ok","serverColumns","docs","serverExportTotalDocs","hasNextPage","hasPrevPage","responseLimit","serverMaxLimit","page","responsePage","totalPages","json","allKeys","Array","from","Set","flatMap","doc","Object","keys","fieldKeys","length","newColumns","map","key","accessor","active","field","name","Heading","renderedCells","val","String","isArray","join","nextPage","prevPage","error","console","aborted","abort","handlePageChange","handlePerPageChange","newLimit","div","className","h3","i18nKey","span","variables","count","data","language","readOnly","numberOfNeighbors","onChange","end","Math","min","start","total","handleChange","limits"],"mappings":"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"}
|
|
@@ -7,11 +7,23 @@
|
|
|
7
7
|
margin-bottom: 10px;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
&__export-info {
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
align-items: flex-end;
|
|
14
|
+
gap: 2px;
|
|
15
|
+
}
|
|
16
|
+
|
|
10
17
|
&__export-count {
|
|
11
18
|
font-size: var(--font-size-small);
|
|
12
19
|
color: var(--theme-elevation-500);
|
|
13
20
|
}
|
|
14
21
|
|
|
22
|
+
&__limit-capped {
|
|
23
|
+
font-size: var(--font-size-small);
|
|
24
|
+
color: var(--theme-warning-500);
|
|
25
|
+
}
|
|
26
|
+
|
|
15
27
|
&__pagination {
|
|
16
28
|
display: flex;
|
|
17
29
|
align-items: center;
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { getTranslation } from '@payloadcms/translations';
|
|
4
4
|
import { Pagination, PerPage, Table, Translation, useConfig, useDebouncedEffect, useDocumentInfo, useField, useFormFields, useTranslation } from '@payloadcms/ui';
|
|
5
5
|
import { formatDocTitle } from '@payloadcms/ui/shared';
|
|
6
|
-
import { fieldAffectsData } from 'payload/shared';
|
|
6
|
+
import { fieldAffectsData, getObjectDotNotation } from 'payload/shared';
|
|
7
7
|
import React, { useState, useTransition } from 'react';
|
|
8
8
|
import { DEFAULT_PREVIEW_LIMIT, PREVIEW_LIMIT_OPTIONS } from '../../constants.js';
|
|
9
9
|
import './index.scss';
|
|
@@ -162,7 +162,7 @@ export const ImportPreview = ()=>{
|
|
|
162
162
|
}
|
|
163
163
|
// Skip if this field doesn't exist in any document
|
|
164
164
|
const hasData = docs.some((doc)=>{
|
|
165
|
-
const value =
|
|
165
|
+
const value = getObjectDotNotation(doc, fieldPath);
|
|
166
166
|
return value !== undefined && value !== null;
|
|
167
167
|
});
|
|
168
168
|
if (!hasData && field.type !== 'relationship') {
|
|
@@ -174,7 +174,7 @@ export const ImportPreview = ()=>{
|
|
|
174
174
|
field,
|
|
175
175
|
Heading: label,
|
|
176
176
|
renderedCells: docs.map((doc)=>{
|
|
177
|
-
const value =
|
|
177
|
+
const value = getObjectDotNotation(doc, fieldPath);
|
|
178
178
|
if (value === undefined || value === null) {
|
|
179
179
|
return null;
|
|
180
180
|
}
|
|
@@ -608,17 +608,5 @@ export const ImportPreview = ()=>{
|
|
|
608
608
|
]
|
|
609
609
|
});
|
|
610
610
|
};
|
|
611
|
-
// Helper function to get nested values
|
|
612
|
-
const getValueAtPath = (obj, path)=>{
|
|
613
|
-
const segments = path.split('.');
|
|
614
|
-
let current = obj;
|
|
615
|
-
for (const segment of segments){
|
|
616
|
-
if (current === null || current === undefined) {
|
|
617
|
-
return undefined;
|
|
618
|
-
}
|
|
619
|
-
current = current[segment];
|
|
620
|
-
}
|
|
621
|
-
return current;
|
|
622
|
-
};
|
|
623
611
|
|
|
624
612
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ImportPreview/index.tsx"],"sourcesContent":["'use client'\nimport type { Column } from '@payloadcms/ui'\nimport type { ClientField, ConditionalDateProps, PaginatedDocs } from 'payload'\n\nimport { getTranslation } from '@payloadcms/translations'\nimport {\n Pagination,\n PerPage,\n Table,\n Translation,\n useConfig,\n useDebouncedEffect,\n useDocumentInfo,\n useField,\n useFormFields,\n useTranslation,\n} from '@payloadcms/ui'\nimport { formatDocTitle } from '@payloadcms/ui/shared'\nimport { fieldAffectsData } from 'payload/shared'\nimport React, { useState, useTransition } from 'react'\n\nimport type {\n PluginImportExportTranslationKeys,\n PluginImportExportTranslations,\n} from '../../translations/index.js'\nimport type { ImportPreviewResponse } from '../../types.js'\n\nimport { DEFAULT_PREVIEW_LIMIT, PREVIEW_LIMIT_OPTIONS } from '../../constants.js'\nimport './index.scss'\n\nconst baseClass = 'import-preview'\n\nexport const ImportPreview: React.FC = () => {\n const [isPending, startTransition] = useTransition()\n const {\n config,\n config: { routes },\n } = useConfig()\n const { collectionSlug } = useDocumentInfo()\n const { i18n, t } = useTranslation<\n PluginImportExportTranslations,\n PluginImportExportTranslationKeys\n >()\n\n const { value: targetCollectionSlug } = useField<string>({ path: 'collectionSlug' })\n const { value: importMode } = useField<string>({ path: 'importMode' })\n const { value: matchField } = useField<string>({ path: 'matchField' })\n const { value: filename } = useField<string>({ path: 'filename' })\n const { value: url } = useField<string>({ path: 'url' })\n const { value: mimeType } = useField<string>({ path: 'mimeType' })\n const { value: status } = useField<string>({ path: 'status' })\n const { value: summary } = useField<any>({ path: 'summary' })\n\n // Access the file field directly from form fields\n const fileField = useFormFields(([fields]) => fields?.file || null)\n\n const [dataToRender, setDataToRender] = useState<Record<string, unknown>[]>([])\n const [columns, setColumns] = useState<Column[]>([])\n const [totalDocs, setTotalDocs] = useState<number>(0)\n const [error, setError] = useState<null | string>(null)\n\n // Preview pagination state\n const [previewPage, setPreviewPage] = useState(1)\n const [previewLimit, setPreviewLimit] = useState(DEFAULT_PREVIEW_LIMIT)\n const [paginationData, setPaginationData] = useState<null | Pick<\n PaginatedDocs,\n 'hasNextPage' | 'hasPrevPage' | 'limit' | 'nextPage' | 'page' | 'prevPage' | 'totalPages'\n >>(null)\n\n const collectionConfig = React.useMemo(\n () => config.collections.find((c) => c.slug === targetCollectionSlug),\n [targetCollectionSlug, config.collections],\n )\n\n useDebouncedEffect(\n () => {\n if (!collectionSlug || !targetCollectionSlug) {\n return\n }\n\n if (!targetCollectionSlug || (!url && !fileField?.value)) {\n setDataToRender([])\n setColumns([])\n setTotalDocs(0)\n setPaginationData(null)\n return\n }\n\n if (!collectionConfig) {\n setDataToRender([])\n setColumns([])\n setTotalDocs(0)\n setPaginationData(null)\n return\n }\n\n const abortController = new AbortController()\n\n const processFileData = async () => {\n setError(null)\n\n try {\n // Determine format from file\n let format: 'csv' | 'json' = 'json'\n if (fileField?.value && fileField.value instanceof File) {\n const file = fileField.value\n format = file.type === 'text/csv' || file.name?.endsWith('.csv') ? 'csv' : 'json'\n } else if (mimeType === 'text/csv' || filename?.endsWith('.csv')) {\n format = 'csv'\n }\n\n // Get file data as base64\n let fileData: string | undefined\n\n if (fileField?.value && fileField.value instanceof File) {\n // File is being uploaded, read its contents\n const arrayBuffer = await fileField.value.arrayBuffer()\n const base64 = Buffer.from(arrayBuffer).toString('base64')\n fileData = base64\n } else if (url) {\n // File has been saved, fetch from URL\n const response = await fetch(url, { signal: abortController.signal })\n if (!response.ok) {\n throw new Error('Failed to fetch file')\n }\n const arrayBuffer = await response.arrayBuffer()\n const base64 = Buffer.from(arrayBuffer).toString('base64')\n fileData = base64\n }\n\n if (!fileData) {\n setDataToRender([])\n setColumns([])\n setTotalDocs(0)\n setPaginationData(null)\n return\n }\n\n // Fetch transformed data from the server\n const res = await fetch(`${routes.api}/${collectionSlug}/preview-data`, {\n body: JSON.stringify({\n collectionSlug: targetCollectionSlug,\n fileData,\n format,\n previewLimit,\n previewPage,\n }),\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n method: 'POST',\n signal: abortController.signal,\n })\n\n if (!res.ok) {\n throw new Error('Failed to process file')\n }\n\n const {\n docs,\n hasNextPage,\n hasPrevPage,\n limit: responseLimit,\n page: responsePage,\n totalDocs: serverTotalDocs,\n totalPages,\n }: ImportPreviewResponse = await res.json()\n\n setTotalDocs(serverTotalDocs)\n setPaginationData({\n hasNextPage,\n hasPrevPage,\n limit: responseLimit,\n nextPage: responsePage + 1,\n page: responsePage,\n prevPage: responsePage - 1,\n totalPages,\n })\n\n if (!Array.isArray(docs) || docs.length === 0) {\n setDataToRender([])\n setColumns([])\n return\n }\n\n // Build columns from collection fields without traverseFields\n const buildColumnsFromFields = (\n fields: ClientField[],\n parentPath = '',\n parentLabel = '',\n ): Column[] => {\n const cols: Column[] = []\n\n fields.forEach((field) => {\n if (!fieldAffectsData(field) || field.admin?.disabled) {\n return\n }\n\n // Build the field path\n const fieldPath = parentPath ? `${parentPath}.${field.name}` : field.name\n\n // Get the field label\n let label = field.name\n if ('label' in field && field.label) {\n label = getTranslation(field.label, i18n)\n }\n\n // Add parent label prefix if in a group\n if (parentLabel) {\n label = `${parentLabel} > ${label}`\n }\n\n // Skip if this field doesn't exist in any document\n const hasData = docs.some((doc) => {\n const value = getValueAtPath(doc, fieldPath)\n return value !== undefined && value !== null\n })\n\n if (!hasData && field.type !== 'relationship') {\n return\n }\n\n cols.push({\n accessor: fieldPath,\n active: true,\n field,\n Heading: label,\n renderedCells: docs.map((doc) => {\n const value = getValueAtPath(doc, fieldPath)\n\n if (value === undefined || value === null) {\n return null\n }\n\n // Format based on field type\n if (field.type === 'relationship' || field.type === 'upload') {\n // Handle relationships\n if (typeof value === 'object' && !Array.isArray(value)) {\n // Single relationship\n const relationTo = Array.isArray(field.relationTo)\n ? (value as any).relationTo\n : field.relationTo\n\n const relatedConfig = config.collections.find((c) => c.slug === relationTo)\n if (relatedConfig && relatedConfig.admin?.useAsTitle) {\n const titleValue = (value as any)[relatedConfig.admin.useAsTitle]\n if (titleValue) {\n return formatDocTitle({\n collectionConfig: relatedConfig,\n data: value as any,\n dateFormat: config.admin.dateFormat,\n i18n,\n })\n }\n }\n\n // Fallback to ID\n const id = (value as any).id || value\n return `${getTranslation(relatedConfig?.labels?.singular || relationTo, i18n)}: ${id}`\n } else if (Array.isArray(value)) {\n // Multiple relationships\n return value\n .map((item) => {\n if (typeof item === 'object') {\n const relationTo = Array.isArray(field.relationTo)\n ? item.relationTo\n : field.relationTo\n const relatedConfig = config.collections.find(\n (c) => c.slug === relationTo,\n )\n\n if (relatedConfig && relatedConfig.admin?.useAsTitle) {\n const titleValue = item[relatedConfig.admin.useAsTitle]\n if (titleValue) {\n return formatDocTitle({\n collectionConfig: relatedConfig,\n data: item,\n dateFormat: config.admin.dateFormat,\n i18n,\n })\n }\n }\n\n return item.id || item\n }\n return item\n })\n .join(', ')\n }\n\n // Just an ID\n return String(value)\n } else if (field.type === 'date') {\n // Format dates\n const dateFormat =\n (field.admin &&\n 'date' in field.admin &&\n (field.admin.date as ConditionalDateProps)?.displayFormat) ||\n config.admin.dateFormat\n\n return new Date(value as string).toLocaleString(i18n.language, {\n dateStyle: 'medium',\n timeStyle: 'short',\n })\n } else if (field.type === 'checkbox') {\n return value ? '✓' : '✗'\n } else if (field.type === 'select' || field.type === 'radio') {\n // Show the label for select/radio options\n const option = field.options?.find((opt) => {\n if (typeof opt === 'string') {\n return opt === value\n }\n return opt.value === value\n })\n\n if (option && typeof option === 'object') {\n return getTranslation(option.label, i18n)\n }\n return String(value)\n } else if (field.type === 'number') {\n return String(value)\n } else if (Array.isArray(value)) {\n // Handle arrays\n if (field.type === 'blocks') {\n return value.map((block: any) => `${block.blockType || 'Block'}`).join(', ')\n }\n return `[${value.length} items]`\n } else if (typeof value === 'object') {\n // Handle objects\n if (field.type === 'group') {\n return '{...}'\n }\n return JSON.stringify(value)\n }\n\n return String(value)\n }),\n })\n\n // For groups, add nested fields with parent label\n if (field.type === 'group' && 'fields' in field) {\n const groupLabel =\n 'label' in field && field.label ? getTranslation(field.label, i18n) : field.name\n\n const nestedCols = buildColumnsFromFields(\n field.fields,\n fieldPath,\n parentLabel ? `${parentLabel} > ${groupLabel}` : groupLabel,\n )\n cols.push(...nestedCols)\n }\n\n // For tabs, process the fields within\n if ('tabs' in field && Array.isArray(field.tabs)) {\n field.tabs.forEach((tab) => {\n if ('name' in tab && tab.name) {\n // Named tab\n const tabPath = parentPath ? `${parentPath}.${tab.name}` : tab.name\n const tabLabel =\n 'label' in tab && tab.label ? getTranslation(tab.label, i18n) : tab.name\n\n const tabCols = buildColumnsFromFields(\n tab.fields,\n tabPath,\n parentLabel ? `${parentLabel} > ${tabLabel}` : tabLabel,\n )\n cols.push(...tabCols)\n } else {\n // Unnamed tab - fields go directly under parent\n const tabLabel =\n 'label' in tab && tab.label ? getTranslation(tab.label, i18n) : ''\n\n const tabCols = buildColumnsFromFields(\n tab.fields,\n parentPath,\n tabLabel && typeof tabLabel === 'string' && parentLabel\n ? `${parentLabel} > ${tabLabel}`\n : typeof tabLabel === 'string'\n ? tabLabel\n : parentLabel,\n )\n cols.push(...tabCols)\n }\n })\n }\n })\n\n return cols\n }\n\n // Add default meta fields at the end\n const fieldColumns = buildColumnsFromFields(collectionConfig.fields)\n const metaFields = ['id', 'createdAt', 'updatedAt', '_status']\n\n metaFields.forEach((metaField) => {\n const hasData = docs.some((doc) => doc[metaField] !== undefined)\n if (!hasData) {\n return\n }\n\n fieldColumns.push({\n accessor: metaField,\n active: true,\n field: { name: metaField } as ClientField,\n Heading: getTranslation(metaField, i18n),\n renderedCells: docs.map((doc) => {\n const value = doc[metaField]\n if (value === undefined || value === null) {\n return null\n }\n\n if (metaField === 'createdAt' || metaField === 'updatedAt') {\n return new Date(value as string).toLocaleString(i18n.language, {\n dateStyle: 'medium',\n timeStyle: 'short',\n })\n }\n\n return String(value)\n }),\n })\n })\n\n setColumns(fieldColumns)\n setDataToRender(docs)\n } catch (err) {\n console.error('Error processing file data:', err)\n setError(err instanceof Error ? err.message : 'Failed to load preview')\n setDataToRender([])\n setColumns([])\n setTotalDocs(0)\n setPaginationData(null)\n }\n }\n\n startTransition(async () => await processFileData())\n\n return () => {\n if (!abortController.signal.aborted) {\n abortController.abort('Component unmounted')\n }\n }\n },\n [\n collectionSlug,\n targetCollectionSlug,\n url,\n filename,\n mimeType,\n fileField?.value,\n collectionConfig,\n config,\n i18n,\n previewLimit,\n previewPage,\n routes.api,\n ],\n 500,\n )\n\n // If import has been processed, show results instead of preview\n if (status !== 'pending' && summary) {\n return (\n <div className={baseClass}>\n <div className={`${baseClass}__header`}>\n <h3>\n {/* @ts-expect-error - translations are not typed in plugins */}\n <Translation i18nKey=\"plugin-import-export:importResults\" t={t} />\n </h3>\n </div>\n <div className={`${baseClass}__results`}>\n <p>\n <strong>Status:</strong> {status}\n </p>\n <p>\n <strong>Imported:</strong> {summary.imported || 0}\n </p>\n <p>\n <strong>Updated:</strong> {summary.updated || 0}\n </p>\n <p>\n <strong>Total:</strong> {summary.total || 0}\n </p>\n {summary.issues > 0 && (\n <p>\n <strong>Issues:</strong> {summary.issues}\n </p>\n )}\n {summary.issueDetails && summary.issueDetails.length > 0 && (\n <div style={{ marginTop: '1rem' }}>\n <strong>Issue Details:</strong>\n <ul style={{ marginTop: '0.5rem' }}>\n {summary.issueDetails.slice(0, 10).map((issue: any, index: number) => (\n <li key={index}>\n Row {issue.row}: {issue.error}\n </li>\n ))}\n {summary.issueDetails.length > 10 && (\n <li>... and {summary.issueDetails.length - 10} more issues</li>\n )}\n </ul>\n </div>\n )}\n </div>\n </div>\n )\n }\n\n if (!targetCollectionSlug) {\n return (\n <div className={baseClass}>\n <p style={{ opacity: 0.6 }}>\n {/* @ts-expect-error - translations are not typed in plugins */}\n <Translation i18nKey=\"plugin-import-export:collectionRequired\" t={t} />\n </p>\n </div>\n )\n }\n\n if (error) {\n return (\n <div className={baseClass}>\n <p style={{ color: 'red' }}>\n <Translation i18nKey=\"general:error\" t={t} />: {error}\n </p>\n </div>\n )\n }\n\n if (!url && !fileField?.value) {\n return (\n <div className={baseClass}>\n <p style={{ opacity: 0.6 }}>\n {/* @ts-expect-error - translations are not typed in plugins */}\n <Translation i18nKey=\"plugin-import-export:uploadFileToSeePreview\" t={t} />\n </p>\n </div>\n )\n }\n\n const handlePageChange = (page: number) => {\n setPreviewPage(page)\n }\n\n const handlePerPageChange = (newLimit: number) => {\n setPreviewLimit(newLimit)\n setPreviewPage(1)\n }\n\n return (\n <div className={baseClass}>\n <div className={`${baseClass}__header`}>\n <h3>\n <Translation i18nKey=\"version:preview\" t={t} />\n </h3>\n {totalDocs > 0 && !isPending && (\n <div className={`${baseClass}__info`}>\n <span className={`${baseClass}__import-count`}>\n <Translation\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n i18nKey=\"plugin-import-export:documentsToImport\"\n t={t}\n variables={{\n count: totalDocs,\n }}\n />\n </span>\n {' | '}\n {/* @ts-expect-error - translations are not typed in plugins */}\n <Translation i18nKey=\"plugin-import-export:mode\" t={t} />: {importMode || 'create'}\n {importMode !== 'create' && (\n <>\n {' | '}\n {/* @ts-expect-error - translations are not typed in plugins */}\n <Translation i18nKey=\"plugin-import-export:matchBy\" t={t} />: {matchField || 'id'}\n </>\n )}\n </div>\n )}\n </div>\n {isPending && !dataToRender.length && (\n <div className={`${baseClass}__loading`}>\n <Translation i18nKey=\"general:loading\" t={t} />\n </div>\n )}\n {dataToRender.length > 0 && <Table columns={columns} data={dataToRender} />}\n {!isPending && dataToRender.length === 0 && targetCollectionSlug && (\n <p>\n {/* @ts-expect-error - translations are not typed in plugins */}\n <Translation i18nKey=\"plugin-import-export:noDataToPreview\" t={t} />\n </p>\n )}\n {paginationData && totalDocs > 0 && (\n <div className={`${baseClass}__pagination`}>\n {paginationData.totalPages > 1 && (\n <Pagination\n hasNextPage={paginationData.hasNextPage}\n hasPrevPage={paginationData.hasPrevPage}\n nextPage={paginationData.nextPage ?? undefined}\n numberOfNeighbors={1}\n onChange={handlePageChange}\n page={paginationData.page}\n prevPage={paginationData.prevPage ?? undefined}\n totalPages={paginationData.totalPages}\n />\n )}\n <span className={`${baseClass}__page-info`}>\n <Translation\n // @ts-expect-error - plugin translations not typed\n i18nKey=\"plugin-import-export:previewPageInfo\"\n t={t}\n variables={{\n end: Math.min((paginationData.page ?? 1) * previewLimit, totalDocs),\n start: ((paginationData.page ?? 1) - 1) * previewLimit + 1,\n total: totalDocs,\n }}\n />\n </span>\n <PerPage\n handleChange={handlePerPageChange}\n limit={previewLimit}\n limits={PREVIEW_LIMIT_OPTIONS}\n />\n </div>\n )}\n </div>\n )\n}\n\n// Helper function to get nested values\nconst getValueAtPath = (obj: Record<string, unknown>, path: string): unknown => {\n const segments = path.split('.')\n let current: any = obj\n\n for (const segment of segments) {\n if (current === null || current === undefined) {\n return undefined\n }\n current = current[segment]\n }\n\n return current\n}\n"],"names":["getTranslation","Pagination","PerPage","Table","Translation","useConfig","useDebouncedEffect","useDocumentInfo","useField","useFormFields","useTranslation","formatDocTitle","fieldAffectsData","React","useState","useTransition","DEFAULT_PREVIEW_LIMIT","PREVIEW_LIMIT_OPTIONS","baseClass","ImportPreview","isPending","startTransition","config","routes","collectionSlug","i18n","t","value","targetCollectionSlug","path","importMode","matchField","filename","url","mimeType","status","summary","fileField","fields","file","dataToRender","setDataToRender","columns","setColumns","totalDocs","setTotalDocs","error","setError","previewPage","setPreviewPage","previewLimit","setPreviewLimit","paginationData","setPaginationData","collectionConfig","useMemo","collections","find","c","slug","abortController","AbortController","processFileData","format","File","type","name","endsWith","fileData","arrayBuffer","base64","Buffer","from","toString","response","fetch","signal","ok","Error","res","api","body","JSON","stringify","credentials","headers","method","docs","hasNextPage","hasPrevPage","limit","responseLimit","page","responsePage","serverTotalDocs","totalPages","json","nextPage","prevPage","Array","isArray","length","buildColumnsFromFields","parentPath","parentLabel","cols","forEach","field","admin","disabled","fieldPath","label","hasData","some","doc","getValueAtPath","undefined","push","accessor","active","Heading","renderedCells","map","relationTo","relatedConfig","useAsTitle","titleValue","data","dateFormat","id","labels","singular","item","join","String","date","displayFormat","Date","toLocaleString","language","dateStyle","timeStyle","option","options","opt","block","blockType","groupLabel","nestedCols","tabs","tab","tabPath","tabLabel","tabCols","fieldColumns","metaFields","metaField","err","console","message","aborted","abort","div","className","h3","i18nKey","p","strong","imported","updated","total","issues","issueDetails","style","marginTop","ul","slice","issue","index","li","row","opacity","color","handlePageChange","handlePerPageChange","newLimit","span","variables","count","numberOfNeighbors","onChange","end","Math","min","start","handleChange","limits","obj","segments","split","current","segment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ImportPreview/index.tsx"],"sourcesContent":["'use client'\nimport type { Column } from '@payloadcms/ui'\nimport type { ClientField, ConditionalDateProps, PaginatedDocs } from 'payload'\n\nimport { getTranslation } from '@payloadcms/translations'\nimport {\n Pagination,\n PerPage,\n Table,\n Translation,\n useConfig,\n useDebouncedEffect,\n useDocumentInfo,\n useField,\n useFormFields,\n useTranslation,\n} from '@payloadcms/ui'\nimport { formatDocTitle } from '@payloadcms/ui/shared'\nimport { fieldAffectsData, getObjectDotNotation } from 'payload/shared'\nimport React, { useState, useTransition } from 'react'\n\nimport type {\n PluginImportExportTranslationKeys,\n PluginImportExportTranslations,\n} from '../../translations/index.js'\nimport type { ImportPreviewResponse } from '../../types.js'\n\nimport { DEFAULT_PREVIEW_LIMIT, PREVIEW_LIMIT_OPTIONS } from '../../constants.js'\nimport './index.scss'\n\nconst baseClass = 'import-preview'\n\nexport const ImportPreview: React.FC = () => {\n const [isPending, startTransition] = useTransition()\n const {\n config,\n config: { routes },\n } = useConfig()\n const { collectionSlug } = useDocumentInfo()\n const { i18n, t } = useTranslation<\n PluginImportExportTranslations,\n PluginImportExportTranslationKeys\n >()\n\n const { value: targetCollectionSlug } = useField<string>({ path: 'collectionSlug' })\n const { value: importMode } = useField<string>({ path: 'importMode' })\n const { value: matchField } = useField<string>({ path: 'matchField' })\n const { value: filename } = useField<string>({ path: 'filename' })\n const { value: url } = useField<string>({ path: 'url' })\n const { value: mimeType } = useField<string>({ path: 'mimeType' })\n const { value: status } = useField<string>({ path: 'status' })\n const { value: summary } = useField<any>({ path: 'summary' })\n\n // Access the file field directly from form fields\n const fileField = useFormFields(([fields]) => fields?.file || null)\n\n const [dataToRender, setDataToRender] = useState<Record<string, unknown>[]>([])\n const [columns, setColumns] = useState<Column[]>([])\n const [totalDocs, setTotalDocs] = useState<number>(0)\n const [error, setError] = useState<null | string>(null)\n\n // Preview pagination state\n const [previewPage, setPreviewPage] = useState(1)\n const [previewLimit, setPreviewLimit] = useState(DEFAULT_PREVIEW_LIMIT)\n const [paginationData, setPaginationData] = useState<null | Pick<\n PaginatedDocs,\n 'hasNextPage' | 'hasPrevPage' | 'limit' | 'nextPage' | 'page' | 'prevPage' | 'totalPages'\n >>(null)\n\n const collectionConfig = React.useMemo(\n () => config.collections.find((c) => c.slug === targetCollectionSlug),\n [targetCollectionSlug, config.collections],\n )\n\n useDebouncedEffect(\n () => {\n if (!collectionSlug || !targetCollectionSlug) {\n return\n }\n\n if (!targetCollectionSlug || (!url && !fileField?.value)) {\n setDataToRender([])\n setColumns([])\n setTotalDocs(0)\n setPaginationData(null)\n return\n }\n\n if (!collectionConfig) {\n setDataToRender([])\n setColumns([])\n setTotalDocs(0)\n setPaginationData(null)\n return\n }\n\n const abortController = new AbortController()\n\n const processFileData = async () => {\n setError(null)\n\n try {\n // Determine format from file\n let format: 'csv' | 'json' = 'json'\n if (fileField?.value && fileField.value instanceof File) {\n const file = fileField.value\n format = file.type === 'text/csv' || file.name?.endsWith('.csv') ? 'csv' : 'json'\n } else if (mimeType === 'text/csv' || filename?.endsWith('.csv')) {\n format = 'csv'\n }\n\n // Get file data as base64\n let fileData: string | undefined\n\n if (fileField?.value && fileField.value instanceof File) {\n // File is being uploaded, read its contents\n const arrayBuffer = await fileField.value.arrayBuffer()\n const base64 = Buffer.from(arrayBuffer).toString('base64')\n fileData = base64\n } else if (url) {\n // File has been saved, fetch from URL\n const response = await fetch(url, { signal: abortController.signal })\n if (!response.ok) {\n throw new Error('Failed to fetch file')\n }\n const arrayBuffer = await response.arrayBuffer()\n const base64 = Buffer.from(arrayBuffer).toString('base64')\n fileData = base64\n }\n\n if (!fileData) {\n setDataToRender([])\n setColumns([])\n setTotalDocs(0)\n setPaginationData(null)\n return\n }\n\n // Fetch transformed data from the server\n const res = await fetch(`${routes.api}/${collectionSlug}/preview-data`, {\n body: JSON.stringify({\n collectionSlug: targetCollectionSlug,\n fileData,\n format,\n previewLimit,\n previewPage,\n }),\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n method: 'POST',\n signal: abortController.signal,\n })\n\n if (!res.ok) {\n throw new Error('Failed to process file')\n }\n\n const {\n docs,\n hasNextPage,\n hasPrevPage,\n limit: responseLimit,\n page: responsePage,\n totalDocs: serverTotalDocs,\n totalPages,\n }: ImportPreviewResponse = await res.json()\n\n setTotalDocs(serverTotalDocs)\n setPaginationData({\n hasNextPage,\n hasPrevPage,\n limit: responseLimit,\n nextPage: responsePage + 1,\n page: responsePage,\n prevPage: responsePage - 1,\n totalPages,\n })\n\n if (!Array.isArray(docs) || docs.length === 0) {\n setDataToRender([])\n setColumns([])\n return\n }\n\n // Build columns from collection fields without traverseFields\n const buildColumnsFromFields = (\n fields: ClientField[],\n parentPath = '',\n parentLabel = '',\n ): Column[] => {\n const cols: Column[] = []\n\n fields.forEach((field) => {\n if (!fieldAffectsData(field) || field.admin?.disabled) {\n return\n }\n\n // Build the field path\n const fieldPath = parentPath ? `${parentPath}.${field.name}` : field.name\n\n // Get the field label\n let label = field.name\n if ('label' in field && field.label) {\n label = getTranslation(field.label, i18n)\n }\n\n // Add parent label prefix if in a group\n if (parentLabel) {\n label = `${parentLabel} > ${label}`\n }\n\n // Skip if this field doesn't exist in any document\n const hasData = docs.some((doc) => {\n const value = getObjectDotNotation(doc, fieldPath)\n return value !== undefined && value !== null\n })\n\n if (!hasData && field.type !== 'relationship') {\n return\n }\n\n cols.push({\n accessor: fieldPath,\n active: true,\n field,\n Heading: label,\n renderedCells: docs.map((doc) => {\n const value = getObjectDotNotation(doc, fieldPath)\n\n if (value === undefined || value === null) {\n return null\n }\n\n // Format based on field type\n if (field.type === 'relationship' || field.type === 'upload') {\n // Handle relationships\n if (typeof value === 'object' && !Array.isArray(value)) {\n // Single relationship\n const relationTo = Array.isArray(field.relationTo)\n ? (value as any).relationTo\n : field.relationTo\n\n const relatedConfig = config.collections.find((c) => c.slug === relationTo)\n if (relatedConfig && relatedConfig.admin?.useAsTitle) {\n const titleValue = (value as any)[relatedConfig.admin.useAsTitle]\n if (titleValue) {\n return formatDocTitle({\n collectionConfig: relatedConfig,\n data: value as any,\n dateFormat: config.admin.dateFormat,\n i18n,\n })\n }\n }\n\n // Fallback to ID\n const id = (value as any).id || value\n return `${getTranslation(relatedConfig?.labels?.singular || relationTo, i18n)}: ${id}`\n } else if (Array.isArray(value)) {\n // Multiple relationships\n return value\n .map((item) => {\n if (typeof item === 'object') {\n const relationTo = Array.isArray(field.relationTo)\n ? item.relationTo\n : field.relationTo\n const relatedConfig = config.collections.find(\n (c) => c.slug === relationTo,\n )\n\n if (relatedConfig && relatedConfig.admin?.useAsTitle) {\n const titleValue = item[relatedConfig.admin.useAsTitle]\n if (titleValue) {\n return formatDocTitle({\n collectionConfig: relatedConfig,\n data: item,\n dateFormat: config.admin.dateFormat,\n i18n,\n })\n }\n }\n\n return item.id || item\n }\n return item\n })\n .join(', ')\n }\n\n // Just an ID\n return String(value)\n } else if (field.type === 'date') {\n // Format dates\n const dateFormat =\n (field.admin &&\n 'date' in field.admin &&\n (field.admin.date as ConditionalDateProps)?.displayFormat) ||\n config.admin.dateFormat\n\n return new Date(value as string).toLocaleString(i18n.language, {\n dateStyle: 'medium',\n timeStyle: 'short',\n })\n } else if (field.type === 'checkbox') {\n return value ? '✓' : '✗'\n } else if (field.type === 'select' || field.type === 'radio') {\n // Show the label for select/radio options\n const option = field.options?.find((opt) => {\n if (typeof opt === 'string') {\n return opt === value\n }\n return opt.value === value\n })\n\n if (option && typeof option === 'object') {\n return getTranslation(option.label, i18n)\n }\n return String(value)\n } else if (field.type === 'number') {\n return String(value)\n } else if (Array.isArray(value)) {\n // Handle arrays\n if (field.type === 'blocks') {\n return value.map((block: any) => `${block.blockType || 'Block'}`).join(', ')\n }\n return `[${value.length} items]`\n } else if (typeof value === 'object') {\n // Handle objects\n if (field.type === 'group') {\n return '{...}'\n }\n return JSON.stringify(value)\n }\n\n return String(value)\n }),\n })\n\n // For groups, add nested fields with parent label\n if (field.type === 'group' && 'fields' in field) {\n const groupLabel =\n 'label' in field && field.label ? getTranslation(field.label, i18n) : field.name\n\n const nestedCols = buildColumnsFromFields(\n field.fields,\n fieldPath,\n parentLabel ? `${parentLabel} > ${groupLabel}` : groupLabel,\n )\n cols.push(...nestedCols)\n }\n\n // For tabs, process the fields within\n if ('tabs' in field && Array.isArray(field.tabs)) {\n field.tabs.forEach((tab) => {\n if ('name' in tab && tab.name) {\n // Named tab\n const tabPath = parentPath ? `${parentPath}.${tab.name}` : tab.name\n const tabLabel =\n 'label' in tab && tab.label ? getTranslation(tab.label, i18n) : tab.name\n\n const tabCols = buildColumnsFromFields(\n tab.fields,\n tabPath,\n parentLabel ? `${parentLabel} > ${tabLabel}` : tabLabel,\n )\n cols.push(...tabCols)\n } else {\n // Unnamed tab - fields go directly under parent\n const tabLabel =\n 'label' in tab && tab.label ? getTranslation(tab.label, i18n) : ''\n\n const tabCols = buildColumnsFromFields(\n tab.fields,\n parentPath,\n tabLabel && typeof tabLabel === 'string' && parentLabel\n ? `${parentLabel} > ${tabLabel}`\n : typeof tabLabel === 'string'\n ? tabLabel\n : parentLabel,\n )\n cols.push(...tabCols)\n }\n })\n }\n })\n\n return cols\n }\n\n // Add default meta fields at the end\n const fieldColumns = buildColumnsFromFields(collectionConfig.fields)\n const metaFields = ['id', 'createdAt', 'updatedAt', '_status']\n\n metaFields.forEach((metaField) => {\n const hasData = docs.some((doc) => doc[metaField] !== undefined)\n if (!hasData) {\n return\n }\n\n fieldColumns.push({\n accessor: metaField,\n active: true,\n field: { name: metaField } as ClientField,\n Heading: getTranslation(metaField, i18n),\n renderedCells: docs.map((doc) => {\n const value = doc[metaField]\n if (value === undefined || value === null) {\n return null\n }\n\n if (metaField === 'createdAt' || metaField === 'updatedAt') {\n return new Date(value as string).toLocaleString(i18n.language, {\n dateStyle: 'medium',\n timeStyle: 'short',\n })\n }\n\n return String(value)\n }),\n })\n })\n\n setColumns(fieldColumns)\n setDataToRender(docs)\n } catch (err) {\n console.error('Error processing file data:', err)\n setError(err instanceof Error ? err.message : 'Failed to load preview')\n setDataToRender([])\n setColumns([])\n setTotalDocs(0)\n setPaginationData(null)\n }\n }\n\n startTransition(async () => await processFileData())\n\n return () => {\n if (!abortController.signal.aborted) {\n abortController.abort('Component unmounted')\n }\n }\n },\n [\n collectionSlug,\n targetCollectionSlug,\n url,\n filename,\n mimeType,\n fileField?.value,\n collectionConfig,\n config,\n i18n,\n previewLimit,\n previewPage,\n routes.api,\n ],\n 500,\n )\n\n // If import has been processed, show results instead of preview\n if (status !== 'pending' && summary) {\n return (\n <div className={baseClass}>\n <div className={`${baseClass}__header`}>\n <h3>\n {/* @ts-expect-error - translations are not typed in plugins */}\n <Translation i18nKey=\"plugin-import-export:importResults\" t={t} />\n </h3>\n </div>\n <div className={`${baseClass}__results`}>\n <p>\n <strong>Status:</strong> {status}\n </p>\n <p>\n <strong>Imported:</strong> {summary.imported || 0}\n </p>\n <p>\n <strong>Updated:</strong> {summary.updated || 0}\n </p>\n <p>\n <strong>Total:</strong> {summary.total || 0}\n </p>\n {summary.issues > 0 && (\n <p>\n <strong>Issues:</strong> {summary.issues}\n </p>\n )}\n {summary.issueDetails && summary.issueDetails.length > 0 && (\n <div style={{ marginTop: '1rem' }}>\n <strong>Issue Details:</strong>\n <ul style={{ marginTop: '0.5rem' }}>\n {summary.issueDetails.slice(0, 10).map((issue: any, index: number) => (\n <li key={index}>\n Row {issue.row}: {issue.error}\n </li>\n ))}\n {summary.issueDetails.length > 10 && (\n <li>... and {summary.issueDetails.length - 10} more issues</li>\n )}\n </ul>\n </div>\n )}\n </div>\n </div>\n )\n }\n\n if (!targetCollectionSlug) {\n return (\n <div className={baseClass}>\n <p style={{ opacity: 0.6 }}>\n {/* @ts-expect-error - translations are not typed in plugins */}\n <Translation i18nKey=\"plugin-import-export:collectionRequired\" t={t} />\n </p>\n </div>\n )\n }\n\n if (error) {\n return (\n <div className={baseClass}>\n <p style={{ color: 'red' }}>\n <Translation i18nKey=\"general:error\" t={t} />: {error}\n </p>\n </div>\n )\n }\n\n if (!url && !fileField?.value) {\n return (\n <div className={baseClass}>\n <p style={{ opacity: 0.6 }}>\n {/* @ts-expect-error - translations are not typed in plugins */}\n <Translation i18nKey=\"plugin-import-export:uploadFileToSeePreview\" t={t} />\n </p>\n </div>\n )\n }\n\n const handlePageChange = (page: number) => {\n setPreviewPage(page)\n }\n\n const handlePerPageChange = (newLimit: number) => {\n setPreviewLimit(newLimit)\n setPreviewPage(1)\n }\n\n return (\n <div className={baseClass}>\n <div className={`${baseClass}__header`}>\n <h3>\n <Translation i18nKey=\"version:preview\" t={t} />\n </h3>\n {totalDocs > 0 && !isPending && (\n <div className={`${baseClass}__info`}>\n <span className={`${baseClass}__import-count`}>\n <Translation\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n i18nKey=\"plugin-import-export:documentsToImport\"\n t={t}\n variables={{\n count: totalDocs,\n }}\n />\n </span>\n {' | '}\n {/* @ts-expect-error - translations are not typed in plugins */}\n <Translation i18nKey=\"plugin-import-export:mode\" t={t} />: {importMode || 'create'}\n {importMode !== 'create' && (\n <>\n {' | '}\n {/* @ts-expect-error - translations are not typed in plugins */}\n <Translation i18nKey=\"plugin-import-export:matchBy\" t={t} />: {matchField || 'id'}\n </>\n )}\n </div>\n )}\n </div>\n {isPending && !dataToRender.length && (\n <div className={`${baseClass}__loading`}>\n <Translation i18nKey=\"general:loading\" t={t} />\n </div>\n )}\n {dataToRender.length > 0 && <Table columns={columns} data={dataToRender} />}\n {!isPending && dataToRender.length === 0 && targetCollectionSlug && (\n <p>\n {/* @ts-expect-error - translations are not typed in plugins */}\n <Translation i18nKey=\"plugin-import-export:noDataToPreview\" t={t} />\n </p>\n )}\n {paginationData && totalDocs > 0 && (\n <div className={`${baseClass}__pagination`}>\n {paginationData.totalPages > 1 && (\n <Pagination\n hasNextPage={paginationData.hasNextPage}\n hasPrevPage={paginationData.hasPrevPage}\n nextPage={paginationData.nextPage ?? undefined}\n numberOfNeighbors={1}\n onChange={handlePageChange}\n page={paginationData.page}\n prevPage={paginationData.prevPage ?? undefined}\n totalPages={paginationData.totalPages}\n />\n )}\n <span className={`${baseClass}__page-info`}>\n <Translation\n // @ts-expect-error - plugin translations not typed\n i18nKey=\"plugin-import-export:previewPageInfo\"\n t={t}\n variables={{\n end: Math.min((paginationData.page ?? 1) * previewLimit, totalDocs),\n start: ((paginationData.page ?? 1) - 1) * previewLimit + 1,\n total: totalDocs,\n }}\n />\n </span>\n <PerPage\n handleChange={handlePerPageChange}\n limit={previewLimit}\n limits={PREVIEW_LIMIT_OPTIONS}\n />\n </div>\n )}\n </div>\n )\n}\n"],"names":["getTranslation","Pagination","PerPage","Table","Translation","useConfig","useDebouncedEffect","useDocumentInfo","useField","useFormFields","useTranslation","formatDocTitle","fieldAffectsData","getObjectDotNotation","React","useState","useTransition","DEFAULT_PREVIEW_LIMIT","PREVIEW_LIMIT_OPTIONS","baseClass","ImportPreview","isPending","startTransition","config","routes","collectionSlug","i18n","t","value","targetCollectionSlug","path","importMode","matchField","filename","url","mimeType","status","summary","fileField","fields","file","dataToRender","setDataToRender","columns","setColumns","totalDocs","setTotalDocs","error","setError","previewPage","setPreviewPage","previewLimit","setPreviewLimit","paginationData","setPaginationData","collectionConfig","useMemo","collections","find","c","slug","abortController","AbortController","processFileData","format","File","type","name","endsWith","fileData","arrayBuffer","base64","Buffer","from","toString","response","fetch","signal","ok","Error","res","api","body","JSON","stringify","credentials","headers","method","docs","hasNextPage","hasPrevPage","limit","responseLimit","page","responsePage","serverTotalDocs","totalPages","json","nextPage","prevPage","Array","isArray","length","buildColumnsFromFields","parentPath","parentLabel","cols","forEach","field","admin","disabled","fieldPath","label","hasData","some","doc","undefined","push","accessor","active","Heading","renderedCells","map","relationTo","relatedConfig","useAsTitle","titleValue","data","dateFormat","id","labels","singular","item","join","String","date","displayFormat","Date","toLocaleString","language","dateStyle","timeStyle","option","options","opt","block","blockType","groupLabel","nestedCols","tabs","tab","tabPath","tabLabel","tabCols","fieldColumns","metaFields","metaField","err","console","message","aborted","abort","div","className","h3","i18nKey","p","strong","imported","updated","total","issues","issueDetails","style","marginTop","ul","slice","issue","index","li","row","opacity","color","handlePageChange","handlePerPageChange","newLimit","span","variables","count","numberOfNeighbors","onChange","end","Math","min","start","handleChange","limits"],"mappings":"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"}
|
|
@@ -18,6 +18,11 @@ export type Export = {
|
|
|
18
18
|
id: number | string;
|
|
19
19
|
limit?: number;
|
|
20
20
|
locale?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Maximum number of documents that can be exported in a single operation.
|
|
23
|
+
* This value has already been resolved from the plugin config.
|
|
24
|
+
*/
|
|
25
|
+
maxLimit?: number;
|
|
21
26
|
name: string;
|
|
22
27
|
page?: number;
|
|
23
28
|
slug: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createExport.d.ts","sourceRoot":"","sources":["../../src/export/createExport.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAa,KAAK,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"createExport.d.ts","sourceRoot":"","sources":["../../src/export/createExport.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAa,KAAK,EAAE,MAAM,SAAS,CAAA;AAgBrE,MAAM,MAAM,MAAM,GAAG;IACnB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,IAAI,GAAG,KAAK,CAAA;IACrB,iBAAiB,EAAE,MAAM,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,MAAM,EAAE,KAAK,GAAG,MAAM,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,IAAI,CAAA;IACV,cAAc,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,KAAK,CAAC,EAAE,KAAK,CAAA;CACd,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,GAAG,EAAE,cAAc,CAAA;CACpB,GAAG,MAAM,CAAA;AAEV,eAAO,MAAM,YAAY,SAAgB,gBAAgB,kCAydxD,CAAA"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { APIError } from 'payload';
|
|
3
3
|
import { Readable } from 'stream';
|
|
4
4
|
import { buildDisabledFieldRegex } from '../utilities/buildDisabledFieldRegex.js';
|
|
5
|
+
import { collectTimezoneCompanionFields } from '../utilities/collectTimezoneCompanionFields.js';
|
|
5
6
|
import { flattenObject } from '../utilities/flattenObject.js';
|
|
6
7
|
import { getExportFieldFunctions } from '../utilities/getExportFieldFunctions.js';
|
|
7
8
|
import { getFilename } from '../utilities/getFilename.js';
|
|
@@ -10,7 +11,7 @@ import { getSelect } from '../utilities/getSelect.js';
|
|
|
10
11
|
import { validateLimitValue } from '../utilities/validateLimitValue.js';
|
|
11
12
|
import { createExportBatchProcessor } from './batchProcessor.js';
|
|
12
13
|
export const createExport = async (args)=>{
|
|
13
|
-
const { id, name: nameArg, batchSize = 100, collectionSlug, debug = false, download, drafts: draftsFromInput, exportsCollection, fields, format, limit: incomingLimit, locale: localeFromInput, page, req, sort, userCollection, userID, where: whereFromInput = {} } = args;
|
|
14
|
+
const { id, name: nameArg, batchSize = 100, collectionSlug, debug = false, download, drafts: draftsFromInput, exportsCollection, fields, format, limit: incomingLimit, maxLimit, locale: localeFromInput, page, req, sort, userCollection, userID, where: whereFromInput = {} } = args;
|
|
14
15
|
const { locale: localeFromReq, payload } = req;
|
|
15
16
|
if (debug) {
|
|
16
17
|
req.payload.logger.debug({
|
|
@@ -65,7 +66,22 @@ export const createExport = async (args)=>{
|
|
|
65
66
|
locale
|
|
66
67
|
});
|
|
67
68
|
}
|
|
68
|
-
|
|
69
|
+
// Determine maximum export documents:
|
|
70
|
+
// 1. If maxLimit is defined, it sets the absolute ceiling
|
|
71
|
+
// 2. User's limit is applied but clamped to maxLimit if it exceeds it
|
|
72
|
+
let maxExportDocuments;
|
|
73
|
+
if (typeof maxLimit === 'number' && maxLimit > 0) {
|
|
74
|
+
if (typeof incomingLimit === 'number' && incomingLimit > 0) {
|
|
75
|
+
// User provided a limit - clamp it to maxLimit
|
|
76
|
+
maxExportDocuments = Math.min(incomingLimit, maxLimit);
|
|
77
|
+
} else {
|
|
78
|
+
// No user limit - use maxLimit as the ceiling
|
|
79
|
+
maxExportDocuments = maxLimit;
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
// No maxLimit - use user's limit if provided
|
|
83
|
+
maxExportDocuments = typeof incomingLimit === 'number' && incomingLimit > 0 ? incomingLimit : undefined;
|
|
84
|
+
}
|
|
69
85
|
// Try to count documents - if access is denied, treat as 0 documents
|
|
70
86
|
let totalDocs = 0;
|
|
71
87
|
let accessDenied = false;
|
|
@@ -113,12 +129,14 @@ export const createExport = async (args)=>{
|
|
|
113
129
|
const toCSVFunctions = getExportFieldFunctions({
|
|
114
130
|
fields: collectionConfig.flattenedFields
|
|
115
131
|
});
|
|
132
|
+
// Collect auto-generated timezone companion fields from schema
|
|
133
|
+
const timezoneCompanionFields = collectTimezoneCompanionFields(collectionConfig.flattenedFields);
|
|
116
134
|
const disabledFields = collectionConfig.admin?.custom?.['plugin-import-export']?.disabledFields ?? [];
|
|
117
|
-
const
|
|
135
|
+
const disabledMatchers = disabledFields.map(buildDisabledFieldRegex);
|
|
118
136
|
const filterDisabledCSV = (row)=>{
|
|
119
137
|
const filtered = {};
|
|
120
138
|
for (const [key, value] of Object.entries(row)){
|
|
121
|
-
const isDisabled =
|
|
139
|
+
const isDisabled = disabledMatchers.some((matcher)=>matcher.test(key));
|
|
122
140
|
if (!isDisabled) {
|
|
123
141
|
filtered[key] = value;
|
|
124
142
|
}
|
|
@@ -157,7 +175,8 @@ export const createExport = async (args)=>{
|
|
|
157
175
|
disabledFields,
|
|
158
176
|
fields,
|
|
159
177
|
locale,
|
|
160
|
-
localeCodes
|
|
178
|
+
localeCodes,
|
|
179
|
+
timezoneCompanionFields
|
|
161
180
|
});
|
|
162
181
|
if (debug) {
|
|
163
182
|
req.payload.logger.debug({
|
|
@@ -171,9 +190,9 @@ export const createExport = async (args)=>{
|
|
|
171
190
|
let columnsFinalized = false;
|
|
172
191
|
const encoder = new TextEncoder();
|
|
173
192
|
let isFirstBatch = true;
|
|
174
|
-
let
|
|
193
|
+
let currentBatchPage = adjustedPage;
|
|
175
194
|
let fetched = 0;
|
|
176
|
-
const maxDocs = typeof
|
|
195
|
+
const maxDocs = typeof maxExportDocuments === 'number' ? maxExportDocuments : Number.POSITIVE_INFINITY;
|
|
177
196
|
const stream = new Readable({
|
|
178
197
|
async read () {
|
|
179
198
|
const remaining = Math.max(0, maxDocs - fetched);
|
|
@@ -187,11 +206,11 @@ export const createExport = async (args)=>{
|
|
|
187
206
|
}
|
|
188
207
|
const result = await payload.find({
|
|
189
208
|
...findArgs,
|
|
190
|
-
page:
|
|
209
|
+
page: currentBatchPage,
|
|
191
210
|
limit: Math.min(batchSize, remaining)
|
|
192
211
|
});
|
|
193
212
|
if (debug) {
|
|
194
|
-
req.payload.logger.debug(`Streaming batch ${
|
|
213
|
+
req.payload.logger.debug(`Streaming batch ${currentBatchPage} with ${result.docs.length} docs`);
|
|
195
214
|
}
|
|
196
215
|
if (result.docs.length === 0) {
|
|
197
216
|
// Close JSON array properly if JSON
|
|
@@ -207,6 +226,7 @@ export const createExport = async (args)=>{
|
|
|
207
226
|
const batchRows = result.docs.map((doc)=>filterDisabledCSV(flattenObject({
|
|
208
227
|
doc,
|
|
209
228
|
fields,
|
|
229
|
+
timezoneCompanionFields,
|
|
210
230
|
toCSVFunctions
|
|
211
231
|
})));
|
|
212
232
|
// On first batch, discover additional columns from data and merge with schema
|
|
@@ -240,6 +260,7 @@ export const createExport = async (args)=>{
|
|
|
240
260
|
return fullRow;
|
|
241
261
|
});
|
|
242
262
|
const csvString = stringify(paddedRows, {
|
|
263
|
+
bom: isFirstBatch,
|
|
243
264
|
header: isFirstBatch,
|
|
244
265
|
columns: allColumns
|
|
245
266
|
});
|
|
@@ -257,7 +278,7 @@ export const createExport = async (args)=>{
|
|
|
257
278
|
}
|
|
258
279
|
fetched += result.docs.length;
|
|
259
280
|
isFirstBatch = false;
|
|
260
|
-
|
|
281
|
+
currentBatchPage += 1;
|
|
261
282
|
if (!result.hasNextPage || fetched >= maxDocs) {
|
|
262
283
|
if (debug) {
|
|
263
284
|
req.payload.logger.debug('Stream complete - no more pages');
|
|
@@ -289,6 +310,7 @@ export const createExport = async (args)=>{
|
|
|
289
310
|
const transformDoc = (doc)=>isCSV ? filterDisabledCSV(flattenObject({
|
|
290
311
|
doc,
|
|
291
312
|
fields,
|
|
313
|
+
timezoneCompanionFields,
|
|
292
314
|
toCSVFunctions
|
|
293
315
|
})) : filterDisabledJSON(doc);
|
|
294
316
|
// Skip fetching if access was denied - we'll create an empty export
|
|
@@ -302,7 +324,7 @@ export const createExport = async (args)=>{
|
|
|
302
324
|
collectionSlug,
|
|
303
325
|
findArgs: findArgs,
|
|
304
326
|
format,
|
|
305
|
-
maxDocs: typeof
|
|
327
|
+
maxDocs: typeof maxExportDocuments === 'number' ? maxExportDocuments : Number.POSITIVE_INFINITY,
|
|
306
328
|
req,
|
|
307
329
|
startPage: adjustedPage,
|
|
308
330
|
transformDoc
|
|
@@ -319,7 +341,8 @@ export const createExport = async (args)=>{
|
|
|
319
341
|
disabledFields,
|
|
320
342
|
fields,
|
|
321
343
|
locale,
|
|
322
|
-
localeCodes
|
|
344
|
+
localeCodes,
|
|
345
|
+
timezoneCompanionFields
|
|
323
346
|
});
|
|
324
347
|
// Merge schema columns with data-discovered columns
|
|
325
348
|
// Schema provides ordering, data provides additional columns (e.g., array indices > 0)
|
|
@@ -333,6 +356,7 @@ export const createExport = async (args)=>{
|
|
|
333
356
|
});
|
|
334
357
|
// Always output CSV with header, even if empty
|
|
335
358
|
outputData.push(stringify(paddedRows, {
|
|
359
|
+
bom: true,
|
|
336
360
|
header: true,
|
|
337
361
|
columns: finalColumns
|
|
338
362
|
}));
|