@vuu-ui/vuu-table-extras 3.3.7 → 3.3.8
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/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "3.3.
|
|
2
|
+
"version": "3.3.8",
|
|
3
3
|
"author": "heswell",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"license": "Apache-2.0",
|
|
@@ -11,19 +11,19 @@
|
|
|
11
11
|
"lezer-generate:column": "lezer-generator --output ./src/column-expression-input/column-language-parser/generated/column-parser.js ./src/column-expression-input/column-language-parser/grammar/column.grammar"
|
|
12
12
|
},
|
|
13
13
|
"devDependencies": {
|
|
14
|
-
"@vuu-ui/vuu-filter-types": "3.3.
|
|
15
|
-
"@vuu-ui/vuu-protocol-types": "3.3.
|
|
14
|
+
"@vuu-ui/vuu-filter-types": "3.3.8",
|
|
15
|
+
"@vuu-ui/vuu-protocol-types": "3.3.8"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@vuu-ui/vuu-codemirror": "3.3.
|
|
19
|
-
"@vuu-ui/vuu-data-editing": "3.3.
|
|
20
|
-
"@vuu-ui/vuu-data-react": "3.3.
|
|
21
|
-
"@vuu-ui/vuu-data-types": "3.3.
|
|
22
|
-
"@vuu-ui/vuu-table-types": "3.3.
|
|
23
|
-
"@vuu-ui/vuu-popups": "3.3.
|
|
24
|
-
"@vuu-ui/vuu-table": "3.3.
|
|
25
|
-
"@vuu-ui/vuu-utils": "3.3.
|
|
26
|
-
"@vuu-ui/vuu-ui-controls": "3.3.
|
|
18
|
+
"@vuu-ui/vuu-codemirror": "3.3.8",
|
|
19
|
+
"@vuu-ui/vuu-data-editing": "3.3.8",
|
|
20
|
+
"@vuu-ui/vuu-data-react": "3.3.8",
|
|
21
|
+
"@vuu-ui/vuu-data-types": "3.3.8",
|
|
22
|
+
"@vuu-ui/vuu-table-types": "3.3.8",
|
|
23
|
+
"@vuu-ui/vuu-popups": "3.3.8",
|
|
24
|
+
"@vuu-ui/vuu-table": "3.3.8",
|
|
25
|
+
"@vuu-ui/vuu-utils": "3.3.8",
|
|
26
|
+
"@vuu-ui/vuu-ui-controls": "3.3.8",
|
|
27
27
|
"@lezer/lr": "1.4.2",
|
|
28
28
|
"@salt-ds/core": "1.54.1",
|
|
29
29
|
"@salt-ds/lab": "1.0.0-alpha.83",
|
|
@@ -7,7 +7,7 @@ import { useCsvUpload } from "./useCsvUpload.js";
|
|
|
7
7
|
import CsvUpload from "./CsvUpload.css";
|
|
8
8
|
const classBase = "vuuCsvUpload";
|
|
9
9
|
const CsvUpload_CsvUpload = (props)=>{
|
|
10
|
-
const { children, dialogTitle = "Import CSV", embedded = false, onCancel, onClose, open } = props;
|
|
10
|
+
const { children, dialogTitle = "Import CSV", embedded = false, onCancel, onClose, open, renderError } = props;
|
|
11
11
|
const isControlledOpen = void 0 !== open;
|
|
12
12
|
const [internalOpen, setInternalOpen] = useState(open ?? true);
|
|
13
13
|
const dialogOpen = isControlledOpen ? open : internalOpen;
|
|
@@ -17,7 +17,7 @@ const CsvUpload_CsvUpload = (props)=>{
|
|
|
17
17
|
css: CsvUpload,
|
|
18
18
|
window: targetWindow
|
|
19
19
|
});
|
|
20
|
-
const { canImport, cancelImport, isProcessingFile, isImporting, importData, onDrop, onTriggerChange, schema, validation } = useCsvUpload(props);
|
|
20
|
+
const { canImport, cancelImport, isProcessingFile, isImporting, importData, onDrop, onTriggerChange, schema, validation, error } = useCsvUpload(props);
|
|
21
21
|
const handleCancel = useCallback(async ()=>{
|
|
22
22
|
await cancelImport();
|
|
23
23
|
if (!isControlledOpen) setInternalOpen(false);
|
|
@@ -40,7 +40,7 @@ const CsvUpload_CsvUpload = (props)=>{
|
|
|
40
40
|
className: `${classBase}-dropZone`,
|
|
41
41
|
disabled: void 0 === schema || isProcessingFile || isImporting,
|
|
42
42
|
onDrop: onDrop,
|
|
43
|
-
status: validation && validation.errors.length > 0 ? "error" : void 0,
|
|
43
|
+
status: validation && validation.errors.length > 0 || error ? "error" : void 0,
|
|
44
44
|
children: [
|
|
45
45
|
/*#__PURE__*/ jsx(FileDropZoneIcon, {}),
|
|
46
46
|
validation && validation.errors.length > 0 ? /*#__PURE__*/ jsxs(Fragment, {
|
|
@@ -53,7 +53,7 @@ const CsvUpload_CsvUpload = (props)=>{
|
|
|
53
53
|
children: validation.errors.filter((e)=>e.column in validation.errorMap.fileErrors).map((error, i)=>/*#__PURE__*/ jsx("li", {
|
|
54
54
|
className: `${classBase}-errorItem`,
|
|
55
55
|
children: error.message
|
|
56
|
-
}, i))
|
|
56
|
+
}, `${error.column}-${error.message}-${i}`))
|
|
57
57
|
}),
|
|
58
58
|
/*#__PURE__*/ jsx("div", {
|
|
59
59
|
children: "Please rectify and reupload"
|
|
@@ -69,6 +69,19 @@ const CsvUpload_CsvUpload = (props)=>{
|
|
|
69
69
|
})
|
|
70
70
|
]
|
|
71
71
|
}),
|
|
72
|
+
error && (renderError ? renderError(error) : /*#__PURE__*/ jsxs("div", {
|
|
73
|
+
className: `${classBase}-errors`,
|
|
74
|
+
children: [
|
|
75
|
+
/*#__PURE__*/ jsx("div", {
|
|
76
|
+
children: /*#__PURE__*/ jsx("strong", {
|
|
77
|
+
children: "Import Error:"
|
|
78
|
+
})
|
|
79
|
+
}),
|
|
80
|
+
/*#__PURE__*/ jsx("div", {
|
|
81
|
+
children: error.errors.importError?.message || error.errors.schemaError?.message || error.errors.validationError?.message || "An unexpected error occurred during import."
|
|
82
|
+
})
|
|
83
|
+
]
|
|
84
|
+
})),
|
|
72
85
|
children
|
|
73
86
|
]
|
|
74
87
|
});
|
|
@@ -12,6 +12,13 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
12
12
|
const [isProcessingFile, setIsProcessingFile] = useState(false);
|
|
13
13
|
const [isImporting, setIsImporting] = useState(false);
|
|
14
14
|
const [fetchedImportSchema, setFetchedImportSchema] = useState();
|
|
15
|
+
const [error, setError] = useState();
|
|
16
|
+
const handleError = useCallback((errResult)=>{
|
|
17
|
+
setError(errResult);
|
|
18
|
+
onError?.(errResult);
|
|
19
|
+
}, [
|
|
20
|
+
onError
|
|
21
|
+
]);
|
|
15
22
|
useEffect(()=>{
|
|
16
23
|
if (importSchema || void 0 === importTable) return void setFetchedImportSchema(void 0);
|
|
17
24
|
let cancelled = false;
|
|
@@ -195,21 +202,23 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
195
202
|
]);
|
|
196
203
|
const cancelImport = useCallback(async ()=>{
|
|
197
204
|
operationIdRef.current++;
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
205
|
+
processingPromiseRef.current = void 0;
|
|
206
|
+
setIsProcessingFile(false);
|
|
207
|
+
setIsImporting(false);
|
|
208
|
+
handleError(void 0);
|
|
201
209
|
await closePendingEditSession(false);
|
|
202
210
|
}, [
|
|
203
|
-
closePendingEditSession
|
|
211
|
+
closePendingEditSession,
|
|
212
|
+
handleError
|
|
204
213
|
]);
|
|
205
214
|
const processFile = useCallback(async (file, operationId)=>{
|
|
206
215
|
setValidation(void 0);
|
|
207
|
-
|
|
216
|
+
handleError(void 0);
|
|
208
217
|
await closePendingEditSession(false);
|
|
209
218
|
if (operationId !== operationIdRef.current) return;
|
|
210
219
|
if (!isSessionTable(dataSource.table) && ("initialising" === dataSource.status || "unsubscribed" === dataSource.status)) {
|
|
211
220
|
const errorMessage = `CsvUpload requires dataSource to be subscribed before uploading (current status: "${dataSource.status}").`;
|
|
212
|
-
|
|
221
|
+
handleError({
|
|
213
222
|
errors: {
|
|
214
223
|
validationError: createUploadError("validation", errorMessage)
|
|
215
224
|
}
|
|
@@ -223,7 +232,7 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
223
232
|
const parsedCsv = parseCsv(fileContents, parseOptions);
|
|
224
233
|
if (parsedCsv.error && hasFileParseErrors(parsedCsv.error)) {
|
|
225
234
|
setValidation(void 0);
|
|
226
|
-
|
|
235
|
+
handleError({
|
|
227
236
|
errors: {
|
|
228
237
|
validationError: createUploadError("validation", `Validation failed: ${parsedCsv.error.message}`, parsedCsv.error)
|
|
229
238
|
}
|
|
@@ -235,7 +244,7 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
235
244
|
});
|
|
236
245
|
if (Object.keys(schemaValidation.errorMap.fileErrors).length > 0) {
|
|
237
246
|
setValidation(schemaValidation);
|
|
238
|
-
|
|
247
|
+
handleError({
|
|
239
248
|
errors: {
|
|
240
249
|
schemaError: createUploadError("schema", "CSV validation failed.", parsedCsv.error, {
|
|
241
250
|
errorMap: schemaValidation.errorMap,
|
|
@@ -248,24 +257,28 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
248
257
|
}
|
|
249
258
|
const mergedValidation = mergeValidationWithParseErrors(schemaValidation, parsedCsv.error);
|
|
250
259
|
setValidation(mergedValidation);
|
|
251
|
-
if (mergedValidation.rows.length > 0) {
|
|
260
|
+
if (mergedValidation.rows.length > 0) try {
|
|
252
261
|
await beginEditSession();
|
|
253
262
|
if (operationId !== operationIdRef.current) return;
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
importError: createUploadError("import", `RPC import failed: ${toErrorMessage(error)}`)
|
|
263
|
-
}
|
|
264
|
-
});
|
|
263
|
+
const rowsAdded = await addAllRows(mergedValidation, operationId);
|
|
264
|
+
if (!rowsAdded) return;
|
|
265
|
+
} catch (error) {
|
|
266
|
+
if (void 0 !== sessionDataSourceRef.current) await endEditSessionAndNotify(false, "failed");
|
|
267
|
+
else try {
|
|
268
|
+
await editSession.end(false);
|
|
269
|
+
} catch (err) {
|
|
270
|
+
console.error("[useCsvUpload] failed to end clean session", err);
|
|
265
271
|
}
|
|
272
|
+
setValidation(void 0);
|
|
273
|
+
handleError({
|
|
274
|
+
errors: {
|
|
275
|
+
importError: createUploadError("import", `RPC import failed: ${toErrorMessage(error)}`)
|
|
276
|
+
}
|
|
277
|
+
});
|
|
266
278
|
}
|
|
267
279
|
}, [
|
|
268
|
-
|
|
280
|
+
handleError,
|
|
281
|
+
editSession,
|
|
269
282
|
addAllRows,
|
|
270
283
|
maxRows,
|
|
271
284
|
parseOptions,
|
|
@@ -297,13 +310,13 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
297
310
|
validationError: createUploadError("validation", errorMessage, parseError)
|
|
298
311
|
}
|
|
299
312
|
};
|
|
300
|
-
|
|
313
|
+
handleError(errors);
|
|
301
314
|
} finally{
|
|
302
315
|
if (processingPromiseRef.current === processingPromise) processingPromiseRef.current = void 0;
|
|
303
316
|
setIsProcessingFile(false);
|
|
304
317
|
}
|
|
305
318
|
}, [
|
|
306
|
-
|
|
319
|
+
handleError,
|
|
307
320
|
onProcessingStarted,
|
|
308
321
|
processFile,
|
|
309
322
|
setActiveSessionDataSource
|
|
@@ -326,7 +339,7 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
326
339
|
const importData = useCallback(async ()=>{
|
|
327
340
|
if (!canImport || void 0 === validation) return false;
|
|
328
341
|
setIsImporting(true);
|
|
329
|
-
|
|
342
|
+
handleError(void 0);
|
|
330
343
|
try {
|
|
331
344
|
const fallbackTableData = {
|
|
332
345
|
columns: validation.columns,
|
|
@@ -357,7 +370,7 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
357
370
|
importError: createUploadError("import", errorMessage)
|
|
358
371
|
}
|
|
359
372
|
};
|
|
360
|
-
|
|
373
|
+
handleError(errors);
|
|
361
374
|
return false;
|
|
362
375
|
} finally{
|
|
363
376
|
setIsImporting(false);
|
|
@@ -366,7 +379,7 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
366
379
|
canImport,
|
|
367
380
|
editSession,
|
|
368
381
|
endEditSessionAndNotify,
|
|
369
|
-
|
|
382
|
+
handleError,
|
|
370
383
|
onImported,
|
|
371
384
|
onPreview,
|
|
372
385
|
importMode,
|
|
@@ -382,7 +395,8 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
382
395
|
onTriggerChange,
|
|
383
396
|
sessionTable,
|
|
384
397
|
schema,
|
|
385
|
-
validation
|
|
398
|
+
validation,
|
|
399
|
+
error
|
|
386
400
|
};
|
|
387
401
|
};
|
|
388
402
|
export { useCsvUpload };
|
|
@@ -60,5 +60,9 @@ export interface CsvUploadProps {
|
|
|
60
60
|
parseOptions?: CsvParseOptions;
|
|
61
61
|
importMode?: "direct" | "preview";
|
|
62
62
|
rowDefaults?: RowDefaultDataItemValues;
|
|
63
|
+
/**
|
|
64
|
+
* Custom renderer for the error panel.
|
|
65
|
+
*/
|
|
66
|
+
renderError?: (error: CsvUploadErrorResult) => ReactNode;
|
|
63
67
|
}
|
|
64
68
|
export declare const CsvUpload: (props: CsvUploadProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -37,5 +37,6 @@ export type UseCsvUploadReturn = {
|
|
|
37
37
|
sessionTable: CsvUploadSessionTable | undefined;
|
|
38
38
|
schema: TableSchema | undefined;
|
|
39
39
|
validation: CsvValidationResult | undefined;
|
|
40
|
+
error: CsvUploadErrorResult | undefined;
|
|
40
41
|
};
|
|
41
42
|
export declare const useCsvUpload: ({ dataSource, importMode, importSchema, importTable, onImportSessionEnded, onImportSessionStarted, onError, onImported, onPreview, onProcessingStarted, maxRows, parseOptions, rowDefaults, }: CsvUploadHookProps) => UseCsvUploadReturn;
|