diff --git a/src/components/TableModals/ImportAirtableWizard/ImportAirtableWizard.tsx b/src/components/TableModals/ImportAirtableWizard/ImportAirtableWizard.tsx index 7a6cee3f..193743c2 100644 --- a/src/components/TableModals/ImportAirtableWizard/ImportAirtableWizard.tsx +++ b/src/components/TableModals/ImportAirtableWizard/ImportAirtableWizard.tsx @@ -28,6 +28,8 @@ import { fieldParser } from "@src/components/TableModals/ImportAirtableWizard/ut import Step1Columns from "./Step1Columns"; import Step2NewColumns from "./Step2NewColumns"; import Step3Preview from "./Step3Preview"; +import useConverter from "@src/components/TableModals/ImportCsvWizard/useConverter"; +import useUploadFileFromURL from "@src/components/TableModals/ImportCsvWizard/useUploadFileFromURL"; export type AirtableConfig = { pairs: { fieldKey: string; columnKey: string }[]; @@ -65,6 +67,8 @@ export default function ImportAirtableWizard({ onClose }: ITableModalProps) { newColumns: [], documentId: "recordId", }); + const { needsUploadTypes, getConverter } = useConverter(); + const { addTask, runBatchedUpload, hasUploadJobs } = useUploadFileFromURL(); const updateConfig: IStepProps["updateConfig"] = useCallback((value) => { setConfig((prev) => { @@ -99,10 +103,24 @@ export default function ImportAirtableWizard({ onClose }: ITableModalProps) { const matchingColumn = columns[pair.columnKey] ?? find(config.newColumns, { key: pair.columnKey }); - const parser = fieldParser(matchingColumn.type); + const parser = + getConverter(matchingColumn.type) || fieldParser(matchingColumn.type); const value = parser ? parser(record.fields[pair.fieldKey]) : record.fields[pair.fieldKey]; + + if (needsUploadTypes(matchingColumn.type)) { + if (value && value.length > 0) { + addTask({ + docRef: { + path: `${tableSettings.collection}/${record.id}`, + id: record.id, + }, + fieldName: pair.columnKey, + files: value, + }); + } + } return config.documentId === "recordId" ? { ...a, [pair.columnKey]: value, _rowy_ref: { id: record.id } } : { ...a, [pair.columnKey]: value }; @@ -196,6 +214,10 @@ export default function ImportAirtableWizard({ onClose }: ITableModalProps) { `Imported ${Number(countRef.current).toLocaleString()} rows`, { variant: "success" } ); + + if (hasUploadJobs()) { + await runBatchedUpload(); + } } catch (e) { enqueueSnackbar((e as Error).message, { variant: "error" }); } finally { diff --git a/src/components/TableModals/ImportCsvWizard/ImportCsvWizard.tsx b/src/components/TableModals/ImportCsvWizard/ImportCsvWizard.tsx index 421fbc30..4f3f9a9e 100644 --- a/src/components/TableModals/ImportCsvWizard/ImportCsvWizard.tsx +++ b/src/components/TableModals/ImportCsvWizard/ImportCsvWizard.tsx @@ -37,7 +37,6 @@ import { import { ColumnConfig } from "@src/types/table"; import { getFieldProp } from "@src/components/fields"; import { analytics, logEvent } from "@src/analytics"; -import { FieldType } from "@src/constants/fields"; import { generateId } from "@src/utils/table"; import { isValidDocId } from "./utils"; import useUploadFileFromURL from "./useUploadFileFromURL"; @@ -50,8 +49,6 @@ export type CsvConfig = { documentIdCsvKey: string | null; }; -const needsUploadTypes = [FieldType.image, FieldType.file]; - export interface IStepProps { csvData: NonNullable; config: CsvConfig; @@ -71,8 +68,8 @@ export default function ImportCsvWizard({ onClose }: ITableModalProps) { const theme = useTheme(); const isXs = useMediaQuery(theme.breakpoints.down("sm")); const snackbarProgressRef = useRef(); - const { addTask, runBatchUpload, askPermission } = useUploadFileFromURL(); - const { needsConverter, getConverter } = useConverter(); + const { addTask, runBatchedUpload } = useUploadFileFromURL(); + const { needsUploadTypes, needsConverter, getConverter } = useConverter(); const columns = useMemoValue(tableSchema.columns ?? {}, isEqual); @@ -147,7 +144,7 @@ export default function ImportCsvWizard({ onClose }: ITableModalProps) { if (needsConverter(column.type)) { requiredConverts[index] = getConverter(column.type); // console.log({ needsUploadTypes }, column.type); - if (needsUploadTypes.includes(column.type)) { + if (needsUploadTypes(column.type)) { requiredUploads[column.fieldName + ""] = true; } } @@ -158,6 +155,7 @@ export default function ImportCsvWizard({ onClose }: ITableModalProps) { config.pairs, getConverter, needsConverter, + needsUploadTypes, tableSchema.columns, ]); @@ -266,8 +264,8 @@ export default function ImportCsvWizard({ onClose }: ITableModalProps) { `Imported ${Number(validRows.length).toLocaleString()} rows`, { variant: "success" } ); - if (Object.keys(requiredUploads).length && (await askPermission())) { - await runBatchUpload(); + if (Object.keys(requiredUploads).length > 0) { + await runBatchedUpload(); } } catch (e) { enqueueSnackbar((e as Error).message, { variant: "error" }); diff --git a/src/components/TableModals/ImportCsvWizard/useConverter.ts b/src/components/TableModals/ImportCsvWizard/useConverter.ts index 489a3127..58f597be 100644 --- a/src/components/TableModals/ImportCsvWizard/useConverter.ts +++ b/src/components/TableModals/ImportCsvWizard/useConverter.ts @@ -16,6 +16,9 @@ const needsConverter = (type: FieldType) => FieldType.geoPoint, ].includes(type); +const needsUploadTypes = (type: FieldType) => + [FieldType.image, FieldType.file].includes(type); + export default function useConverter() { const [firebaseDb] = useAtom(firebaseDbAtom, projectScope); @@ -35,27 +38,59 @@ export default function useConverter() { }; const imageOrFileConverter = (urls: any): RowyFile[] => { - if (!urls) return []; - if (Array.isArray(urls)) return urls; - if (typeof urls === "string") { - return urls - .split(",") - .map((url) => { - url = url.trim(); - if (url !== "") { - return { - downloadURL: url, - name: url.split("/").pop() || "", - lastModifiedTS: +new Date(), - type: "", - }; - } + try { + if (!urls) return []; + if (Array.isArray(urls)) { + return urls + .map((url) => { + if (typeof url === "string") { + url = url.trim(); + if (url !== "") { + return { + downloadURL: url, + name: url.split("/").pop() || "", + lastModifiedTS: +new Date(), + type: "", + }; + } + } else if (url && typeof url === "object" && url.downloadURL) { + return url; + } else { + if (url.url) { + return { + downloadURL: url.url, + name: url.filename || url.url.split("/").pop() || "", + lastModifiedTS: +new Date(), + type: "", + }; + } + } + return null; + }) + .filter((val) => val !== null) as RowyFile[]; + } + if (typeof urls === "string") { + return urls + .split(",") + .map((url) => { + url = url.trim(); + if (url !== "") { + return { + downloadURL: url, + name: url.split("/").pop() || "", + lastModifiedTS: +new Date(), + type: "", + }; + } - return null; - }) - .filter((val) => val !== null) as RowyFile[]; + return null; + }) + .filter((val) => val !== null) as RowyFile[]; + } + return []; + } catch (e) { + return []; } - return []; }; const geoPointConverter = (value: any) => { @@ -120,5 +155,6 @@ export default function useConverter() { imageOrFileConverter, getConverter, checkAndConvert, + needsUploadTypes, }; } diff --git a/src/components/TableModals/ImportCsvWizard/useUploadFileFromURL.tsx b/src/components/TableModals/ImportCsvWizard/useUploadFileFromURL.tsx index 0fae28fd..00d99b69 100644 --- a/src/components/TableModals/ImportCsvWizard/useUploadFileFromURL.tsx +++ b/src/components/TableModals/ImportCsvWizard/useUploadFileFromURL.tsx @@ -126,7 +126,7 @@ export default function useUploadFileFromURL() { [enqueueSnackbar] ); - const runBatchUpload = useCallback(async () => { + const runBatchedUpload = useCallback(async () => { if (!snackbarProgressId.current) { showProgress(jobs.current.length); } @@ -145,7 +145,7 @@ export default function useUploadFileFromURL() { await batchUpload(currentJobs); if (jobs.current.length > 0) { - await runBatchUpload(); + await runBatchedUpload(); } if (snackbarProgressId.current) { @@ -157,10 +157,12 @@ export default function useUploadFileFromURL() { jobs.current.push(job); }, []); + const hasUploadJobs = () => jobs.current.length > 0; return { addTask, - runBatchUpload, + runBatchedUpload, askPermission, + hasUploadJobs, }; }