fuse-importer 0.26.8 → 0.27.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/lib/esm/Importer/ImporterWithContext.js +2 -1
- package/lib/esm/Importer/Review/ReviewContextProvider.d.ts +1 -0
- package/lib/esm/Importer/Review/ReviewContextProvider.js +59 -27
- package/lib/esm/Importer/Review/ReviewWithContext.js +2 -2
- package/lib/esm/Importer/Uploader/DragAndDropImporter/ImporterDropzone.js +9 -12
- package/lib/esm/Importer/common/Spreadsheet/SpreadsheetContextProvider/filterMethods.js +9 -20
- package/lib/esm/Importer/common/Spreadsheet/SpreadsheetContextProvider/index.js +9 -1
- package/lib/esm/Importer/common/Spreadsheet/common/types.d.ts +1 -0
- package/lib/esm/Importer/common/Spreadsheet/hooks.d.ts +1 -1
- package/lib/esm/Importer/common/Spreadsheet/hooks.js +29 -9
- package/lib/esm/Importer/common/Spreadsheet/index.d.ts +1 -1
- package/lib/esm/Importer/common/Spreadsheet/index.js +4 -10
- package/lib/esm/Importer/common/Spreadsheet/validation/index.js +8 -2
- package/lib/esm/Importer/data/index.js +3 -1
- package/lib/esm/common/AppLoadingContextProvider/AppLoadingUI.d.ts +1 -0
- package/lib/esm/common/AppLoadingContextProvider/AppLoadingUI.js +26 -0
- package/lib/esm/common/AppLoadingContextProvider/index.d.ts +10 -0
- package/lib/esm/common/AppLoadingContextProvider/index.js +25 -0
- package/lib/esm/index.d.ts +1 -1
- package/lib/esm/index.js +15 -27
- package/lib/esm/locales/de.js +1 -1
- package/lib/esm/locales/en.js +1 -1
- package/lib/esm/locales/es.js +1 -1
- package/lib/esm/locales/fr.js +1 -1
- package/lib/esm/types.d.ts +4 -7
- package/lib/main.js +24 -24
- package/lib/main.js.LICENSE.txt +6 -1
- package/package.json +5 -5
|
@@ -32,6 +32,7 @@ import { Footer } from "./common/Footer";
|
|
|
32
32
|
import { GlobalStyle } from "./common/GlobalStyle";
|
|
33
33
|
import { ImporterFonts } from "./common/ImporterFonts";
|
|
34
34
|
import { useImporterContext } from "./contexts/ImporterContextProvider";
|
|
35
|
+
import { AppLoadingContextProvider } from "../common/AppLoadingContextProvider";
|
|
35
36
|
export var Layout = styled(Div)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n background: ", ";\n display: flex;\n flex-direction: column;\n height: 100vh;\n left: 0;\n overflow-y: auto;\n position: fixed;\n top: 0;\n width: 100vw;\n z-index: ", ";\n ", ";\n"], ["\n background: ", ";\n display: flex;\n flex-direction: column;\n height: 100vh;\n left: 0;\n overflow-y: auto;\n position: fixed;\n top: 0;\n width: 100vw;\n z-index: ", ";\n ", ";\n"])), function (_a) {
|
|
36
37
|
var theme = _a.theme;
|
|
37
38
|
return theme.colors.backgroundInterface;
|
|
@@ -57,6 +58,6 @@ export var ImporterWithContext = function () {
|
|
|
57
58
|
return (_jsxs(_Fragment, { children: [_jsxs(Div, { children: [previewMode && _jsx(PreviewModeBanner, {}), !previewMode && _jsx(TrialModeBanner, {}), _jsx(Stepper, { stepLabels: stepLabels, logoURL: logoURL })] }), _jsxs(Content, { children: [currentStepIndex === 0 && _jsx(Uploader, {}), currentStepIndex === 1 && _jsx(Matcher, {}), currentStepIndex === 2 && templateHeaders && _jsx(Review, {})] }), inTrialMode && (_jsx(Content, __assign({ inTrialMode: inTrialMode }, { children: _jsx(Footer, {}) })))] }));
|
|
58
59
|
}
|
|
59
60
|
var shouldShowPreviewFirstTime = previewFirstTime && previewMode;
|
|
60
|
-
return (
|
|
61
|
+
return (_jsx(ThemeProvider, __assign({ theme: theme }, { children: _jsxs(AppLoadingContextProvider, { children: [_jsx(Toast, {}), _jsx(GlobalStyle, {}), _jsx(ImporterFonts, {}), templateHeaders ? (_jsx(ReviewContextProvider, __assign({ initialRecords: initialRecords }, { children: _jsx(Layout, __assign({ zIndex: zIndex, ref: layoutRef }, { children: shouldShowPreviewFirstTime ? (_jsx(PreviewFirstTime, {})) : (renderContent()) })) }))) : (_jsx(AppLoading, {}))] }) })));
|
|
61
62
|
};
|
|
62
63
|
var templateObject_1, templateObject_2, templateObject_3;
|
|
@@ -67,13 +67,14 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
67
67
|
};
|
|
68
68
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
69
69
|
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react";
|
|
70
|
-
import
|
|
70
|
+
import Papa from "papaparse";
|
|
71
71
|
import { AppLoading } from "../common/AppLoading";
|
|
72
72
|
import { isRecordEmpty } from "../common/Spreadsheet/common";
|
|
73
73
|
import { sendRecordsToIntegrations } from "../common/utils";
|
|
74
74
|
import { useImporterContext } from "../contexts/ImporterContextProvider";
|
|
75
75
|
import { transformToRecords } from "../data/index";
|
|
76
76
|
import { getPreviewDataSet, getReviewDataSet, getTemplateFields, recordListToDataSet, } from "../data";
|
|
77
|
+
import { useAppLoadingContext } from "../../common/AppLoadingContextProvider";
|
|
77
78
|
var ReviewContext = createContext({});
|
|
78
79
|
var trackImportedRowsCount = function (fuseApi, templateSlug, rowCount) { return __awaiter(void 0, void 0, void 0, function () {
|
|
79
80
|
var error_1, errorMessage;
|
|
@@ -107,6 +108,15 @@ var filterAndMapWithBackendErrors = function (dataSet, errors) {
|
|
|
107
108
|
return __assign(__assign({}, record), { _meta: __assign(__assign({}, meta), { isInvalid: true, backendErrors: errors[rId] }) });
|
|
108
109
|
}, []);
|
|
109
110
|
};
|
|
111
|
+
function downloadCsv(data, fileName) {
|
|
112
|
+
var blob = new Blob([data], { type: "text/csv;charset=utf-8;" });
|
|
113
|
+
var link = document.createElement("a");
|
|
114
|
+
link.href = URL.createObjectURL(blob);
|
|
115
|
+
link.download = fileName;
|
|
116
|
+
document.body.appendChild(link);
|
|
117
|
+
link.click();
|
|
118
|
+
document.body.removeChild(link);
|
|
119
|
+
}
|
|
110
120
|
function csvExport(data) {
|
|
111
121
|
var valuesWithQuotesWhenNecessary = data.map(function (obj) {
|
|
112
122
|
var newObj = {};
|
|
@@ -117,15 +127,13 @@ function csvExport(data) {
|
|
|
117
127
|
}
|
|
118
128
|
return newObj;
|
|
119
129
|
});
|
|
120
|
-
var
|
|
121
|
-
|
|
122
|
-
utils.book_append_sheet(workbook, worksheet, "Data");
|
|
123
|
-
utils.sheet_to_csv(worksheet);
|
|
124
|
-
writeFile(workbook, "export.csv");
|
|
130
|
+
var csv = Papa.unparse(valuesWithQuotesWhenNecessary);
|
|
131
|
+
downloadCsv(csv, "export.csv");
|
|
125
132
|
}
|
|
126
133
|
export var ReviewContextProvider = function (_a) {
|
|
127
134
|
var initialRecords = _a.initialRecords, children = _a.children;
|
|
128
135
|
var _b = useImporterContext(), templateHeaderMatchings = _b.templateHeaderMatchings, enumFieldValueMatchings = _b.enumFieldValueMatchings, templateHeaders = _b.templateHeaders, uploadedDataHeaders = _b.uploadedDataHeaders, headerRowIndex = _b.headerRowIndex, uploadedData = _b.uploadedData, currentStepIndex = _b.currentStepIndex, integrations = _b.integrations, templateSlug = _b.templateSlug, fuseApi = _b.fuseApi, setSelectedRows = _b.setSelectedRows, _c = _b.importerOptions, disableSubmitIfInvalid = _c.disableSubmitIfInvalid, batchValidationDelayMs = _c.batchValidationDelayMs, batchValidationSize = _c.batchValidationSize, previewMode = _c.previewMode, loadingComponent = _c.loadingComponent, onSubmit = _b.onSubmit, onValidateRecord = _b.onValidateRecord, formatRecord = _b.formatRecord, selectedRows = _b.selectedRows;
|
|
136
|
+
var setIsLoadingApp = useAppLoadingContext().setIsLoadingApp;
|
|
129
137
|
var _d = useState(false), isSubmitting = _d[0], setIsSubmitting = _d[1];
|
|
130
138
|
var _e = useState(false), isSubmitDisabled = _e[0], setIsSubmitDisabled = _e[1];
|
|
131
139
|
var _f = useState(false), importWasSuccessful = _f[0], setImportWasSuccessful = _f[1];
|
|
@@ -134,6 +142,7 @@ export var ReviewContextProvider = function (_a) {
|
|
|
134
142
|
var _j = useState(null), previewInitialDataSet = _j[0], setPreviewInitialDataSet = _j[1];
|
|
135
143
|
var _k = useState([]), reviewFields = _k[0], setReviewFields = _k[1];
|
|
136
144
|
var _l = useState(null), reviewInitialDataSet = _l[0], setReviewInitialDataSet = _l[1];
|
|
145
|
+
var _m = useState(null), initialDataSetUpdatedAt = _m[0], setInitialDataSetUpdatedAt = _m[1];
|
|
137
146
|
useEffect(function () {
|
|
138
147
|
if (currentStepIndex === 1)
|
|
139
148
|
setReviewInitialDataSet(null);
|
|
@@ -232,31 +241,53 @@ export var ReviewContextProvider = function (_a) {
|
|
|
232
241
|
reviewDataSetRef.current = null;
|
|
233
242
|
return;
|
|
234
243
|
}
|
|
244
|
+
var sleep = function (n) { return new Promise(function (resolve) { return setTimeout(resolve, n); }); };
|
|
235
245
|
if (currentStepIndex === 0) {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
246
|
+
if (!previewInitialDataSet) {
|
|
247
|
+
//Uploader spreadsheet data
|
|
248
|
+
var _a = getPreviewDataSet({ uploadedData: uploadedData }), fields = _a.fields, initialDataSet = _a.initialDataSet;
|
|
249
|
+
setPreviewFields(fields);
|
|
250
|
+
setPreviewInitialDataSet(initialDataSet);
|
|
251
|
+
}
|
|
240
252
|
}
|
|
241
253
|
else if (currentStepIndex === 2) {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
254
|
+
setIsLoadingApp(true);
|
|
255
|
+
(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
256
|
+
var fields, _records, initialDataSet;
|
|
257
|
+
return __generator(this, function (_a) {
|
|
258
|
+
switch (_a.label) {
|
|
259
|
+
case 0:
|
|
260
|
+
if (!(uploadedData.length > 10000)) return [3 /*break*/, 2];
|
|
261
|
+
// wait for the first render to complete before blocking main thread with review step logic
|
|
262
|
+
return [4 /*yield*/, sleep(200)];
|
|
263
|
+
case 1:
|
|
264
|
+
// wait for the first render to complete before blocking main thread with review step logic
|
|
265
|
+
_a.sent();
|
|
266
|
+
_a.label = 2;
|
|
267
|
+
case 2:
|
|
268
|
+
fields = getTemplateFields({ templateHeaders: templateHeaders });
|
|
269
|
+
_records = initialRecords ||
|
|
270
|
+
transformToRecords({
|
|
271
|
+
templateHeaderMatchings: templateHeaderMatchings,
|
|
272
|
+
enumFieldValueMatchings: enumFieldValueMatchings,
|
|
273
|
+
templateHeaders: templateHeaders,
|
|
274
|
+
uploadedDataHeaders: uploadedDataHeaders,
|
|
275
|
+
uploadedData: uploadedData.slice(headerRowIndex + 1),
|
|
276
|
+
formatRecord: formatRecord,
|
|
277
|
+
});
|
|
278
|
+
initialDataSet = getReviewDataSet({
|
|
279
|
+
records: _records,
|
|
280
|
+
fields: fields,
|
|
281
|
+
}).initialDataSet;
|
|
282
|
+
setSelectedRows([]);
|
|
283
|
+
setReviewFields(fields);
|
|
284
|
+
setReviewInitialDataSet(initialDataSet);
|
|
285
|
+
setInitialDataSetUpdatedAt(Date.now());
|
|
286
|
+
setIsLoadingApp(false);
|
|
287
|
+
return [2 /*return*/];
|
|
288
|
+
}
|
|
252
289
|
});
|
|
253
|
-
|
|
254
|
-
records: _records,
|
|
255
|
-
fields: fields,
|
|
256
|
-
}).initialDataSet;
|
|
257
|
-
setSelectedRows([]);
|
|
258
|
-
setReviewFields(fields);
|
|
259
|
-
setReviewInitialDataSet(initialDataSet);
|
|
290
|
+
}); })();
|
|
260
291
|
}
|
|
261
292
|
}, [uploadedData, currentStepIndex, templateHeaders, uploadedData]);
|
|
262
293
|
var value = {
|
|
@@ -269,6 +300,7 @@ export var ReviewContextProvider = function (_a) {
|
|
|
269
300
|
appResponse: appResponse,
|
|
270
301
|
isSubmitting: isSubmitting,
|
|
271
302
|
options: options,
|
|
303
|
+
initialDataSetUpdatedAt: initialDataSetUpdatedAt,
|
|
272
304
|
onSubmit: onSubmitData,
|
|
273
305
|
onExport: onExport,
|
|
274
306
|
onValidateRecord: onValidateRecord,
|
|
@@ -23,10 +23,10 @@ import { AppResponseModal } from "./AppResponseModal";
|
|
|
23
23
|
import { useReviewContext } from "./ReviewContextProvider";
|
|
24
24
|
var TitleContainer = styled(Div)(templateObject_1 || (templateObject_1 = __makeTemplateObject([""], [""])));
|
|
25
25
|
var ReviewWithContext = function () {
|
|
26
|
-
var _a = useReviewContext(), fields = _a.reviewFields, initialDataSet = _a.reviewInitialDataSet, options = _a.options, onValidateRecord = _a.onValidateRecord, onDataSetChanged = _a.onDataSetChanged, onValidationStateChanged = _a.onValidationStateChanged;
|
|
26
|
+
var _a = useReviewContext(), fields = _a.reviewFields, initialDataSet = _a.reviewInitialDataSet, options = _a.options, initialDataSetUpdatedAt = _a.initialDataSetUpdatedAt, onValidateRecord = _a.onValidateRecord, onDataSetChanged = _a.onDataSetChanged, onValidationStateChanged = _a.onValidationStateChanged;
|
|
27
27
|
var _b = useImporterContext(), selectedRows = _b.selectedRows, setSelectedRows = _b.setSelectedRows, isUsingManualImport = _b.isUsingManualImport;
|
|
28
28
|
var t = useTranslation("review").t;
|
|
29
|
-
var spreadsheetUI = initialDataSet && (_jsx(Spreadsheet, { options: __assign(__assign({}, options), { showCheckboxColumn: true }), selectedRows: selectedRows, setSelectedRows: setSelectedRows, initialDataSet: initialDataSet, fields: fields, onDataSetChanged: onDataSetChanged, onValidateRecord: onValidateRecord, onValidationStateChanged: onValidationStateChanged }));
|
|
29
|
+
var spreadsheetUI = initialDataSet && (_jsx(Spreadsheet, { initialDataSetUpdatedAt: initialDataSetUpdatedAt, options: __assign(__assign({}, options), { showCheckboxColumn: true }), selectedRows: selectedRows, setSelectedRows: setSelectedRows, initialDataSet: initialDataSet, fields: fields, onDataSetChanged: onDataSetChanged, onValidateRecord: onValidateRecord, onValidationStateChanged: onValidationStateChanged }));
|
|
30
30
|
return (_jsxs(Div, __assign({ centered: true, flexColumn: true, h100: true }, { children: [_jsx(AppResponseModal, {}), _jsxs(Div, __assign({ w100: true, h100: true, flexColumn: true }, { children: [_jsx(TitleContainer, __assign({ flexColumn: true, ml: 32 }, { children: _jsx(Div, __assign({ h2: true, mt: 40, mb: 40 }, { children: t(isUsingManualImport.current ? "manual_importer_title" : "title") })) })), _jsx(Div, __assign({ h100: true, w100: true, justifyCenter: true }, { children: spreadsheetUI }))] }))] })));
|
|
31
31
|
};
|
|
32
32
|
export default ReviewWithContext;
|
|
@@ -16,7 +16,6 @@ var __assign = (this && this.__assign) || function () {
|
|
|
16
16
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
17
17
|
import { useDropzone } from "react-dropzone";
|
|
18
18
|
import styled, { css } from "styled-components";
|
|
19
|
-
import * as XLSX from "xlsx";
|
|
20
19
|
import { useUploaderContext } from "../UploaderContextProvider";
|
|
21
20
|
import { useImporterContext } from "../../contexts/ImporterContextProvider";
|
|
22
21
|
import { Div } from "../../../styled/utils";
|
|
@@ -25,6 +24,7 @@ import { addToast } from "../../../common/Toast";
|
|
|
25
24
|
import { Button } from "../../../common/buttons";
|
|
26
25
|
import { DragAndDropSvg, UploadIndicatorSvg } from "./backgrounds";
|
|
27
26
|
import { useTranslation } from "react-i18next";
|
|
27
|
+
import Papa from "papaparse";
|
|
28
28
|
var DragAndDropCard = styled(Div)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n border-radius: 8px;\n margin-right: ", ";\n width: 100%;\n height: 100%;\n display: flex;\n background: ", ";\n border: 1px dashed ", ";\n\n @media (max-width: 1050px) {\n padding: 24px;\n width: auto;\n }\n\n ", "\n"], ["\n border-radius: 8px;\n margin-right: ", ";\n width: 100%;\n height: 100%;\n display: flex;\n background: ", ";\n border: 1px dashed ", ";\n\n @media (max-width: 1050px) {\n padding: 24px;\n width: auto;\n }\n\n ", "\n"])), function (props) { return (props.isDragActive ? "-10px" : "revert"); }, theme.colors.white, theme.colors.red50, function (props) {
|
|
29
29
|
return props.isDragActive && css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n background: ", ";\n border: 1px solid ", ";\n justify-content: center;\n "], ["\n background: ", ";\n border: 1px solid ", ";\n justify-content: center;\n "])), function (p) { return p.theme.colors.blue100; }, function (p) { return p.theme.colors.blue500; });
|
|
30
30
|
});
|
|
@@ -63,14 +63,11 @@ var ImporterDropzone = function () {
|
|
|
63
63
|
var _a;
|
|
64
64
|
var results = event.target.result;
|
|
65
65
|
var getDataFromFile = function (fileResults) {
|
|
66
|
-
var
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
var workBookName = workBook.SheetNames[0];
|
|
72
|
-
var sheet = workBook.Sheets[workBookName];
|
|
73
|
-
return XLSX.utils.sheet_to_json(sheet, { header: 1, raw: false });
|
|
66
|
+
var csvString = new TextDecoder().decode(fileResults instanceof ArrayBuffer
|
|
67
|
+
? fileResults
|
|
68
|
+
: new TextEncoder().encode(fileResults));
|
|
69
|
+
var data = Papa.parse(csvString).data;
|
|
70
|
+
return data;
|
|
74
71
|
};
|
|
75
72
|
var fileData = getDataFromFile(results);
|
|
76
73
|
var headersCount = (_a = fileData[0]) === null || _a === void 0 ? void 0 : _a.length;
|
|
@@ -85,7 +82,7 @@ var ImporterDropzone = function () {
|
|
|
85
82
|
var onDropRejected = function (rejectedFiles) {
|
|
86
83
|
var errorMessages = rejectedFiles.map(function (file) {
|
|
87
84
|
if (file.errors[0].code === "file-too-large") {
|
|
88
|
-
return "Maximum file size is
|
|
85
|
+
return "Maximum file size is 200MB";
|
|
89
86
|
}
|
|
90
87
|
else {
|
|
91
88
|
return file.errors[0].message;
|
|
@@ -101,9 +98,9 @@ var ImporterDropzone = function () {
|
|
|
101
98
|
onDropRejected: onDropRejected,
|
|
102
99
|
noClick: true,
|
|
103
100
|
noKeyboard: true,
|
|
104
|
-
accept: ".csv
|
|
101
|
+
accept: ".csv",
|
|
105
102
|
maxFiles: 1,
|
|
106
|
-
maxSize:
|
|
103
|
+
maxSize: 200000000, // 200MB
|
|
107
104
|
}), getRootProps = _b.getRootProps, getInputProps = _b.getInputProps, open = _b.open, isDragActive = _b.isDragActive;
|
|
108
105
|
return (_jsxs(DragAndDropCard, __assign({ isDragActive: isDragActive, centered: true, pRelative: true }, getRootProps(), { children: [_jsx("input", __assign({}, getInputProps())), isDragActive && dropzoneUploadingUI, _jsx(DragAndDropComponent, { openUploadFileDialog: open })] })));
|
|
109
106
|
};
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
var __assign = (this && this.__assign) || function () {
|
|
2
|
-
__assign = Object.assign || function(t) {
|
|
3
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
-
s = arguments[i];
|
|
5
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
-
t[p] = s[p];
|
|
7
|
-
}
|
|
8
|
-
return t;
|
|
9
|
-
};
|
|
10
|
-
return __assign.apply(this, arguments);
|
|
11
|
-
};
|
|
12
1
|
//Filter records by search value
|
|
13
2
|
export var filterRecordsBySearchValue = function (obj, value) {
|
|
14
3
|
var isObject = function (value) {
|
|
@@ -38,6 +27,7 @@ export var filterRecordsBySearchValue = function (obj, value) {
|
|
|
38
27
|
return filteredObj;
|
|
39
28
|
};
|
|
40
29
|
export var filterRecordsByType = function (obj, filterType) {
|
|
30
|
+
var _a, _b;
|
|
41
31
|
var rowIsEmpty = function (row) {
|
|
42
32
|
return Object.keys(row).every(function (key) {
|
|
43
33
|
if (key === "_meta")
|
|
@@ -45,16 +35,15 @@ export var filterRecordsByType = function (obj, filterType) {
|
|
|
45
35
|
return !row[key];
|
|
46
36
|
});
|
|
47
37
|
};
|
|
48
|
-
var
|
|
49
|
-
|
|
50
|
-
|
|
38
|
+
var filteredObj = {};
|
|
39
|
+
for (var key in obj) {
|
|
40
|
+
if (filterType === "all" ||
|
|
51
41
|
(((_b = (_a = obj[key]) === null || _a === void 0 ? void 0 : _a._meta) === null || _b === void 0 ? void 0 : _b.isInvalid) !== (filterType === "valid") &&
|
|
52
|
-
!rowIsEmpty(obj[key]))
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}, {});
|
|
42
|
+
!rowIsEmpty(obj[key]))) {
|
|
43
|
+
filteredObj[key] = obj[key];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return filteredObj;
|
|
58
47
|
};
|
|
59
48
|
//Filter records by selected column error
|
|
60
49
|
export var filterRecordsByError = function (obj, keyToFilter, errors) {
|
|
@@ -66,7 +66,11 @@ export var SpreadsheetContextProvider = function (_a) {
|
|
|
66
66
|
}), updateRecordAndRevalidate = _k.updateRecordAndRevalidate, deleteRecords = _k.deleteRecords, warnings = _k.warnings, errors = _k.errors, validationState = __rest(_k, ["updateRecordAndRevalidate", "deleteRecords", "warnings", "errors"]);
|
|
67
67
|
var addNewRowsToSpreadsheet = function () {
|
|
68
68
|
addRowTimeoutRef.current = setTimeout(function () {
|
|
69
|
-
var
|
|
69
|
+
var _a, _b;
|
|
70
|
+
var highestRowIndex = -1;
|
|
71
|
+
for (var key in dataSet)
|
|
72
|
+
if (((_b = (_a = dataSet[key]) === null || _a === void 0 ? void 0 : _a._meta) === null || _b === void 0 ? void 0 : _b.rowIndex) > highestRowIndex)
|
|
73
|
+
highestRowIndex = dataSet[key]._meta.rowIndex;
|
|
70
74
|
var newRow = addMeta({}, highestRowIndex + 1);
|
|
71
75
|
setDataSet(function (oldValues) {
|
|
72
76
|
var _a;
|
|
@@ -132,6 +136,10 @@ export var SpreadsheetContextProvider = function (_a) {
|
|
|
132
136
|
addNewRowsToSpreadsheet();
|
|
133
137
|
}
|
|
134
138
|
}, [dataSet]);
|
|
139
|
+
// Review this later, this probably isn't the best approach
|
|
140
|
+
useEffect(function () {
|
|
141
|
+
setDataSet(initialDataSet);
|
|
142
|
+
}, [initialDataSet]);
|
|
135
143
|
useEffect(function () {
|
|
136
144
|
onValidationStateChanged &&
|
|
137
145
|
onValidationStateChanged(__assign(__assign({}, validationState), { errors: errors, warnings: warnings }));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { SpreadsheetOptions } from "../../..";
|
|
3
|
-
import { BatchValidationErrors, Field, OnValidateRecord, Record, RecordDataSet } from "../../../types";
|
|
4
3
|
import { DeleteRecords } from "../../../common/Table/TableActions/hooks";
|
|
4
|
+
import { BatchValidationErrors, Field, OnValidateRecord, Record, RecordDataSet } from "../../../types";
|
|
5
5
|
type UseValidationStateArgs = {
|
|
6
6
|
onValidateRecord?: OnValidateRecord;
|
|
7
7
|
setDataSet: React.Dispatch<React.SetStateAction<RecordDataSet>>;
|
|
@@ -46,10 +46,10 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
46
46
|
}
|
|
47
47
|
};
|
|
48
48
|
import { omit, set } from "lodash";
|
|
49
|
-
import { useCallback, useEffect, useMemo, useState
|
|
50
|
-
import { sleep } from "../../..";
|
|
51
|
-
import { selectValidatorsFor, validateRecord } from "./validation";
|
|
49
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
52
50
|
import { useTableActions, } from "../../../common/Table/TableActions/hooks";
|
|
51
|
+
import { selectValidatorsFor, validateRecord } from "./validation";
|
|
52
|
+
import { useAppLoadingContext } from "../../../common/AppLoadingContextProvider";
|
|
53
53
|
var checkIfHasErrors = function (errors) {
|
|
54
54
|
return errors && Object.keys(errors).length > 0;
|
|
55
55
|
};
|
|
@@ -61,6 +61,7 @@ export var useValidationState = function (_a) {
|
|
|
61
61
|
var _c = useState({}), warnings = _c[0], setWarnings = _c[1];
|
|
62
62
|
var _d = useState(0), validationPercentage = _d[0], setValidationPercentage = _d[1];
|
|
63
63
|
var validatorsCache = useMemo(function () { return selectValidatorsFor(fields); }, [fields]);
|
|
64
|
+
var setIsLoadingApp = useAppLoadingContext().setIsLoadingApp;
|
|
64
65
|
var deleteRecords = useTableActions({
|
|
65
66
|
setDataSet: setDataSet,
|
|
66
67
|
setErrors: setErrors,
|
|
@@ -112,7 +113,7 @@ export var useValidationState = function (_a) {
|
|
|
112
113
|
}); }, [dataSet, validatorsCache]);
|
|
113
114
|
// Initial data validation and update dataSet
|
|
114
115
|
useEffect(function () {
|
|
115
|
-
if (isReadOnly)
|
|
116
|
+
if (!initialDataSet || isReadOnly)
|
|
116
117
|
return;
|
|
117
118
|
var isCancelled = false;
|
|
118
119
|
setIsLoading(true);
|
|
@@ -125,7 +126,7 @@ export var useValidationState = function (_a) {
|
|
|
125
126
|
warnings = {};
|
|
126
127
|
initialData = Object.values(initialDataSet);
|
|
127
128
|
length = initialData.length;
|
|
128
|
-
_a = options.batchValidationDelayMs, batchValidationDelayMs = _a === void 0 ? 400 : _a, _b = options.batchValidationSize, batchValidationSize = _b === void 0 ?
|
|
129
|
+
_a = options.batchValidationDelayMs, batchValidationDelayMs = _a === void 0 ? 400 : _a, _b = options.batchValidationSize, batchValidationSize = _b === void 0 ? length : _b;
|
|
129
130
|
batchSize = Math.min(Math.floor(batchValidationSize), length) || length;
|
|
130
131
|
batchCount = Math.ceil(length / batchSize);
|
|
131
132
|
batchIdx = 0;
|
|
@@ -182,10 +183,29 @@ export var useValidationState = function (_a) {
|
|
|
182
183
|
}
|
|
183
184
|
});
|
|
184
185
|
}); };
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
186
|
+
var sleep = function (n) { return new Promise(function (resolve) { return setTimeout(resolve, n); }); };
|
|
187
|
+
(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
188
|
+
return __generator(this, function (_a) {
|
|
189
|
+
switch (_a.label) {
|
|
190
|
+
case 0:
|
|
191
|
+
setIsLoadingApp(true);
|
|
192
|
+
if (!(Object.values(initialDataSet).length > 10000)) return [3 /*break*/, 2];
|
|
193
|
+
// wait for the first render to complete before blocking main thread with review step logic
|
|
194
|
+
return [4 /*yield*/, sleep(200)];
|
|
195
|
+
case 1:
|
|
196
|
+
// wait for the first render to complete before blocking main thread with review step logic
|
|
197
|
+
_a.sent();
|
|
198
|
+
_a.label = 2;
|
|
199
|
+
case 2: return [4 /*yield*/, initialValidation()];
|
|
200
|
+
case 3:
|
|
201
|
+
_a.sent();
|
|
202
|
+
if (!isCancelled)
|
|
203
|
+
setIsLoading(false);
|
|
204
|
+
setIsLoadingApp(false);
|
|
205
|
+
return [2 /*return*/];
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}); })();
|
|
189
209
|
return function () {
|
|
190
210
|
isCancelled = true;
|
|
191
211
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { SpreadsheetProps } from "./common/types";
|
|
3
|
-
declare const _default: React.MemoExoticComponent<({ initialDataSet, ...props }: SpreadsheetProps) => JSX.Element>;
|
|
3
|
+
declare const _default: React.MemoExoticComponent<({ initialDataSet, initialDataSetUpdatedAt, ...props }: SpreadsheetProps) => JSX.Element>;
|
|
4
4
|
export default _default;
|
|
5
5
|
export * from "./SpreadsheetContextProvider";
|
|
6
6
|
export * from "./hooks";
|
|
@@ -20,10 +20,10 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
20
20
|
}
|
|
21
21
|
return t;
|
|
22
22
|
};
|
|
23
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
23
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
24
24
|
import { get } from "lodash";
|
|
25
25
|
import { DateTime } from "luxon";
|
|
26
|
-
import React
|
|
26
|
+
import React from "react";
|
|
27
27
|
import { areEqual } from "react-window";
|
|
28
28
|
import { useImporterContext } from "../../contexts/ImporterContextProvider";
|
|
29
29
|
import { SpreadsheetContextProvider } from "./SpreadsheetContextProvider";
|
|
@@ -107,14 +107,8 @@ var useFieldSorting = function () {
|
|
|
107
107
|
return { getDefaultSortCompareFn: getDefaultSortCompareFn };
|
|
108
108
|
};
|
|
109
109
|
var SpreadsheetWrapper = function (_a) {
|
|
110
|
-
var initialDataSet = _a.initialDataSet, props = __rest(_a, ["initialDataSet"]);
|
|
111
|
-
|
|
112
|
-
useEffect(function () {
|
|
113
|
-
/* increment the key to force a re-mount of the Spreadsheet component
|
|
114
|
-
when the initialDataSet changes */
|
|
115
|
-
setKey(key + 1);
|
|
116
|
-
}, [initialDataSet]);
|
|
117
|
-
return _jsx(Spreadsheet, __assign({ initialDataSet: initialDataSet }, props), key);
|
|
110
|
+
var initialDataSet = _a.initialDataSet, initialDataSetUpdatedAt = _a.initialDataSetUpdatedAt, props = __rest(_a, ["initialDataSet", "initialDataSetUpdatedAt"]);
|
|
111
|
+
return (_jsx(_Fragment, { children: initialDataSet && (_jsx(Spreadsheet, __assign({ initialDataSet: initialDataSet }, props), initialDataSetUpdatedAt || 0)) }));
|
|
118
112
|
};
|
|
119
113
|
var Spreadsheet = function (props) {
|
|
120
114
|
var getDefaultSortCompareFn = useFieldSorting().getDefaultSortCompareFn;
|
|
@@ -54,7 +54,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
54
54
|
}
|
|
55
55
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
56
56
|
};
|
|
57
|
-
import { ignoreNullOrUndefinedKeyValues, isNullOrUndefined, isRecordEmpty, } from "../common";
|
|
57
|
+
import { ignoreNullOrUndefinedKeyValues, isEmpty, isNullOrUndefined, isRecordEmpty, } from "../common";
|
|
58
58
|
import { fieldValidations } from "./validators";
|
|
59
59
|
var datePatternTypes = ["date", "datetime", "time"];
|
|
60
60
|
function safeCallOnValidateRecord(_a) {
|
|
@@ -98,11 +98,17 @@ function safeCallValidator(_a) {
|
|
|
98
98
|
return "".concat(e);
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
|
+
function mergeErrorsAndWarnings(currentErrors, errors) {
|
|
102
|
+
return __assign(__assign({}, currentErrors), { errors: __assign(__assign({}, (currentErrors.errors || {})), errors), warnings: __assign({}, (currentErrors.warnings || {})) });
|
|
103
|
+
}
|
|
101
104
|
function runValidatorsFor(_a) {
|
|
102
105
|
var record = _a.record, data = _a.data, validators = _a.validators;
|
|
103
106
|
return validators.reduce(function (currentErrors, _a) {
|
|
104
107
|
var field = _a.field, validators = _a.validators;
|
|
105
108
|
var errors = {};
|
|
109
|
+
if (!field.isRequired && isEmpty(record[field.name])) {
|
|
110
|
+
return mergeErrorsAndWarnings(currentErrors, errors);
|
|
111
|
+
}
|
|
106
112
|
for (var index = 0; index < validators.length; index++) {
|
|
107
113
|
var _b = validators[index], validator = _b.validator, validatorFunction = _b.validatorFunction;
|
|
108
114
|
var error = safeCallValidator({
|
|
@@ -117,7 +123,7 @@ function runValidatorsFor(_a) {
|
|
|
117
123
|
break;
|
|
118
124
|
}
|
|
119
125
|
}
|
|
120
|
-
return
|
|
126
|
+
return mergeErrorsAndWarnings(currentErrors, errors);
|
|
121
127
|
}, {});
|
|
122
128
|
}
|
|
123
129
|
export function selectValidatorsFor(fields) {
|
|
@@ -89,7 +89,9 @@ export var transformToRecords = function (_a) {
|
|
|
89
89
|
};
|
|
90
90
|
export var getPreviewDataSet = function (_a) {
|
|
91
91
|
var uploadedData = _a.uploadedData;
|
|
92
|
-
var rowLen =
|
|
92
|
+
var rowLen = 0;
|
|
93
|
+
for (var i = 0; i < uploadedData.length; i++)
|
|
94
|
+
rowLen = Math.max(rowLen, uploadedData[i].length);
|
|
93
95
|
var fields = new Array(rowLen).fill(null).map(function (_, i) {
|
|
94
96
|
var key = String.fromCharCode(65 + i);
|
|
95
97
|
return {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const AppLoadingUI: () => JSX.Element;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
|
|
2
|
+
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
|
|
3
|
+
return cooked;
|
|
4
|
+
};
|
|
5
|
+
var __assign = (this && this.__assign) || function () {
|
|
6
|
+
__assign = Object.assign || function(t) {
|
|
7
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
8
|
+
s = arguments[i];
|
|
9
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
10
|
+
t[p] = s[p];
|
|
11
|
+
}
|
|
12
|
+
return t;
|
|
13
|
+
};
|
|
14
|
+
return __assign.apply(this, arguments);
|
|
15
|
+
};
|
|
16
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
17
|
+
import styled from "styled-components";
|
|
18
|
+
import { Div } from "../../styled/utils";
|
|
19
|
+
import { Spinner } from "../Spinner";
|
|
20
|
+
var LoadingBackdrop = styled(Div)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n position: fixed;\n top: 0px;\n left: 0px;\n margin: 0px;\n width: 100vw;\n height: 100vh;\n z-index: 99999999;\n background: ", ";\n opacity: 0.2;\n"], ["\n position: fixed;\n top: 0px;\n left: 0px;\n margin: 0px;\n width: 100vw;\n height: 100vh;\n z-index: 99999999;\n background: ", ";\n opacity: 0.2;\n"])), function (props) { return props.theme.colors.gray200; });
|
|
21
|
+
var ModalContainer = styled(Div)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n top: 0px;\n left: 0px;\n margin: 0px;\n position: fixed;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000000000;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n div {\n pointer-events: auto;\n }\n"], ["\n top: 0px;\n left: 0px;\n margin: 0px;\n position: fixed;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000000000;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n div {\n pointer-events: auto;\n }\n"])));
|
|
22
|
+
var LoaderContainer = styled(ModalContainer)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n pointer-events: none;\n"], ["\n pointer-events: none;\n"])));
|
|
23
|
+
export var AppLoadingUI = function () {
|
|
24
|
+
return (_jsxs(_Fragment, { children: [_jsx(LoadingBackdrop, {}), _jsx(LoaderContainer, { children: _jsx(Div, __assign({ w: 300 }, { children: _jsx(Div, __assign({ pRelative: true }, { children: _jsx(Spinner, {}) })) })) })] }));
|
|
25
|
+
};
|
|
26
|
+
var templateObject_1, templateObject_2, templateObject_3;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export type State = {
|
|
3
|
+
isLoadingApp: boolean;
|
|
4
|
+
setIsLoadingApp: React.Dispatch<React.SetStateAction<boolean>>;
|
|
5
|
+
};
|
|
6
|
+
export declare const AppLoadingContext: React.Context<State>;
|
|
7
|
+
export declare const AppLoadingContextProvider: ({ children }: {
|
|
8
|
+
children: any;
|
|
9
|
+
}) => JSX.Element;
|
|
10
|
+
export declare const useAppLoadingContext: () => State;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
import { createContext, useContext, useState } from "react";
|
|
14
|
+
import { AppLoadingUI } from "./AppLoadingUI";
|
|
15
|
+
export var AppLoadingContext = createContext({});
|
|
16
|
+
export var AppLoadingContextProvider = function (_a) {
|
|
17
|
+
var children = _a.children;
|
|
18
|
+
var _b = useState(false), isLoadingApp = _b[0], setIsLoadingApp = _b[1];
|
|
19
|
+
var value = {
|
|
20
|
+
isLoadingApp: isLoadingApp,
|
|
21
|
+
setIsLoadingApp: setIsLoadingApp,
|
|
22
|
+
};
|
|
23
|
+
return (_jsxs(AppLoadingContext.Provider, __assign({ value: value }, { children: [isLoadingApp && _jsx(AppLoadingUI, {}), children] })));
|
|
24
|
+
};
|
|
25
|
+
export var useAppLoadingContext = function () { return useContext(AppLoadingContext); };
|
package/lib/esm/index.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ declare class FuseImporter {
|
|
|
16
16
|
private windowScrollPosition;
|
|
17
17
|
close(): void;
|
|
18
18
|
show(): Promise<void>;
|
|
19
|
-
addColumn<T extends FieldTypesAsUnion>(
|
|
19
|
+
addColumn<T extends FieldTypesAsUnion>(columnData: ColumnRequiredProps<T>): void;
|
|
20
20
|
private renderImporterComponent;
|
|
21
21
|
private createDivComponent;
|
|
22
22
|
private createIframe;
|