fuse-importer 0.23.2 → 0.23.5
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/README.md +13 -14
- package/lib/esm/Importer/FuseApi.js +1 -1
- package/lib/esm/Importer/ImporterContextProvider.d.ts +2 -0
- package/lib/esm/Importer/ImporterContextProvider.js +4 -1
- package/lib/esm/Importer/Review/index.js +1 -1
- package/lib/esm/Importer/SpreadsheetReviewContextProvider.d.ts +2 -1
- package/lib/esm/Importer/SpreadsheetReviewContextProvider.js +20 -9
- package/lib/esm/Importer/Stepper.js +4 -2
- package/lib/esm/Importer/Uploader/DragAndDropImporter/ImporterDropzone.js +1 -1
- package/lib/esm/Importer/Uploader/HeadersPreview.js +1 -1
- package/lib/esm/Importer/common/Spreadsheet/SpreadsheetContextProvider.d.ts +1 -0
- package/lib/esm/Importer/common/Spreadsheet/SpreadsheetContextProvider.js +81 -61
- package/lib/esm/Importer/common/Spreadsheet/SpreadsheetRowNumbers.d.ts +3 -3
- package/lib/esm/Importer/common/Spreadsheet/SpreadsheetRowNumbers.js +10 -10
- package/lib/esm/Importer/common/Spreadsheet/common/fields/index.d.ts +2 -2
- package/lib/esm/Importer/common/Spreadsheet/common/fields/index.js +32 -47
- package/lib/esm/Importer/common/Spreadsheet/common/index.js +1 -1
- package/lib/esm/Importer/common/Spreadsheet/index.js +18 -57
- package/lib/esm/Importer/index.js +2 -2
- package/lib/esm/api/index.d.ts +1 -0
- package/lib/esm/api/index.js +3 -3
- package/lib/esm/common/Modal.d.ts +7 -4
- package/lib/esm/common/Modal.js +2 -2
- package/lib/esm/common/Table/TableDataProvider.js +24 -23
- package/lib/esm/common/Table/TableView/TableHeaders.d.ts +3 -2
- package/lib/esm/common/Table/TableView/TableHeaders.js +1 -5
- package/lib/esm/common/Table/TableView/TableRow.d.ts +2 -2
- package/lib/esm/common/Table/TableView/TableRow.js +7 -10
- package/lib/esm/common/Table/TableView/index.d.ts +1 -2
- package/lib/esm/common/Table/TableView/index.js +52 -45
- package/lib/esm/common/TooltipProvider.d.ts +1 -0
- package/lib/esm/common/TooltipProvider.js +7 -7
- package/lib/esm/common/buttons.js +2 -2
- package/lib/esm/common/index.d.ts +1 -1
- package/lib/esm/common/index.js +2 -2
- package/lib/esm/common/inputs/Autocomplete.js +8 -4
- package/lib/esm/common/inputs/TextInput.d.ts +2 -1
- package/lib/esm/common/inputs/TextInput.js +3 -2
- package/lib/esm/styled/utils.d.ts +3 -0
- package/lib/esm/styled/utils.js +4 -2
- package/lib/esm/types.d.ts +11 -7
- package/lib/esm/utils/index.d.ts +1 -0
- package/lib/esm/utils/index.js +3 -0
- package/lib/main.js +1 -1
- package/lib/main.js.LICENSE.txt +9 -0
- package/package.json +15 -13
package/README.md
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
<div>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
</p>
|
|
2
|
+
<center>
|
|
3
|
+
<a href="https://fuse.flatironsdevelopment.com/users/sign-up?utm_source=npmjs&utm_medium=Fuse+importer+logo&utm_campaign=NPM">
|
|
4
|
+
<img alt="Flatirons Fuse" src="https://wp.flatironsdevelopment.com/wp-content/uploads/2022/07/fuse-logo.png">
|
|
5
|
+
</a>
|
|
6
|
+
</center>
|
|
7
|
+
<br>
|
|
8
|
+
<br>
|
|
9
|
+
<p>
|
|
10
|
+
Flatirons Fuse is a customizable and powerful CSV Importer that works with all front-end languages.
|
|
11
|
+
</p>
|
|
13
12
|
</div>
|
|
14
13
|
|
|
15
14
|
## Table of Contents
|
|
@@ -69,11 +68,11 @@ For more information see our [full documentation.](https://fuse-docs.flatironsde
|
|
|
69
68
|
|
|
70
69
|
Check it out in action:
|
|
71
70
|
|
|
71
|
+
<div>
|
|
72
72
|
<center>
|
|
73
|
-
|
|
74
|
-
<img src="https://wp.flatironsdevelopment.com/wp-content/uploads/2022/07/Flatirons-Fuse-users-Columns-7-July-2022.gif">
|
|
75
|
-
</a>
|
|
73
|
+
<img alt="Check it out in action" src="https://wp.flatironsdevelopment.com/wp-content/uploads/2022/07/ezgif-1-242e10926e.gif">
|
|
76
74
|
</center>
|
|
75
|
+
</div>
|
|
77
76
|
|
|
78
77
|
## Registration
|
|
79
78
|
|
|
@@ -12,7 +12,7 @@ var __assign = (this && this.__assign) || function () {
|
|
|
12
12
|
import { api } from "../api";
|
|
13
13
|
import { baseUrls } from "./common/index";
|
|
14
14
|
// copies the axios request config from axios.AxiosInstance type and adds
|
|
15
|
-
// baseUrl based on environment and api
|
|
15
|
+
// baseUrl based on environment and api key
|
|
16
16
|
var FuseApi = /** @class */ (function () {
|
|
17
17
|
function FuseApi(environment, apiToken) {
|
|
18
18
|
this.environment = environment;
|
|
@@ -72,6 +72,7 @@ export var ImporterContextProvider = function (_a) {
|
|
|
72
72
|
var _j = useState(null), templateHeaderMatchings = _j[0], setTemplateHeaderMatchings = _j[1];
|
|
73
73
|
var _k = useState(null), enumFieldValueMatchings = _k[0], setEnumFieldValueMatchings = _k[1];
|
|
74
74
|
var _l = useState(null), uploadedDataEnumFieldValues = _l[0], setUploadedDataEnumFieldValues = _l[1];
|
|
75
|
+
var _m = useState(false), isSpreadsheetValid = _m[0], setIsSpreadsheetValid = _m[1];
|
|
75
76
|
var fuseApi = useMemo(function () { return new FuseApi(options.env, apiToken); }, [
|
|
76
77
|
options.env,
|
|
77
78
|
apiToken,
|
|
@@ -130,7 +131,7 @@ export var ImporterContextProvider = function (_a) {
|
|
|
130
131
|
case 2:
|
|
131
132
|
error_1 = _d.sent();
|
|
132
133
|
errorMsg = ((_c = (_b = error_1.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.message) ||
|
|
133
|
-
"There was an error preventing the data importer from loading. Check your API
|
|
134
|
+
"There was an error preventing the data importer from loading. Check your API Key and try again.";
|
|
134
135
|
setTemplateError(errorMsg);
|
|
135
136
|
return [3 /*break*/, 3];
|
|
136
137
|
case 3: return [2 /*return*/];
|
|
@@ -180,6 +181,8 @@ export var ImporterContextProvider = function (_a) {
|
|
|
180
181
|
fuseApi: fuseApi,
|
|
181
182
|
theme: style.theme,
|
|
182
183
|
logoURL: style.logoURL,
|
|
184
|
+
isSpreadsheetValid: isSpreadsheetValid,
|
|
185
|
+
setIsSpreadsheetValid: setIsSpreadsheetValid,
|
|
183
186
|
};
|
|
184
187
|
return (_jsx(ImporterContext.Provider, __assign({ value: value }, { children: children })));
|
|
185
188
|
};
|
|
@@ -76,7 +76,7 @@ var Review = function () {
|
|
|
76
76
|
}, [templateHeaders]);
|
|
77
77
|
var spreadsheetUI = useMemo(function () { return (_jsx(Div, { children: _jsx(Spreadsheet, __assign({ rowWidth: getSpreadsheetRowWidth(fields, 6), options: {
|
|
78
78
|
batchValidationDelayMs: batchValidationDelayMs,
|
|
79
|
-
batchValidationSize: batchValidationSize
|
|
79
|
+
batchValidationSize: batchValidationSize,
|
|
80
80
|
} }, {
|
|
81
81
|
submittedData: submittedData,
|
|
82
82
|
appResponse: appResponse,
|
|
@@ -13,7 +13,8 @@ declare type State = {
|
|
|
13
13
|
declare type Props = {
|
|
14
14
|
onSubmit?: OnSubmit;
|
|
15
15
|
children: JSX.Element;
|
|
16
|
+
loadingComponent?: () => JSX.Element;
|
|
16
17
|
};
|
|
17
|
-
export declare const SpreadsheetReviewContextProvider: ({ children, onSubmit, }: Props) => JSX.Element;
|
|
18
|
+
export declare const SpreadsheetReviewContextProvider: ({ children, onSubmit, loadingComponent, }: Props) => JSX.Element;
|
|
18
19
|
export declare const useSpreadsheetReviewContext: () => State;
|
|
19
20
|
export {};
|
|
@@ -52,7 +52,7 @@ import { getUnsubmittedData } from "./common/utils";
|
|
|
52
52
|
import { useImporterContext } from "./ImporterContextProvider";
|
|
53
53
|
var SpreadsheetReviewContext = createContext({});
|
|
54
54
|
export var SpreadsheetReviewContextProvider = function (_a) {
|
|
55
|
-
var children = _a.children, onSubmit = _a.onSubmit;
|
|
55
|
+
var children = _a.children, onSubmit = _a.onSubmit, loadingComponent = _a.loadingComponent;
|
|
56
56
|
var _b = useState(false), isSubmitting = _b[0], setIsSubmitting = _b[1];
|
|
57
57
|
var _c = useState(null), reviewedData = _c[0], setReviewedData = _c[1];
|
|
58
58
|
var _d = useState(null), submittedData = _d[0], setSubmittedData = _d[1];
|
|
@@ -67,14 +67,25 @@ export var SpreadsheetReviewContextProvider = function (_a) {
|
|
|
67
67
|
switch (_a.label) {
|
|
68
68
|
case 0:
|
|
69
69
|
trackImportedRowsCount = function (rowCount) { return __awaiter(void 0, void 0, void 0, function () {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
70
|
+
var error_1, errorMessage;
|
|
71
|
+
var _a, _b;
|
|
72
|
+
return __generator(this, function (_c) {
|
|
73
|
+
switch (_c.label) {
|
|
74
|
+
case 0:
|
|
75
|
+
_c.trys.push([0, 2, , 3]);
|
|
76
|
+
return [4 /*yield*/, fuseApi.post("/api/v1/importer/templates/".concat(templateSlug, "/imports"), {
|
|
77
|
+
row_count: rowCount,
|
|
78
|
+
})];
|
|
75
79
|
case 1:
|
|
76
|
-
|
|
77
|
-
return [
|
|
80
|
+
_c.sent();
|
|
81
|
+
return [3 /*break*/, 3];
|
|
82
|
+
case 2:
|
|
83
|
+
error_1 = _c.sent();
|
|
84
|
+
errorMessage = ((_b = (_a = error_1 === null || error_1 === void 0 ? void 0 : error_1.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error) ||
|
|
85
|
+
"There was an error submitting your dataset";
|
|
86
|
+
setAppResponse({ message: errorMessage });
|
|
87
|
+
return [3 /*break*/, 3];
|
|
88
|
+
case 3: return [2 /*return*/];
|
|
78
89
|
}
|
|
79
90
|
});
|
|
80
91
|
}); };
|
|
@@ -110,7 +121,7 @@ export var SpreadsheetReviewContextProvider = function (_a) {
|
|
|
110
121
|
onSubmit: onSubmitData,
|
|
111
122
|
setReviewedData: setReviewedData,
|
|
112
123
|
};
|
|
113
|
-
return (_jsxs(SpreadsheetReviewContext.Provider, __assign({ value: value }, { children: [isSubmitting
|
|
124
|
+
return (_jsxs(SpreadsheetReviewContext.Provider, __assign({ value: value }, { children: [isSubmitting ? (loadingComponent ? (loadingComponent()) : (_jsx(AppLoading, {}))) : null, children] })));
|
|
114
125
|
};
|
|
115
126
|
export var useSpreadsheetReviewContext = function () {
|
|
116
127
|
return useContext(SpreadsheetReviewContext);
|
|
@@ -66,7 +66,9 @@ var Stepper = function (_a) {
|
|
|
66
66
|
var _b = useState(false), isUnmatchedHeadersModalOpen = _b[0], setIsUnmatchedHeadersModalOpen = _b[1];
|
|
67
67
|
var _c = useSpreadsheetReviewContext(), appResponse = _c.appResponse, isSpreadsheetReviewComplete = _c.isSpreadsheetReviewComplete, onSubmit = _c.onSubmit;
|
|
68
68
|
var _d = useState(false), isSubmitModalOpen = _d[0], setIsSubmitModalOpen = _d[1];
|
|
69
|
-
var _e = useImporterContext(), currentStepIndex = _e.currentStepIndex, setEnumFieldValueMatchings = _e.setEnumFieldValueMatchings, setCurrentStepIndex = _e.setCurrentStepIndex, templateHeaderMatchings = _e.templateHeaderMatchings, matcherSubstep = _e.matcherSubstep, setMatcherSubstep = _e.setMatcherSubstep, templateHeaders = _e.templateHeaders, uploadedDataEnumFieldValues = _e.uploadedDataEnumFieldValues, onClose = _e.onClose;
|
|
69
|
+
var _e = useImporterContext(), currentStepIndex = _e.currentStepIndex, setEnumFieldValueMatchings = _e.setEnumFieldValueMatchings, setCurrentStepIndex = _e.setCurrentStepIndex, templateHeaderMatchings = _e.templateHeaderMatchings, matcherSubstep = _e.matcherSubstep, setMatcherSubstep = _e.setMatcherSubstep, templateHeaders = _e.templateHeaders, uploadedDataEnumFieldValues = _e.uploadedDataEnumFieldValues, onClose = _e.onClose, isSpreadsheetValid = _e.isSpreadsheetValid, disableSubmitIfInvalid = _e.importerOptions.disableSubmitIfInvalid;
|
|
70
|
+
var isSubmitDisabled = (disableSubmitIfInvalid && !isSpreadsheetValid) ||
|
|
71
|
+
!isSpreadsheetReviewComplete;
|
|
70
72
|
var submitModalUI = (_jsx(Modal, __assign({ isOpen: isSubmitModalOpen, onClose: function () { return setIsSubmitModalOpen(false); } }, { children: _jsxs(Div, __assign({ centered: true, flexColumn: true, p: 60 }, { children: [_jsx(Div, { children: submitSvg }), _jsx(Div, __assign({ h5: true, mt: 20 }, { children: "Ready to submit?" })), _jsx(Div, __assign({ body1: true, mt: 12, w: 448, textAlignCenter: true }, { children: "We didn't find anything wrong with your file. You're good to go!" })), _jsxs(Div, __assign({ dflex: true, mt: 40, w100: true, centered: true }, { children: [_jsx(Button, __assign({ w: 115, variant: "secondary", mr: 10, onClick: function () { return setIsSubmitModalOpen(false); } }, { children: "Go back" })), _jsx(Button, __assign({ w: 140, ml: 10, onClick: function () {
|
|
71
73
|
onSubmit();
|
|
72
74
|
setIsSubmitModalOpen(false);
|
|
@@ -130,7 +132,7 @@ var Stepper = function (_a) {
|
|
|
130
132
|
var isMatchStep = currentStepIndex === 1;
|
|
131
133
|
var isReviewStep = currentStepIndex === 2;
|
|
132
134
|
var leftButtonUI = (_jsx(Div, __assign({ w: 100 }, { children: currentStepIndex > 0 && !appResponse && (_jsx(Button, __assign({ variant: "secondary", onClick: goBack }, { children: "Go back" }))) })));
|
|
133
|
-
var rightButtonUI = (_jsxs(Div, __assign({ w: 100 }, { children: [isMatchStep && (_jsx(Button, __assign({ variant: "primary", onClick: continueToNextStep }, { children: "Continue" }))), isReviewStep && (_jsx(Button, __assign({ variant: "primary", isDisabled:
|
|
135
|
+
var rightButtonUI = (_jsxs(Div, __assign({ w: 100 }, { children: [isMatchStep && (_jsx(Button, __assign({ variant: "primary", onClick: continueToNextStep }, { children: "Continue" }))), isReviewStep && (_jsx(Button, __assign({ variant: "primary", isDisabled: isSubmitDisabled, onClick: function () { return setIsSubmitModalOpen(true); } }, { children: "Submit" })))] })));
|
|
134
136
|
return (_jsxs(_Fragment, { children: [unmatchedHeadersModalUI, submitModalUI, _jsxs(StepperWrapper, __assign({ pRelative: true, alignCenter: true, w100: true, h: 96, centered: true }, { children: [logoURL && _jsx(Logo, { src: logoURL, alt: "" }), _jsxs(Content, __assign({ spaceBetween: true, w: contentWidth }, { children: [leftButtonUI, _jsx(Div, __assign({ alignCenter: true }, { children: stepsUI })), rightButtonUI] })), _jsx(CloseIcon, __assign({ centered: true, clickable: true, onClick: onClose }, { children: closeIconCondensed }))] }))] }));
|
|
135
137
|
};
|
|
136
138
|
var Content = styled(Div)(function (_a) {
|
|
@@ -42,7 +42,7 @@ var ImporterDropzone = function () {
|
|
|
42
42
|
var _a = useUploaderContext(), setIsUploading = _a.setIsUploading, setFileName = _a.setFileName;
|
|
43
43
|
var setUploadedData = useImporterContext().setUploadedData;
|
|
44
44
|
var validHeadersCount = function (headersLength) {
|
|
45
|
-
var headersCountLimit =
|
|
45
|
+
var headersCountLimit = 60;
|
|
46
46
|
if (headersLength > headersCountLimit) {
|
|
47
47
|
addToast("File cannot contain more than ".concat(headersCountLimit, " columns"), "error");
|
|
48
48
|
return false;
|
|
@@ -74,7 +74,7 @@ var HeadersPreview = function () {
|
|
|
74
74
|
};
|
|
75
75
|
});
|
|
76
76
|
}, []);
|
|
77
|
-
return (_jsx(_Fragment, { children: _jsxs(Div, __assign({ flexColumn: true, centered: true, pt: 40 }, { children: [_jsx(Div, __assign({ h2: true, mb: 16 }, { children: "Verify Your Column Headers" })), _jsx(Div, __assign({ body1: true, mb: 24, textAlignCenter: true }, { children: "File must contain column headers to proceed." })), _jsx(HeaderButtons, {}), _jsx(Div, __assign({ w100: true, centered: true, mb: 36 }, { children: _jsx(Spreadsheet,
|
|
77
|
+
return (_jsx(_Fragment, { children: _jsxs(Div, __assign({ flexColumn: true, centered: true, pt: 40 }, { children: [_jsx(Div, __assign({ h2: true, mb: 16 }, { children: "Verify Your Column Headers" })), _jsx(Div, __assign({ body1: true, mb: 24, textAlignCenter: true }, { children: "File must contain column headers to proceed." })), _jsx(HeaderButtons, {}), _jsx(Div, __assign({ w100: true, centered: true, mb: 36 }, { children: _jsx(Spreadsheet, { rowWidth: getSpreadsheetRowWidth(readonlyFields, 6), isReadOnly: true, initialData: formattedData, fields: readonlyFields, highlightFirstRow: true }) }))] })) }));
|
|
78
78
|
};
|
|
79
79
|
export default HeadersPreview;
|
|
80
80
|
var templateObject_1;
|
|
@@ -4,6 +4,7 @@ import { BatchValidationErrors, Field, OnValidateBatch, OnValidateRecord, Record
|
|
|
4
4
|
export declare const getBatchErrors: (records: Record[], onValidateRecord: OnValidateRecord) => Promise<BatchValidationErrors>;
|
|
5
5
|
declare type State = {
|
|
6
6
|
rowWidth?: number;
|
|
7
|
+
dataRef: React.MutableRefObject<Record[]>;
|
|
7
8
|
data: Record[];
|
|
8
9
|
fields: Field[];
|
|
9
10
|
isLoading: boolean;
|
|
@@ -55,9 +55,11 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
55
55
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
56
56
|
};
|
|
57
57
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
58
|
-
import { createContext, useContext, useEffect, useState, useMemo, } from "react";
|
|
58
|
+
import { createContext, useContext, useEffect, useState, useMemo, useCallback, useRef, } from "react";
|
|
59
59
|
import { formatBatchErrors } from "../../..";
|
|
60
60
|
import { getRecordErrors, getRenderedRecordWithErrors, recordIsEmpty, } from "./common";
|
|
61
|
+
import { sleep } from "../../../utils";
|
|
62
|
+
import { useImporterContext } from "../../ImporterContextProvider";
|
|
61
63
|
var MINIMUM_ROW_COUNT = 20;
|
|
62
64
|
var getRowId = function (id) { return "r".concat(id); };
|
|
63
65
|
export var getBatchErrors = function (records, onValidateRecord) { return __awaiter(void 0, void 0, void 0, function () {
|
|
@@ -85,10 +87,14 @@ export var getBatchErrors = function (records, onValidateRecord) { return __awai
|
|
|
85
87
|
});
|
|
86
88
|
}); };
|
|
87
89
|
var SpreadsheetContext = createContext({});
|
|
88
|
-
var
|
|
90
|
+
var addMeta = function (d, i) { return (__assign(__assign({}, d), { _meta: { id: getRowId(i), rowIndex: i } })); };
|
|
89
91
|
export var SpreadsheetContextProvider = function (_a) {
|
|
90
92
|
var initialData = _a.initialData, _b = _a.rowWidth, rowWidth = _b === void 0 ? 1 : _b, _c = _a.onValidateRecord, onValidateRecord = _c === void 0 ? null : _c, _d = _a.onValidateBatch, onValidateBatch = _d === void 0 ? null : _d, appResponse = _a.appResponse, fields = _a.fields, options = _a.options, isReadOnly = _a.isReadOnly, highlightFirstRow = _a.highlightFirstRow, submittedData = _a.submittedData, setReviewedData = _a.setReviewedData, children = _a.children;
|
|
91
|
-
var
|
|
93
|
+
var mappedInitialData = useMemo(function () { return initialData.map(addMeta); }, [
|
|
94
|
+
initialData,
|
|
95
|
+
]);
|
|
96
|
+
var _e = useState(mappedInitialData), data = _e[0], setData = _e[1];
|
|
97
|
+
var dataRef = useRef(mappedInitialData);
|
|
92
98
|
var _f = useState(false), isLoading = _f[0], setIsLoading = _f[1];
|
|
93
99
|
var _g = useState(null), sortByFieldErrors = _g[0], setSortByFieldErrors = _g[1];
|
|
94
100
|
var _h = useState(true), isScrollingEnabled = _h[0], setIsScrollingEnabled = _h[1];
|
|
@@ -100,74 +106,85 @@ export var SpreadsheetContextProvider = function (_a) {
|
|
|
100
106
|
batchValidationErrors: batchValidationErrors,
|
|
101
107
|
submittedData: submittedData,
|
|
102
108
|
}), columnErrorCounts = _l.columnErrorCounts, totalErrors = _l.totalErrors, isValidationComplete = _l.isValidationComplete;
|
|
109
|
+
var updateData = useCallback(function (data) {
|
|
110
|
+
dataRef.current = data;
|
|
111
|
+
setData(data);
|
|
112
|
+
}, []);
|
|
103
113
|
useEffect(function () {
|
|
114
|
+
var batchValidationDelayMs = options.batchValidationDelayMs, _a = options.batchValidationSize, batchValidationSize = _a === void 0 ? 1000 : _a;
|
|
115
|
+
var batchSize = Math.min(Math.floor(batchValidationSize), data.length) || data.length;
|
|
116
|
+
var batchCount = Math.ceil(data.length / batchSize);
|
|
117
|
+
var isCancelled = false;
|
|
118
|
+
var addEmptyRows = function () {
|
|
119
|
+
var newData = __spreadArray([], data, true);
|
|
120
|
+
var emptyRecord = fields.reduce(function (obj, f) {
|
|
121
|
+
var _a;
|
|
122
|
+
return (__assign(__assign({}, obj), (_a = {}, _a[f.name] = null, _a)));
|
|
123
|
+
}, {});
|
|
124
|
+
for (var i = newData.length; i < MINIMUM_ROW_COUNT; i++) {
|
|
125
|
+
newData.push(__assign(__assign({}, emptyRecord), { _meta: {
|
|
126
|
+
id: getRowId(i),
|
|
127
|
+
rowIndex: i,
|
|
128
|
+
} }));
|
|
129
|
+
}
|
|
130
|
+
updateData(newData);
|
|
131
|
+
};
|
|
132
|
+
var validateInBatches = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
133
|
+
var validationErrors, batchIdx, idx, batch, errors, validationPercentage;
|
|
134
|
+
return __generator(this, function (_a) {
|
|
135
|
+
switch (_a.label) {
|
|
136
|
+
case 0:
|
|
137
|
+
validationErrors = {};
|
|
138
|
+
batchIdx = 0;
|
|
139
|
+
_a.label = 1;
|
|
140
|
+
case 1:
|
|
141
|
+
if (!(batchIdx < batchCount)) return [3 /*break*/, 5];
|
|
142
|
+
if (isCancelled)
|
|
143
|
+
return [3 /*break*/, 5];
|
|
144
|
+
idx = batchIdx * batchSize;
|
|
145
|
+
batch = data.slice(idx, idx + batchSize);
|
|
146
|
+
return [4 /*yield*/, (onValidateBatch
|
|
147
|
+
? onValidateBatch(batch)
|
|
148
|
+
: getBatchErrors(batch, onValidateRecord))];
|
|
149
|
+
case 2:
|
|
150
|
+
errors = _a.sent();
|
|
151
|
+
validationErrors = __assign(__assign({}, validationErrors), errors);
|
|
152
|
+
// unblocks main thread for rendering ui
|
|
153
|
+
return [4 /*yield*/, sleep(batchValidationDelayMs)];
|
|
154
|
+
case 3:
|
|
155
|
+
// unblocks main thread for rendering ui
|
|
156
|
+
_a.sent();
|
|
157
|
+
validationPercentage = (Math.min(idx + batchSize, data.length) / data.length) * 100;
|
|
158
|
+
setBatchValidationPercentage(Math.floor(validationPercentage));
|
|
159
|
+
_a.label = 4;
|
|
160
|
+
case 4:
|
|
161
|
+
batchIdx++;
|
|
162
|
+
return [3 /*break*/, 1];
|
|
163
|
+
case 5:
|
|
164
|
+
if (!isCancelled)
|
|
165
|
+
setBatchValidationErrors(validationErrors);
|
|
166
|
+
return [2 /*return*/];
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}); };
|
|
104
170
|
var init = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
105
|
-
var batchValidationDelayMs, batchValidationSize, addEmptyRows, validateInBatches;
|
|
106
171
|
return __generator(this, function (_a) {
|
|
107
|
-
batchValidationDelayMs = options.batchValidationDelayMs, batchValidationSize = options.batchValidationSize;
|
|
108
|
-
addEmptyRows = function () {
|
|
109
|
-
var newData = __spreadArray([], data, true);
|
|
110
|
-
var emptyRecord = fields.reduce(function (obj, f) {
|
|
111
|
-
var _a;
|
|
112
|
-
return (__assign(__assign({}, obj), (_a = {}, _a[f.name] = null, _a)));
|
|
113
|
-
}, {});
|
|
114
|
-
for (var i = newData.length; i < MINIMUM_ROW_COUNT; i++) {
|
|
115
|
-
newData.push(__assign(__assign({}, emptyRecord), { _meta: {
|
|
116
|
-
id: getRowId(i),
|
|
117
|
-
rowIndex: i,
|
|
118
|
-
} }));
|
|
119
|
-
}
|
|
120
|
-
setData(newData);
|
|
121
|
-
};
|
|
122
172
|
if (data.length < MINIMUM_ROW_COUNT)
|
|
123
173
|
addEmptyRows();
|
|
124
|
-
validateInBatches = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
125
|
-
var validationErrors, batchSize, batchCount, batchIdx, idx, batch, errors, validationPercentage;
|
|
126
|
-
return __generator(this, function (_a) {
|
|
127
|
-
switch (_a.label) {
|
|
128
|
-
case 0:
|
|
129
|
-
validationErrors = {};
|
|
130
|
-
batchSize = Math.min(Math.floor(batchValidationSize), data.length) || data.length;
|
|
131
|
-
batchCount = Math.ceil(data.length / batchSize);
|
|
132
|
-
batchIdx = 0;
|
|
133
|
-
_a.label = 1;
|
|
134
|
-
case 1:
|
|
135
|
-
if (!(batchIdx < batchCount)) return [3 /*break*/, 5];
|
|
136
|
-
idx = batchIdx * batchSize;
|
|
137
|
-
batch = data.slice(idx, idx + batchSize);
|
|
138
|
-
return [4 /*yield*/, (onValidateBatch
|
|
139
|
-
? onValidateBatch(batch)
|
|
140
|
-
: getBatchErrors(batch, onValidateRecord))];
|
|
141
|
-
case 2:
|
|
142
|
-
errors = _a.sent();
|
|
143
|
-
validationErrors = __assign(__assign({}, validationErrors), errors);
|
|
144
|
-
// unblocks main thread for rendering ui
|
|
145
|
-
return [4 /*yield*/, sleep(batchValidationDelayMs)];
|
|
146
|
-
case 3:
|
|
147
|
-
// unblocks main thread for rendering ui
|
|
148
|
-
_a.sent();
|
|
149
|
-
validationPercentage = (Math.min(idx + batchSize, data.length) / data.length) * 100;
|
|
150
|
-
setBatchValidationPercentage(Math.floor(validationPercentage));
|
|
151
|
-
setBatchValidationErrors(validationErrors);
|
|
152
|
-
_a.label = 4;
|
|
153
|
-
case 4:
|
|
154
|
-
batchIdx++;
|
|
155
|
-
return [3 /*break*/, 1];
|
|
156
|
-
case 5: return [2 /*return*/];
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
}); };
|
|
160
174
|
validateInBatches();
|
|
161
175
|
return [2 /*return*/];
|
|
162
176
|
});
|
|
163
177
|
}); };
|
|
164
178
|
if (!isReadOnly)
|
|
165
179
|
init();
|
|
180
|
+
return function () {
|
|
181
|
+
isCancelled = true;
|
|
182
|
+
};
|
|
166
183
|
}, []);
|
|
167
184
|
useEffect(function () {
|
|
168
185
|
var appValidationErrors = appResponse === null || appResponse === void 0 ? void 0 : appResponse.errors;
|
|
169
186
|
if (appValidationErrors) {
|
|
170
|
-
|
|
187
|
+
updateData(__spreadArray([], data, true).map(function (record) { return (__assign(__assign({}, record), { _meta: __assign(__assign({}, record._meta), { appValidationErrors: appValidationErrors[record._meta.id] }) })); }));
|
|
171
188
|
}
|
|
172
189
|
}, [appResponse]);
|
|
173
190
|
useEffect(function () {
|
|
@@ -196,9 +213,9 @@ export var SpreadsheetContextProvider = function (_a) {
|
|
|
196
213
|
return a._meta.rowIndex > b._meta.rowIndex ? 1 : -1;
|
|
197
214
|
return bHasErrors ? 1 : -1;
|
|
198
215
|
});
|
|
199
|
-
|
|
216
|
+
updateData(sortedByFieldErrors);
|
|
200
217
|
}, [sortByFieldErrors]);
|
|
201
|
-
var validateRenderedRecords = function (renderedData) { return __awaiter(void 0, void 0, void 0, function () {
|
|
218
|
+
var validateRenderedRecords = useCallback(function (renderedData) { return __awaiter(void 0, void 0, void 0, function () {
|
|
202
219
|
var newData;
|
|
203
220
|
return __generator(this, function (_a) {
|
|
204
221
|
if (isReadOnly)
|
|
@@ -226,12 +243,13 @@ export var SpreadsheetContextProvider = function (_a) {
|
|
|
226
243
|
});
|
|
227
244
|
}); });
|
|
228
245
|
setIsLoading(false);
|
|
229
|
-
|
|
246
|
+
updateData(newData);
|
|
230
247
|
return [2 /*return*/];
|
|
231
248
|
});
|
|
232
|
-
}); };
|
|
249
|
+
}); }, [data]);
|
|
233
250
|
var value = {
|
|
234
251
|
data: data,
|
|
252
|
+
dataRef: dataRef,
|
|
235
253
|
fields: fields,
|
|
236
254
|
isLoading: isLoading,
|
|
237
255
|
setIsLoading: setIsLoading,
|
|
@@ -246,7 +264,7 @@ export var SpreadsheetContextProvider = function (_a) {
|
|
|
246
264
|
sortByFieldErrors: sortByFieldErrors,
|
|
247
265
|
submittedData: submittedData,
|
|
248
266
|
setSortByFieldErrors: setSortByFieldErrors,
|
|
249
|
-
setData:
|
|
267
|
+
setData: updateData,
|
|
250
268
|
onValidateRecord: onValidateRecord,
|
|
251
269
|
validateRenderedRecords: validateRenderedRecords,
|
|
252
270
|
setIsScrollingEnabled: setIsScrollingEnabled,
|
|
@@ -257,6 +275,7 @@ export var SpreadsheetContextProvider = function (_a) {
|
|
|
257
275
|
var useValidationState = function (_a) {
|
|
258
276
|
var data = _a.data, fields = _a.fields, batchValidationErrors = _a.batchValidationErrors, submittedData = _a.submittedData;
|
|
259
277
|
var _b = useState({}), columnErrorCounts = _b[0], setColumnErrorCounts = _b[1];
|
|
278
|
+
var setIsSpreadsheetValid = useImporterContext().setIsSpreadsheetValid;
|
|
260
279
|
useEffect(function () {
|
|
261
280
|
var updateErrorCounts = function () {
|
|
262
281
|
var newColumnErrorCounts = {};
|
|
@@ -276,6 +295,7 @@ var useValidationState = function (_a) {
|
|
|
276
295
|
});
|
|
277
296
|
updateFieldErrorCount(recordErrors);
|
|
278
297
|
});
|
|
298
|
+
setIsSpreadsheetValid(Object.keys(newColumnErrorCounts).length === 0);
|
|
279
299
|
setColumnErrorCounts(newColumnErrorCounts);
|
|
280
300
|
};
|
|
281
301
|
updateErrorCounts();
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import React from "react";
|
|
2
2
|
import { DivCSSProps } from "../../../styled/utils";
|
|
3
3
|
declare type Props = {
|
|
4
4
|
height?: number;
|
|
5
|
-
scrollTop: number;
|
|
6
5
|
spreadsheetHasXScroll?: boolean;
|
|
6
|
+
gridRef: React.MutableRefObject<any>;
|
|
7
7
|
} & DivCSSProps;
|
|
8
|
-
export declare const SpreadsheetRowNumbers: ({ height,
|
|
8
|
+
export declare const SpreadsheetRowNumbers: ({ height, spreadsheetHasXScroll, gridRef, ...props }: Props) => JSX.Element;
|
|
9
9
|
export {};
|
|
@@ -25,27 +25,27 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
25
25
|
return t;
|
|
26
26
|
};
|
|
27
27
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
28
|
-
import { Grid } from "react-
|
|
28
|
+
import { FixedSizeGrid as Grid } from "react-window";
|
|
29
29
|
import styled, { css } from "styled-components";
|
|
30
30
|
import { Div } from "../../../styled/utils";
|
|
31
31
|
import { spreadsheetRowHeightPx } from "./common";
|
|
32
32
|
import { spreadsheetHeaderHeightPx } from "./common/index";
|
|
33
33
|
import { useSpreadsheetContext } from "./SpreadsheetContextProvider";
|
|
34
34
|
var SPREADSHEET_ROW_NUMBERS_WIDTH = 75;
|
|
35
|
+
var gridStyles = {
|
|
36
|
+
outline: "none",
|
|
37
|
+
willChange: "unset",
|
|
38
|
+
overflowY: "hidden",
|
|
39
|
+
overflowX: "scroll",
|
|
40
|
+
};
|
|
35
41
|
export var SpreadsheetRowNumbers = function (_a) {
|
|
36
|
-
var height = _a.height,
|
|
42
|
+
var height = _a.height, spreadsheetHasXScroll = _a.spreadsheetHasXScroll, gridRef = _a.gridRef, props = __rest(_a, ["height", "spreadsheetHasXScroll", "gridRef"]);
|
|
37
43
|
var data = useSpreadsheetContext().data;
|
|
38
|
-
var
|
|
44
|
+
var Cell = function (_a) {
|
|
39
45
|
var rowIndex = _a.rowIndex, style = _a.style;
|
|
40
46
|
return (_jsx(RowNumber, __assign({ style: style, alignCenter: true, justifyEnd: true, isLast: rowIndex === data.length - 1 }, { children: _jsx(Div, __assign({ truncateText: true, mr: 16, textAlignRight: true }, { children: rowIndex + 1 })) }), rowIndex));
|
|
41
47
|
};
|
|
42
|
-
|
|
43
|
-
outline: "none",
|
|
44
|
-
willChange: "unset",
|
|
45
|
-
overflowY: "hidden",
|
|
46
|
-
overflowX: "scroll",
|
|
47
|
-
};
|
|
48
|
-
return (_jsxs(SpreadsheetRowNumbersContainer, __assign({}, props, { h: height }, { children: [_jsx(SpreadsheetRowNumbersHeader, {}), _jsx(Grid, { scrollTop: scrollTop, style: gridStyles, width: SPREADSHEET_ROW_NUMBERS_WIDTH, columnCount: 1, columnWidth: SPREADSHEET_ROW_NUMBERS_WIDTH, height: height - spreadsheetHeaderHeightPx, rowHeight: 40, cellRenderer: rowRenderer, rowCount: data.length })] })));
|
|
48
|
+
return (_jsxs(SpreadsheetRowNumbersContainer, __assign({}, props, { h: height }, { children: [_jsx(SpreadsheetRowNumbersHeader, {}), _jsx(Grid, __assign({ ref: gridRef, style: gridStyles, width: SPREADSHEET_ROW_NUMBERS_WIDTH, columnCount: 1, columnWidth: SPREADSHEET_ROW_NUMBERS_WIDTH, height: height - spreadsheetHeaderHeightPx, rowHeight: 40, rowCount: data.length }, { children: Cell }))] })));
|
|
49
49
|
};
|
|
50
50
|
var RowNumber = styled(Div)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n background-color: ", ";\n ", ";\n ", "\n"], ["\n background-color: ", ";\n ", ";\n ", "\n"])), function (p) { return p.theme.colors.tableHeader; }, function (p) { return p.theme.css.label3; }, function (p) {
|
|
51
51
|
return !p.isLast && css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n box-shadow: inset 0 -1px 0 ", ";\n "], ["\n box-shadow: inset 0 -1px 0 ", ";\n "])), function (p) { return p.theme.colors.gray300; });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="react" />
|
|
2
2
|
import { FieldTypes, Record } from "../../../../../types";
|
|
3
3
|
export declare const parseValue: (fieldType: FieldTypes, value: any) => any;
|
|
4
4
|
export declare const useValidationError: (fieldName: string, record: Record) => {
|
|
@@ -6,7 +6,7 @@ export declare const useValidationError: (fieldName: string, record: Record) =>
|
|
|
6
6
|
};
|
|
7
7
|
export declare const useSpreadsheetField: (name: any, record: Record, fieldType: FieldTypes) => {
|
|
8
8
|
value: any;
|
|
9
|
-
setValue:
|
|
9
|
+
setValue: (value: any) => void;
|
|
10
10
|
validationError: any;
|
|
11
11
|
};
|
|
12
12
|
export declare const SpreadsheetField: ({ validationError, children }: {
|
|
@@ -59,7 +59,8 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
59
59
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
60
60
|
};
|
|
61
61
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
62
|
-
import {
|
|
62
|
+
import { useState, useCallback } from "react";
|
|
63
|
+
import { debounce } from "lodash";
|
|
63
64
|
import styled, { css } from "styled-components";
|
|
64
65
|
import { getRecordErrors, getRenderedRecordWithErrors, isFloat, isInteger, } from "..";
|
|
65
66
|
import { TooltipProvider } from "../../../../../common/TooltipProvider";
|
|
@@ -90,54 +91,38 @@ export var useValidationError = function (fieldName, record) {
|
|
|
90
91
|
return { validationError: validationError };
|
|
91
92
|
};
|
|
92
93
|
export var useSpreadsheetField = function (name, record, fieldType) {
|
|
93
|
-
var _a = useSpreadsheetContext(),
|
|
94
|
+
var _a = useSpreadsheetContext(), dataRef = _a.dataRef, setData = _a.setData, onValidateRecord = _a.onValidateRecord;
|
|
94
95
|
var _b = useState(record[name]), value = _b[0], setValue = _b[1];
|
|
95
96
|
var validationError = useValidationError(name, record).validationError;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
_b = rowIndex;
|
|
126
|
-
_c = getRenderedRecordWithErrors;
|
|
127
|
-
_e = {
|
|
128
|
-
record: newRecord
|
|
129
|
-
};
|
|
130
|
-
return [4 /*yield*/, onValidateRecord(newRecord)];
|
|
131
|
-
case 1:
|
|
132
|
-
_a[_b] = _c.apply(void 0, [(_e.validationErrors = _f.sent(),
|
|
133
|
-
_e)]);
|
|
134
|
-
setData(newData);
|
|
135
|
-
return [2 /*return*/];
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
}); }, 300);
|
|
139
|
-
}, [value]);
|
|
140
|
-
return { value: value, setValue: setValue, validationError: validationError };
|
|
97
|
+
var updateData = useCallback(debounce(function (value) { return __awaiter(void 0, void 0, void 0, function () {
|
|
98
|
+
var newData, newRecord, rowIndex, _a, _b, _c;
|
|
99
|
+
var _d, _e;
|
|
100
|
+
return __generator(this, function (_f) {
|
|
101
|
+
switch (_f.label) {
|
|
102
|
+
case 0:
|
|
103
|
+
newData = __spreadArray([], dataRef.current, true);
|
|
104
|
+
newRecord = __assign(__assign({}, record), (_d = {}, _d[name] = parseValue(fieldType, value), _d));
|
|
105
|
+
rowIndex = newData.findIndex(function (r) { return r._meta.id === record._meta.id; });
|
|
106
|
+
_a = newData;
|
|
107
|
+
_b = rowIndex;
|
|
108
|
+
_c = getRenderedRecordWithErrors;
|
|
109
|
+
_e = {
|
|
110
|
+
record: newRecord
|
|
111
|
+
};
|
|
112
|
+
return [4 /*yield*/, onValidateRecord(newRecord)];
|
|
113
|
+
case 1:
|
|
114
|
+
_a[_b] = _c.apply(void 0, [(_e.validationErrors = _f.sent(),
|
|
115
|
+
_e)]);
|
|
116
|
+
setData(newData);
|
|
117
|
+
return [2 /*return*/];
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}); }, 300), [record]);
|
|
121
|
+
var updateValue = useCallback(function (value) {
|
|
122
|
+
setValue(value);
|
|
123
|
+
updateData(value);
|
|
124
|
+
}, [record, updateData]);
|
|
125
|
+
return { value: value, setValue: updateValue, validationError: validationError };
|
|
141
126
|
};
|
|
142
127
|
var ContentContainer = styled(Div)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n height: calc(100% - 1px);\n width: 100%;\n ", ";\n ", "\n ", "\n"], ["\n height: calc(100% - 1px);\n width: 100%;\n ", ";\n ", "\n ", "\n"])), function (p) { return p.theme.css.alignCenter; }, function (p) {
|
|
143
128
|
return p.hasError && css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n color: ", ";\n background: ", ";\n /* internal border */\n box-shadow: 0px 0px 0px 1px ", " inset;\n "], ["\n color: ", ";\n background: ", ";\n /* internal border */\n box-shadow: 0px 0px 0px 1px ", " inset;\n "])), function (p) { return p.theme.colors.error; }, function (p) { return p.theme.colors.red100; }, function (p) { return p.theme.colors.error; });
|
|
@@ -85,7 +85,7 @@ export var getRecordErrors = function (_a) {
|
|
|
85
85
|
if (isEmpty(fieldValue) && field.isRequired) {
|
|
86
86
|
newErrors[field.name] = "".concat(field.label, " is required");
|
|
87
87
|
}
|
|
88
|
-
else if (validations[field.type]) {
|
|
88
|
+
else if (!isEmpty(fieldValue) && validations[field.type]) {
|
|
89
89
|
newErrors[field.name] = validations[field.type](field, fieldValue);
|
|
90
90
|
}
|
|
91
91
|
return newErrors;
|