From 14ec8da3b875329067d0759a475fdca897a0575a Mon Sep 17 00:00:00 2001 From: Rajkumar Waghmare Date: Mon, 3 Jun 2024 15:24:20 +0900 Subject: [PATCH 1/7] Get the mapped headers early --- package.json | 2 +- src/importer/features/main/index.tsx | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 387d49fe..5767a26f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "csv-import-react", - "version": "1.0.11", + "version": "1.1.00", "description": "Open-source CSV and XLS/XLSX file importer for React and JavaScript", "main": "build/index.js", "module": "build/index.esm.js", diff --git a/src/importer/features/main/index.tsx b/src/importer/features/main/index.tsx index 28c012fb..a46c66a8 100644 --- a/src/importer/features/main/index.tsx +++ b/src/importer/features/main/index.tsx @@ -25,6 +25,7 @@ export default function Main(props: CSVImporterProps) { modalOnCloseTriggered = () => null, template, onComplete, + onCSVHeadersMapped, customStyles, showDownloadTemplateButton, skipHeaderRowSelection, @@ -196,6 +197,13 @@ export default function Main(props: CSVImporterProps) { onSuccess={(columnMapping) => { setIsSubmitting(true); setColumnMapping(columnMapping); + if (onCSVHeadersMapped) { + onCSVHeadersMapped(columnMapping).then(() => { + setIsSubmitting(false); + goNext(); + }); + return; + } // TODO (client-sdk): Move this type, add other data attributes (i.e. column definitions), and move the data processing to a function type MappedRow = { From 8fac24dde24346de38cd778e82fb8dfdc3d714f0 Mon Sep 17 00:00:00 2001 From: Rajkumar Waghmare Date: Mon, 3 Jun 2024 17:46:58 +0900 Subject: [PATCH 2/7] Add the type --- src/types/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types/index.ts b/src/types/index.ts index 1a8961d2..aafefb78 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -14,6 +14,7 @@ export type CSVImporterProps = (HTMLAttributes & HTMLAttribut className?: string; onComplete?: (data: any) => void; waitOnComplete?: boolean; + onCSVHeadersMapped?: (data: any) => Promise; customStyles?: Record | string; showDownloadTemplateButton?: boolean; skipHeaderRowSelection?: boolean; From cd0821b4a370fa28efde20b26a07b46ba0bc4957 Mon Sep 17 00:00:00 2001 From: Rajkumar Waghmare Date: Tue, 4 Jun 2024 08:41:44 +0900 Subject: [PATCH 3/7] Update package version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5767a26f..c92369da 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "csv-import-react", - "version": "1.1.00", + "version": "1.1.0", "description": "Open-source CSV and XLS/XLSX file importer for React and JavaScript", "main": "build/index.js", "module": "build/index.esm.js", From feb470720cfa3d56a8c08eb66687a5e4c7e5f079 Mon Sep 17 00:00:00 2001 From: Rajkumar Waghmare Date: Tue, 4 Jun 2024 11:58:57 +0900 Subject: [PATCH 4/7] Send back the original uploaded file back in onHeadersMapped callback --- README.md | 6 ++++++ src/importer/features/main/index.tsx | 21 +++++++++++++++------ src/types/index.ts | 2 +- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2ee2e03e..528e2fef 100644 --- a/README.md +++ b/README.md @@ -210,6 +210,12 @@ Example `data`: } ``` +### onHeadersMapped (_function_) +Callback function that fires when headers have been mapped (when you dont want to wait for onComplete and you just want the mapped headers and the original uploaded file). It returns `mappedHeaders`, an object that contains the mapping definitions and `originalFile` which is the `File` object representing the original uploaded file without any modifications to it. +```jsx +onHeadersMapped={(mappedHeaders, originalFile) => console.log(data)} +``` + ### darkMode (_boolean_, default: `false`) Toggle between dark mode (`true`) and light mode (`false`). diff --git a/src/importer/features/main/index.tsx b/src/importer/features/main/index.tsx index a46c66a8..a5d2d83c 100644 --- a/src/importer/features/main/index.tsx +++ b/src/importer/features/main/index.tsx @@ -25,7 +25,7 @@ export default function Main(props: CSVImporterProps) { modalOnCloseTriggered = () => null, template, onComplete, - onCSVHeadersMapped, + onHeadersMapped, customStyles, showDownloadTemplateButton, skipHeaderRowSelection, @@ -41,6 +41,7 @@ export default function Main(props: CSVImporterProps) { // Error handling const [initializationError, setInitializationError] = useState(null); const [dataError, setDataError] = useState(null); + const [originalFile, setOriginalFile] = useState(null); // File data const emptyData = { @@ -88,6 +89,7 @@ export default function Main(props: CSVImporterProps) { setColumnMapping({}); setDataError(null); setStep(StepEnum.Upload); + setOriginalFile(null); }; const requestClose = () => { @@ -119,6 +121,8 @@ export default function Main(props: CSVImporterProps) { setDataError={setDataError} onSuccess={async (file: File) => { setDataError(null); + setOriginalFile(file); + const fileType = file.name.slice(file.name.lastIndexOf(".") + 1); if (!["csv", "xls", "xlsx"].includes(fileType)) { setDataError("Only CSV, XLS, and XLSX files can be uploaded"); @@ -197,11 +201,16 @@ export default function Main(props: CSVImporterProps) { onSuccess={(columnMapping) => { setIsSubmitting(true); setColumnMapping(columnMapping); - if (onCSVHeadersMapped) { - onCSVHeadersMapped(columnMapping).then(() => { - setIsSubmitting(false); - goNext(); - }); + if (onHeadersMapped) { + onHeadersMapped(columnMapping, originalFile) + .then(() => { + setIsSubmitting(false); + goNext(); + }) + .catch((error) => { + console.error("onHeadersMapped error", error); + setDataError("An error occurred while processing the data"); + }); return; } diff --git a/src/types/index.ts b/src/types/index.ts index aafefb78..9b728958 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -14,7 +14,7 @@ export type CSVImporterProps = (HTMLAttributes & HTMLAttribut className?: string; onComplete?: (data: any) => void; waitOnComplete?: boolean; - onCSVHeadersMapped?: (data: any) => Promise; + onHeadersMapped?: (mappedHeaders: any, originalFile: File | null) => Promise; customStyles?: Record | string; showDownloadTemplateButton?: boolean; skipHeaderRowSelection?: boolean; From 4fb42a66fa4b460c6f9a11c5ef72499d8fda7059 Mon Sep 17 00:00:00 2001 From: Rajkumar Waghmare Date: Tue, 4 Jun 2024 12:58:34 +0900 Subject: [PATCH 5/7] Update README and define type for data returned by onHeadersMapped --- README.md | 3 ++- src/types/index.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 528e2fef..f441afb8 100644 --- a/README.md +++ b/README.md @@ -212,8 +212,9 @@ Example `data`: ### onHeadersMapped (_function_) Callback function that fires when headers have been mapped (when you dont want to wait for onComplete and you just want the mapped headers and the original uploaded file). It returns `mappedHeaders`, an object that contains the mapping definitions and `originalFile` which is the `File` object representing the original uploaded file without any modifications to it. +When `onHeadersMapped` is defined, `onComplete` callback will not be fired. ```jsx -onHeadersMapped={(mappedHeaders, originalFile) => console.log(data)} +onHeadersMapped={(mappedHeaders, originalFile) => console.log(mappedHeaders)} ``` ### darkMode (_boolean_, default: `false`) diff --git a/src/types/index.ts b/src/types/index.ts index 9b728958..c5346d16 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,4 +1,5 @@ import { HTMLAttributes } from "react"; +import { TemplateColumnMapping } from "../importer/features/map-columns/types"; type ModalParams = { isModal?: boolean; @@ -14,7 +15,7 @@ export type CSVImporterProps = (HTMLAttributes & HTMLAttribut className?: string; onComplete?: (data: any) => void; waitOnComplete?: boolean; - onHeadersMapped?: (mappedHeaders: any, originalFile: File | null) => Promise; + onHeadersMapped?: (mappedHeaders: { [index: number]: TemplateColumnMapping }, originalFile: File | null) => Promise; customStyles?: Record | string; showDownloadTemplateButton?: boolean; skipHeaderRowSelection?: boolean; From 5eb7b784f256466e59de432750c20fd747001f2c Mon Sep 17 00:00:00 2001 From: Rajkumar Waghmare Date: Tue, 4 Jun 2024 14:20:19 +0900 Subject: [PATCH 6/7] Add selectedHeaderRow to onHeadersMapped --- README.md | 4 ++-- src/importer/features/main/index.tsx | 2 +- src/types/index.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f441afb8..99980b01 100644 --- a/README.md +++ b/README.md @@ -211,10 +211,10 @@ Example `data`: ``` ### onHeadersMapped (_function_) -Callback function that fires when headers have been mapped (when you dont want to wait for onComplete and you just want the mapped headers and the original uploaded file). It returns `mappedHeaders`, an object that contains the mapping definitions and `originalFile` which is the `File` object representing the original uploaded file without any modifications to it. +Callback function that fires when headers have been mapped (when you dont want to wait for onComplete and you just want the mapped headers and the original uploaded file). It returns `selectedHeaderRow` which tells which row was selected as a header row in the previous step, `mappedHeaders` an object that contains the mapping definitions and `originalFile` which is the `File` object representing the original uploaded file without any modifications to it. When `onHeadersMapped` is defined, `onComplete` callback will not be fired. ```jsx -onHeadersMapped={(mappedHeaders, originalFile) => console.log(mappedHeaders)} +onHeadersMapped={(selectedHeaderRow, mappedHeaders, originalFile) => console.log(mappedHeaders)} ``` ### darkMode (_boolean_, default: `false`) diff --git a/src/importer/features/main/index.tsx b/src/importer/features/main/index.tsx index a5d2d83c..84bd0dbc 100644 --- a/src/importer/features/main/index.tsx +++ b/src/importer/features/main/index.tsx @@ -202,7 +202,7 @@ export default function Main(props: CSVImporterProps) { setIsSubmitting(true); setColumnMapping(columnMapping); if (onHeadersMapped) { - onHeadersMapped(columnMapping, originalFile) + onHeadersMapped(selectedHeaderRow, columnMapping, originalFile) .then(() => { setIsSubmitting(false); goNext(); diff --git a/src/types/index.ts b/src/types/index.ts index c5346d16..18b03c64 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -15,7 +15,7 @@ export type CSVImporterProps = (HTMLAttributes & HTMLAttribut className?: string; onComplete?: (data: any) => void; waitOnComplete?: boolean; - onHeadersMapped?: (mappedHeaders: { [index: number]: TemplateColumnMapping }, originalFile: File | null) => Promise; + onHeadersMapped?: (selectedHeaderRow: number | null, mappedHeaders: { [index: number]: TemplateColumnMapping }, originalFile: File | null) => Promise; customStyles?: Record | string; showDownloadTemplateButton?: boolean; skipHeaderRowSelection?: boolean; From ab40cd5a488a3563c0fe60899e90ad527dc78110 Mon Sep 17 00:00:00 2001 From: Rajkumar Waghmare Date: Thu, 20 Jun 2024 09:56:00 +0900 Subject: [PATCH 7/7] Fix onHeadersMapped not found issue --- package.json | 2 +- src/components/CSVImporter/index.tsx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index c92369da..215c4d84 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "csv-import-react", - "version": "1.1.0", + "version": "1.1.2", "description": "Open-source CSV and XLS/XLSX file importer for React and JavaScript", "main": "build/index.js", "module": "build/index.esm.js", diff --git a/src/components/CSVImporter/index.tsx b/src/components/CSVImporter/index.tsx index 2f79feeb..4ad023ed 100644 --- a/src/components/CSVImporter/index.tsx +++ b/src/components/CSVImporter/index.tsx @@ -22,6 +22,7 @@ const CSVImporter = forwardRef((importerProps: CSVImporterProps, forwardRef?: an customStyles, showDownloadTemplateButton, skipHeaderRowSelection, + onHeadersMapped, ...props } = importerProps; const ref = forwardRef ?? useRef(null);