added Airtable import/upload files

This commit is contained in:
Anish Roy
2023-03-28 10:21:41 +05:30
parent 3e53b2a178
commit bb2fcf3b64
4 changed files with 89 additions and 31 deletions

View File

@@ -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 {

View File

@@ -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<ImportCsvData>;
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<ISnackbarProgressRef>();
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" });

View File

@@ -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,
};
}

View File

@@ -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,
};
}