@vuu-ui/vuu-table-extras 4.0.0-alpha.20 → 4.0.0-alpha.21
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 +16 -17
- package/src/cell-renderers/pct-progress-cell/PctProgressCell.css.js +2 -2
- package/src/cell-renderers/progress-cell/ProgressCell.css.js +2 -2
- package/src/column-expression-input/ColumnExpressionInput.css.js +5 -5
- package/src/column-expression-input/theme.js +1 -1
- package/src/column-settings-panel/ColumnNameLabel.css.js +1 -1
- package/src/csv-export/export-utils.js +13 -4
- package/src/csv-upload/CsvUpload.css.js +7 -7
- package/src/csv-upload/parse/csv-upload-utils.js +47 -2
- package/src/csv-upload/session/index.js +2 -0
- package/src/csv-upload/session/useImportSchema.js +44 -0
- package/src/csv-upload/session/useImportSession.js +204 -0
- package/src/csv-upload/useCsvUpload.js +45 -188
- package/src/freeze-control/FreezeControl.css.js +4 -4
- package/src/freeze-control/FrozenBanner.css.js +2 -2
- package/types/calculated-column/CalculatedColumnPanel.d.ts +1 -1
- package/types/cell-renderers/background-cell/BackgroundCell.d.ts +1 -1
- package/types/cell-renderers/background-cell/BackgroundCellConfigurationEditor.d.ts +1 -1
- package/types/cell-renderers/button-cell/IconButtonCell.d.ts +1 -1
- package/types/cell-renderers/dropdown-cell/DropdownCell.d.ts +1 -1
- package/types/cell-renderers/lookup-cell/LookupCell.d.ts +1 -1
- package/types/cell-renderers/pct-progress-cell/PctProgressCell.d.ts +1 -1
- package/types/column-expression-input/ColumnExpressionInput.d.ts +1 -1
- package/types/column-expression-input/column-language-parser/test.d.mts +1 -1
- package/types/column-formatting-settings/BaseNumericFormattingSettings.d.ts +1 -1
- package/types/column-formatting-settings/ColumnFormattingPanel.d.ts +1 -1
- package/types/column-formatting-settings/LongTypeFormattingSettings.d.ts +1 -2
- package/types/column-menu/ColumnMenu.d.ts +1 -1
- package/types/column-picker/ColumnPickerAction.d.ts +1 -1
- package/types/column-settings-panel/ColumnNameLabel.d.ts +1 -1
- package/types/column-settings-panel/ColumnSettingsPanel.d.ts +1 -1
- package/types/csv-upload/CsvUpload.d.ts +1 -1
- package/types/csv-upload/data-upload-preview/DataUploadPreview.d.ts +1 -1
- package/types/csv-upload/parse/csv-upload-utils.d.ts +9 -0
- package/types/csv-upload/session/index.d.ts +2 -0
- package/types/csv-upload/session/useImportSchema.d.ts +13 -0
- package/types/csv-upload/session/useImportSession.d.ts +26 -0
- package/types/csv-upload/useCsvUpload.d.ts +1 -1
- package/types/datasource-stats/DatasourceStats.d.ts +1 -1
- package/types/freeze-control/FreezeControl.d.ts +1 -1
- package/types/freeze-control/FrozenBanner.d.ts +1 -1
- package/types/inline-add-row/InlineAddRow.d.ts +1 -1
- package/types/tabbed-table-config-panel/TabbedTableConfigPanel.d.ts +1 -1
- package/types/tabbed-table-config-panel/TabbedTableSettingsAction.d.ts +1 -1
- package/types/table-footer/TableFooter.d.ts +2 -2
- package/types/table-provider/TableProvider.d.ts +1 -1
- package/types/table-settings-panel/TableSettingsPanel.d.ts +1 -1
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "4.0.0-alpha.
|
|
2
|
+
"version": "4.0.0-alpha.21",
|
|
3
3
|
"author": "heswell",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"license": "Apache-2.0",
|
|
@@ -12,25 +12,24 @@
|
|
|
12
12
|
"lezer-generate:column": "lezer-generator --output ./src/column-expression-input/column-language-parser/generated/column-parser.ts ./src/column-expression-input/column-language-parser/grammar/column.grammar"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"@vuu-ui/vuu-filter-types": "4.0.0-alpha.
|
|
16
|
-
"@vuu-ui/vuu-protocol-types": "4.0.0-alpha.
|
|
15
|
+
"@vuu-ui/vuu-filter-types": "4.0.0-alpha.21",
|
|
16
|
+
"@vuu-ui/vuu-protocol-types": "4.0.0-alpha.21"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@vuu-ui/core": "4.0.0-alpha.
|
|
20
|
-
"@vuu-ui/vuu-codemirror": "4.0.0-alpha.
|
|
21
|
-
"@vuu-ui/vuu-data-editing": "4.0.0-alpha.
|
|
22
|
-
"@vuu-ui/vuu-data-react": "4.0.0-alpha.
|
|
23
|
-
"@vuu-ui/vuu-data-types": "4.0.0-alpha.
|
|
24
|
-
"@vuu-ui/vuu-table-types": "4.0.0-alpha.
|
|
25
|
-
"@vuu-ui/vuu-popups": "4.0.0-alpha.
|
|
26
|
-
"@vuu-ui/vuu-table": "4.0.0-alpha.
|
|
27
|
-
"@vuu-ui/vuu-utils": "4.0.0-alpha.
|
|
28
|
-
"@vuu-ui/vuu-ui-controls": "4.0.0-alpha.
|
|
19
|
+
"@vuu-ui/core": "4.0.0-alpha.21",
|
|
20
|
+
"@vuu-ui/vuu-codemirror": "4.0.0-alpha.21",
|
|
21
|
+
"@vuu-ui/vuu-data-editing": "4.0.0-alpha.21",
|
|
22
|
+
"@vuu-ui/vuu-data-react": "4.0.0-alpha.21",
|
|
23
|
+
"@vuu-ui/vuu-data-types": "4.0.0-alpha.21",
|
|
24
|
+
"@vuu-ui/vuu-table-types": "4.0.0-alpha.21",
|
|
25
|
+
"@vuu-ui/vuu-popups": "4.0.0-alpha.21",
|
|
26
|
+
"@vuu-ui/vuu-table": "4.0.0-alpha.21",
|
|
27
|
+
"@vuu-ui/vuu-utils": "4.0.0-alpha.21",
|
|
28
|
+
"@vuu-ui/vuu-ui-controls": "4.0.0-alpha.21",
|
|
29
29
|
"@lezer/lr": "1.4.2",
|
|
30
|
-
"@salt-ds/core": "1.
|
|
31
|
-
"@salt-ds/
|
|
32
|
-
"@salt-ds/
|
|
33
|
-
"@salt-ds/window": "0.1.1",
|
|
30
|
+
"@salt-ds/core": "1.72.0",
|
|
31
|
+
"@salt-ds/styles": "0.4.1",
|
|
32
|
+
"@salt-ds/window": "0.1.2",
|
|
34
33
|
"csv-parse": "^7.0.0"
|
|
35
34
|
},
|
|
36
35
|
"peerDependencies": {
|
|
@@ -9,8 +9,8 @@ const css = `
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
.vuuPctProgressCell-progressBar {
|
|
12
|
-
background-color: var(--
|
|
13
|
-
border-right: solid var(--progress-bar-width) var(--
|
|
12
|
+
background-color: var(--salt-color-green-600-40a);
|
|
13
|
+
border-right: solid var(--progress-bar-width) var(--salt-color-green-600);
|
|
14
14
|
height: 20px;
|
|
15
15
|
width: var(--progress-bar-pct, 0);
|
|
16
16
|
display: inline-block;
|
|
@@ -13,7 +13,7 @@ const css = `
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
.vuuProgressCell-bg {
|
|
16
|
-
background-color: var(--salt-
|
|
16
|
+
background-color: var(--salt-sentiment-neutral-track);
|
|
17
17
|
width: 100%;
|
|
18
18
|
height: 2px;
|
|
19
19
|
display: inline-block;
|
|
@@ -23,7 +23,7 @@ const css = `
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
.vuuProgressCell-bar {
|
|
26
|
-
background-color: var(--salt-
|
|
26
|
+
background-color: var(--salt-sentiment-accent-background);
|
|
27
27
|
height: 100%;
|
|
28
28
|
transform: translateX(var(--progress-bar-pct, -100%));
|
|
29
29
|
width: 100%;
|
|
@@ -5,15 +5,15 @@ const css = `
|
|
|
5
5
|
--vuuFilterEditor-fontFamily: var(--salt-typography-fontFamily);
|
|
6
6
|
--vuuFilterEditor-fontSize: var(--salt-text-fontSize);
|
|
7
7
|
--vuuFilterEditor-cursorColor: var(--salt-content-secondary-foreground);
|
|
8
|
-
--vuuFilterEditor-selectionBackground: var(--salt-
|
|
8
|
+
--vuuFilterEditor-selectionBackground: var(--salt-selectable-background-selected);
|
|
9
9
|
--vuuFilterEditor-tooltipBackground: var(--salt-container-primary-background);
|
|
10
|
-
--vuuFilterEditor-tooltipBorder: solid 1px var(--vuu-color-purple
|
|
10
|
+
--vuuFilterEditor-tooltipBorder: solid 1px var(--vuu-color-purple);
|
|
11
11
|
--vuuFilterEditor-tooltipElevation: var(--salt-overlayable-shadow-popout);
|
|
12
12
|
--vuuFilterEditor-suggestion-selectedBackground: var(--vuu-color-gray-10);
|
|
13
13
|
--vuuFilterEditor-suggestion-selectedColor: var(--salt-content-primary-foreground);
|
|
14
14
|
--vuuFilterEditor-suggestion-detailColor: var(--salt-content-secondary-foreground-disabled);
|
|
15
15
|
--vuuFilterEditor-suggestion-height: 24px;
|
|
16
|
-
--vuuFilterEditor-variableColor: var(--vuu-color-purple
|
|
16
|
+
--vuuFilterEditor-variableColor: var(--vuu-color-purple);
|
|
17
17
|
box-sizing: border-box;
|
|
18
18
|
align-items: center;
|
|
19
19
|
height: 30px;
|
|
@@ -72,13 +72,13 @@ const css = `
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
.vuuFunctionDoc .example-container {
|
|
75
|
-
background-color: var(--
|
|
75
|
+
background-color: var(--salt-color-gray-100);
|
|
76
76
|
margin: 6px 0;
|
|
77
77
|
padding: 3px;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
.vuuFunctionDoc .example-expression {
|
|
81
|
-
color: var(--
|
|
81
|
+
color: var(--salt-color-gray-800);
|
|
82
82
|
font-family: var(--salt-typography-fontFamily-code);
|
|
83
83
|
padding: 8px;
|
|
84
84
|
font-weight: 500;
|
|
@@ -51,8 +51,9 @@ const isExportableColumn = (descriptor)=>{
|
|
|
51
51
|
const exportCsvTemplate = async (dataSource, options = {})=>{
|
|
52
52
|
const { filename = "template.csv", excludeColumns = [], columns, overrides, timeout = DEFAULT_TEMPLATE_TIMEOUT, onError, onSuccess } = options;
|
|
53
53
|
const targetColumnNames = columns ? columns.filter((col)=>"string" == typeof col ? true : isExportableColumn(col) && "client" !== col.source).map((col)=>"string" == typeof col ? col : col.name) : void 0;
|
|
54
|
-
const
|
|
55
|
-
|
|
54
|
+
const targetColumns = targetColumnNames ?? overrides?.columns;
|
|
55
|
+
const sessionOverrides = overrides ?? (targetColumns ? {
|
|
56
|
+
columns: targetColumns
|
|
56
57
|
} : void 0);
|
|
57
58
|
if (!isSessionTable(dataSource.table) && dataSource.createSessionDataSource && "initialising" !== dataSource.status && "unsubscribed" !== dataSource.status) try {
|
|
58
59
|
const sessionDataSource = await dataSource.createSessionDataSource("Empty", "export", sessionOverrides);
|
|
@@ -80,7 +81,16 @@ const exportCsvTemplate = async (dataSource, options = {})=>{
|
|
|
80
81
|
}, (message)=>{
|
|
81
82
|
if ("subscribed" === message.type) {
|
|
82
83
|
const { columns: subColumns } = message;
|
|
83
|
-
const exportCols = subColumns.filter((name)=>!excluded.has(name));
|
|
84
|
+
const exportCols = targetColumns ? targetColumns.filter((name)=>!excluded.has(name)) : subColumns.filter((name)=>!excluded.has(name));
|
|
85
|
+
if (0 === exportCols.length) {
|
|
86
|
+
cleanup();
|
|
87
|
+
const error = new Error("exportCsvTemplate: no columns available for export");
|
|
88
|
+
if (onError) {
|
|
89
|
+
onError(error);
|
|
90
|
+
resolve();
|
|
91
|
+
} else reject(error);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
84
94
|
const header = exportCols.map(csvCell).join(",");
|
|
85
95
|
triggerCsvDownload(`${header}\r\n`, filename);
|
|
86
96
|
cleanup();
|
|
@@ -93,7 +103,6 @@ const exportCsvTemplate = async (dataSource, options = {})=>{
|
|
|
93
103
|
console.warn("[exportCsvTemplate] createSessionDataSource failed, falling back to tableSchema", error);
|
|
94
104
|
}
|
|
95
105
|
const schema = dataSource.tableSchema;
|
|
96
|
-
const targetColumns = targetColumnNames ?? overrides?.columns;
|
|
97
106
|
if (void 0 !== targetColumns) {
|
|
98
107
|
if (schema) {
|
|
99
108
|
const schemaColumnNames = new Set(schema.columns.map((col)=>col.name));
|
|
@@ -20,8 +20,8 @@ const css = `
|
|
|
20
20
|
max-width: 480px;
|
|
21
21
|
max-height: 120px;
|
|
22
22
|
padding: var(--salt-spacing-100) var(--salt-spacing-200);
|
|
23
|
-
background-color:
|
|
24
|
-
border-radius: var(--salt-
|
|
23
|
+
background-color: var(--salt-status-error-background);
|
|
24
|
+
border-radius: var(--salt-palette-corner);
|
|
25
25
|
text-align: left;
|
|
26
26
|
overflow-y: auto;
|
|
27
27
|
}
|
|
@@ -33,9 +33,9 @@ const css = `
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
.vuuCsvUpload-errorItem {
|
|
36
|
-
font-size: var(--salt-text-fontSize
|
|
37
|
-
color: var(--salt-status-error-foreground);
|
|
38
|
-
line-height: var(--salt-text-lineHeight
|
|
36
|
+
font-size: var(--salt-text-label-fontSize);
|
|
37
|
+
color: var(--salt-status-error-foreground-informative);
|
|
38
|
+
line-height: var(--salt-text-label-lineHeight);
|
|
39
39
|
word-break: break-word;
|
|
40
40
|
margin-bottom: var(--salt-spacing-50);
|
|
41
41
|
}
|
|
@@ -50,8 +50,8 @@ const css = `
|
|
|
50
50
|
|
|
51
51
|
.vuuCsvUpload-errors {
|
|
52
52
|
border: solid 1px var(--salt-status-error-borderColor);
|
|
53
|
-
border-radius: var(--salt-
|
|
54
|
-
color: var(--salt-status-error-foreground);
|
|
53
|
+
border-radius: var(--salt-palette-corner);
|
|
54
|
+
color: var(--salt-status-error-foreground-informative);
|
|
55
55
|
gap: var(--salt-spacing-100);
|
|
56
56
|
padding: var(--salt-spacing-200);
|
|
57
57
|
display: grid;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isRpcError } from "@vuu-ui/vuu-utils";
|
|
1
|
+
import { isRpcError, metadataKeys } from "@vuu-ui/vuu-utils";
|
|
2
2
|
import { CSV_FIRST_DATA_ROW_NUMBER } from "./csv-constants.js";
|
|
3
3
|
const isRecord = (value)=>"object" == typeof value && null !== value;
|
|
4
4
|
const toErrorMessage = (error)=>error instanceof Error ? error.message : String(error);
|
|
@@ -56,4 +56,49 @@ const executeBatchRpcCalls = async (items, executor, errorFormatter)=>{
|
|
|
56
56
|
results
|
|
57
57
|
};
|
|
58
58
|
};
|
|
59
|
-
|
|
59
|
+
const getInlineRowErrorMessage = (result)=>{
|
|
60
|
+
if (isRecord(result) && "data" in result && isRecord(result.data)) {
|
|
61
|
+
const data = result.data;
|
|
62
|
+
const msg = data.vuuMsg ?? data.msg;
|
|
63
|
+
if ("string" == typeof msg && "" !== msg.trim()) return msg.trim();
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const getRowVuuMsgError = (row, vuuMsgDataIndex, vuuRowNumDataIndex)=>{
|
|
67
|
+
if (-1 === vuuMsgDataIndex) return;
|
|
68
|
+
const msg = Array.isArray(row) ? row[vuuMsgDataIndex] : row?.vuuMsg;
|
|
69
|
+
if ("string" == typeof msg && "" !== msg.trim()) {
|
|
70
|
+
const rowNum = -1 !== vuuRowNumDataIndex && void 0 !== row[vuuRowNumDataIndex] ? Number(row[vuuRowNumDataIndex]) : Number(row[metadataKeys.IDX]) + CSV_FIRST_DATA_ROW_NUMBER;
|
|
71
|
+
return {
|
|
72
|
+
rowNum,
|
|
73
|
+
message: msg.trim()
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
const waitForSessionErrors = (isRemote, sessionErrors, receivedRowKeys, expectedRowCount, listeners, timeoutMs = 500)=>{
|
|
78
|
+
if (sessionErrors.size > 0 || !isRemote) return Promise.resolve([
|
|
79
|
+
...sessionErrors.values()
|
|
80
|
+
]);
|
|
81
|
+
return new Promise((resolve)=>{
|
|
82
|
+
let timeoutId;
|
|
83
|
+
const onUpdate = ()=>{
|
|
84
|
+
if (sessionErrors.size > 0 || receivedRowKeys.size >= expectedRowCount) {
|
|
85
|
+
cleanup();
|
|
86
|
+
resolve([
|
|
87
|
+
...sessionErrors.values()
|
|
88
|
+
]);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const cleanup = ()=>{
|
|
92
|
+
clearTimeout(timeoutId);
|
|
93
|
+
listeners.delete(onUpdate);
|
|
94
|
+
};
|
|
95
|
+
listeners.add(onUpdate);
|
|
96
|
+
timeoutId = setTimeout(()=>{
|
|
97
|
+
cleanup();
|
|
98
|
+
resolve([
|
|
99
|
+
...sessionErrors.values()
|
|
100
|
+
]);
|
|
101
|
+
}, timeoutMs);
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
export { buildRowErrorMessage, createUploadError, executeBatchRpcCalls, getInlineRowErrorMessage, getRowVuuMsgError, hasFileParseErrors, isCsvParseError, mergeValidationWithParseErrors, normalizeTableData, toErrorMessage, toValidationErrorsFromParseRowErrors, waitForSessionErrors };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useData } from "@vuu-ui/vuu-utils";
|
|
2
|
+
import { useEffect, useMemo, useState } from "react";
|
|
3
|
+
const useImportSchema = ({ dataSource, importSchema, importTable })=>{
|
|
4
|
+
const { getServerAPI } = useData();
|
|
5
|
+
const [fetchedImportSchema, setFetchedImportSchema] = useState();
|
|
6
|
+
useEffect(()=>{
|
|
7
|
+
if (importSchema || void 0 === importTable) return void setFetchedImportSchema(void 0);
|
|
8
|
+
let cancelled = false;
|
|
9
|
+
(async ()=>{
|
|
10
|
+
try {
|
|
11
|
+
const server = await getServerAPI();
|
|
12
|
+
const tableSchema = await server.getTableSchema(importTable);
|
|
13
|
+
if (!cancelled) setFetchedImportSchema(tableSchema);
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.error("[useImportSchema] failed to fetch import table schema", error);
|
|
16
|
+
}
|
|
17
|
+
})();
|
|
18
|
+
return ()=>{
|
|
19
|
+
cancelled = true;
|
|
20
|
+
};
|
|
21
|
+
}, [
|
|
22
|
+
getServerAPI,
|
|
23
|
+
importSchema,
|
|
24
|
+
importTable
|
|
25
|
+
]);
|
|
26
|
+
const resolvedImportSchema = importSchema ?? fetchedImportSchema;
|
|
27
|
+
const sessionOverrides = useMemo(()=>{
|
|
28
|
+
const columns = resolvedImportSchema?.columns.map(({ name })=>name);
|
|
29
|
+
return columns || importTable ? {
|
|
30
|
+
columns,
|
|
31
|
+
table: importTable
|
|
32
|
+
} : void 0;
|
|
33
|
+
}, [
|
|
34
|
+
resolvedImportSchema,
|
|
35
|
+
importTable
|
|
36
|
+
]);
|
|
37
|
+
const schema = importTable ? resolvedImportSchema : resolvedImportSchema ?? dataSource.tableSchema;
|
|
38
|
+
return {
|
|
39
|
+
resolvedImportSchema,
|
|
40
|
+
schema,
|
|
41
|
+
sessionOverrides
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
export { useImportSchema };
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { EditSession } from "@vuu-ui/vuu-data-editing";
|
|
2
|
+
import { Range, buildColumnMap, isRpcError, isSessionTable, metadataKeys } from "@vuu-ui/vuu-utils";
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
|
+
import { buildRowErrorMessage, getInlineRowErrorMessage, getRowVuuMsgError, toErrorMessage, waitForSessionErrors } from "../parse/csv-upload-utils.js";
|
|
5
|
+
import { CSV_FIRST_DATA_ROW_NUMBER } from "../parse/csv-constants.js";
|
|
6
|
+
const useImportSession = ({ dataSource, sessionOverrides, rowDefaults, processingPromiseRef, onImportSessionEnded })=>{
|
|
7
|
+
const sessionErrorsRef = useRef(new Map());
|
|
8
|
+
const receivedRowKeysRef = useRef(new Set());
|
|
9
|
+
const sessionRowUpdateListenersRef = useRef(new Set());
|
|
10
|
+
const importDataSource = useMemo(()=>({
|
|
11
|
+
tableSchema: dataSource.tableSchema,
|
|
12
|
+
createSessionDataSource: async (copyOption, sessionType)=>{
|
|
13
|
+
if (!dataSource.createSessionDataSource) throw Error("[useCsvUpload] dataSource does not support createSessionDataSource");
|
|
14
|
+
const sessionDs = await dataSource.createSessionDataSource(copyOption, sessionType, sessionOverrides);
|
|
15
|
+
if (!sessionDs) throw Error("[useCsvUpload] Failed to create session datasource");
|
|
16
|
+
if (!sessionDs.columns.includes("vuuMsg")) sessionDs.columns = sessionDs.columns.concat("vuuMsg");
|
|
17
|
+
const columnMap = buildColumnMap(sessionDs.columns);
|
|
18
|
+
const vuuMsgDataIndex = columnMap.vuuMsg ?? -1;
|
|
19
|
+
const vuuRowNumDataIndex = columnMap.vuuRowNum ?? -1;
|
|
20
|
+
const handleSessionMessage = (message)=>{
|
|
21
|
+
if ("viewport-update" === message.type && message.rows) {
|
|
22
|
+
for (const row of message.rows){
|
|
23
|
+
const rowKey = row[metadataKeys.KEY] ?? row[metadataKeys.IDX];
|
|
24
|
+
receivedRowKeysRef.current.add(rowKey);
|
|
25
|
+
const error = getRowVuuMsgError(row, vuuMsgDataIndex, vuuRowNumDataIndex);
|
|
26
|
+
if (error) sessionErrorsRef.current.set(rowKey, error);
|
|
27
|
+
}
|
|
28
|
+
for (const listener of sessionRowUpdateListenersRef.current)listener();
|
|
29
|
+
} else if ("viewport-clear" === message.type) {
|
|
30
|
+
sessionErrorsRef.current.clear();
|
|
31
|
+
receivedRowKeysRef.current.clear();
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
if (sessionDs.isRemote) return new Promise((resolve, reject)=>{
|
|
35
|
+
const handleSubscribed = ()=>{
|
|
36
|
+
sessionDs.removeListener("subscribed", handleSubscribed);
|
|
37
|
+
resolve(sessionDs);
|
|
38
|
+
};
|
|
39
|
+
sessionDs.on("subscribed", handleSubscribed);
|
|
40
|
+
try {
|
|
41
|
+
sessionDs.subscribe({
|
|
42
|
+
range: Range(0, 0)
|
|
43
|
+
}, handleSessionMessage);
|
|
44
|
+
} catch (err) {
|
|
45
|
+
sessionDs.removeListener("subscribed", handleSubscribed);
|
|
46
|
+
reject(err);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
if ("function" == typeof sessionDs.subscribe && "initialising" === sessionDs.status) try {
|
|
50
|
+
sessionDs.subscribe({
|
|
51
|
+
range: Range(0, 0)
|
|
52
|
+
}, handleSessionMessage);
|
|
53
|
+
} catch {}
|
|
54
|
+
return sessionDs;
|
|
55
|
+
}
|
|
56
|
+
}), [
|
|
57
|
+
dataSource,
|
|
58
|
+
sessionOverrides
|
|
59
|
+
]);
|
|
60
|
+
const editSession = useMemo(()=>new EditSession({
|
|
61
|
+
dataSource: importDataSource,
|
|
62
|
+
editSessionApi: "createSessionDataSource",
|
|
63
|
+
rowDefaults
|
|
64
|
+
}), [
|
|
65
|
+
importDataSource,
|
|
66
|
+
rowDefaults
|
|
67
|
+
]);
|
|
68
|
+
const ownsEditSessionRef = useRef(true);
|
|
69
|
+
const sessionDataSourceRef = useRef(void 0);
|
|
70
|
+
const [sessionTable, setSessionTable] = useState();
|
|
71
|
+
useEffect(()=>()=>{
|
|
72
|
+
const processingPromise = processingPromiseRef?.current;
|
|
73
|
+
(async ()=>{
|
|
74
|
+
try {
|
|
75
|
+
await processingPromise;
|
|
76
|
+
} finally{
|
|
77
|
+
if (ownsEditSessionRef.current) try {
|
|
78
|
+
const sessionDs = sessionDataSourceRef.current ?? editSession.sessionDataSource;
|
|
79
|
+
if (sessionDs?.status !== "unsubscribed") await editSession.end(false);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.error("[useCsvUpload] failed to discard edit session during cleanup", error);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
})();
|
|
85
|
+
}, [
|
|
86
|
+
editSession,
|
|
87
|
+
processingPromiseRef
|
|
88
|
+
]);
|
|
89
|
+
const setActiveSessionDataSource = useCallback((sessionDataSource)=>{
|
|
90
|
+
sessionDataSourceRef.current = sessionDataSource;
|
|
91
|
+
const table = sessionDataSource?.table;
|
|
92
|
+
setSessionTable(table && isSessionTable(table) ? table : void 0);
|
|
93
|
+
}, []);
|
|
94
|
+
const endEditSessionAndNotify = useCallback(async (save, reason)=>{
|
|
95
|
+
ownsEditSessionRef.current = false;
|
|
96
|
+
const sessionDataSource = sessionDataSourceRef.current;
|
|
97
|
+
if (!sessionDataSource) throw Error("CsvUpload has no active edit session.");
|
|
98
|
+
if (!sessionDataSource.endEditSession) throw Error("CsvUpload requires the session datasource to support endEditSession.");
|
|
99
|
+
const currentSessionTable = sessionDataSource.table;
|
|
100
|
+
try {
|
|
101
|
+
await editSession.end(save);
|
|
102
|
+
} finally{
|
|
103
|
+
if ("unsubscribed" !== sessionDataSource.status && "function" == typeof sessionDataSource.unsubscribe) sessionDataSource.unsubscribe();
|
|
104
|
+
setActiveSessionDataSource(void 0);
|
|
105
|
+
}
|
|
106
|
+
onImportSessionEnded?.({
|
|
107
|
+
reason,
|
|
108
|
+
sessionTable: currentSessionTable && isSessionTable(currentSessionTable) ? currentSessionTable : void 0
|
|
109
|
+
});
|
|
110
|
+
}, [
|
|
111
|
+
editSession,
|
|
112
|
+
onImportSessionEnded,
|
|
113
|
+
setActiveSessionDataSource
|
|
114
|
+
]);
|
|
115
|
+
const beginEditSession = useCallback(async ()=>{
|
|
116
|
+
sessionErrorsRef.current.clear();
|
|
117
|
+
receivedRowKeysRef.current.clear();
|
|
118
|
+
ownsEditSessionRef.current = true;
|
|
119
|
+
const sessionDataSource = await editSession.begin("Empty", "import");
|
|
120
|
+
const sessionVuuTable = sessionDataSource?.table;
|
|
121
|
+
if (void 0 === sessionDataSource || void 0 === sessionVuuTable || !isSessionTable(sessionVuuTable)) throw Error("CsvUpload createSessionDataSource returned no session datasource.");
|
|
122
|
+
setActiveSessionDataSource(sessionDataSource);
|
|
123
|
+
return sessionDataSource;
|
|
124
|
+
}, [
|
|
125
|
+
editSession,
|
|
126
|
+
setActiveSessionDataSource
|
|
127
|
+
]);
|
|
128
|
+
const closePendingEditSession = useCallback(async (save)=>{
|
|
129
|
+
if (void 0 === sessionDataSourceRef.current) return;
|
|
130
|
+
await endEditSessionAndNotify(save, save ? "saved" : "discarded");
|
|
131
|
+
}, [
|
|
132
|
+
endEditSessionAndNotify
|
|
133
|
+
]);
|
|
134
|
+
const releaseEditSessionOwnership = useCallback(()=>{
|
|
135
|
+
ownsEditSessionRef.current = false;
|
|
136
|
+
}, []);
|
|
137
|
+
const addAllRows = useCallback(async (mergedValidation, isCancelled)=>{
|
|
138
|
+
const vuuMsgByRow = new Map();
|
|
139
|
+
for (const { rowNum, column, message } of mergedValidation.errors){
|
|
140
|
+
if (rowNum < CSV_FIRST_DATA_ROW_NUMBER) continue;
|
|
141
|
+
const existing = vuuMsgByRow.get(rowNum);
|
|
142
|
+
const columnError = `${column}: ${message}`;
|
|
143
|
+
vuuMsgByRow.set(rowNum, existing ? `${existing}; ${columnError}` : columnError);
|
|
144
|
+
}
|
|
145
|
+
const parsedRowCount = mergedValidation.rows.length;
|
|
146
|
+
const unparsedErrorRows = [
|
|
147
|
+
...vuuMsgByRow.keys()
|
|
148
|
+
].filter((rowNum)=>rowNum - CSV_FIRST_DATA_ROW_NUMBER >= parsedRowCount).map((rowNum)=>({
|
|
149
|
+
rowNum,
|
|
150
|
+
rowData: {},
|
|
151
|
+
vuuMsg: vuuMsgByRow.get(rowNum) ?? ""
|
|
152
|
+
}));
|
|
153
|
+
const allRows = [
|
|
154
|
+
...mergedValidation.rows.map((rowData, idx)=>({
|
|
155
|
+
rowNum: idx + CSV_FIRST_DATA_ROW_NUMBER,
|
|
156
|
+
rowData: rowData ?? {},
|
|
157
|
+
vuuMsg: vuuMsgByRow.get(idx + CSV_FIRST_DATA_ROW_NUMBER) ?? ""
|
|
158
|
+
})),
|
|
159
|
+
...unparsedErrorRows
|
|
160
|
+
];
|
|
161
|
+
const rpcErrors = [];
|
|
162
|
+
for (const { rowNum, rowData, vuuMsg } of allRows){
|
|
163
|
+
if (isCancelled()) return false;
|
|
164
|
+
try {
|
|
165
|
+
const payload = vuuMsg ? {
|
|
166
|
+
vuuRowNum: rowNum,
|
|
167
|
+
vuuMsg
|
|
168
|
+
} : {
|
|
169
|
+
...rowData,
|
|
170
|
+
vuuRowNum: rowNum,
|
|
171
|
+
vuuMsg
|
|
172
|
+
};
|
|
173
|
+
const result = await editSession.addRow(payload);
|
|
174
|
+
if (isRpcError(result)) throw Error(result.errorMessage);
|
|
175
|
+
if ("string" == typeof result) throw Error(result);
|
|
176
|
+
const inlineMsg = getInlineRowErrorMessage(result);
|
|
177
|
+
if (inlineMsg) sessionErrorsRef.current.set(rowNum, {
|
|
178
|
+
rowNum,
|
|
179
|
+
message: inlineMsg
|
|
180
|
+
});
|
|
181
|
+
} catch (error) {
|
|
182
|
+
rpcErrors.push(`${0 === rowNum ? "Header" : `Row ${rowNum}`}: ${toErrorMessage(error)}`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (rpcErrors.length > 0) throw Error(buildRowErrorMessage("Import failed", rpcErrors));
|
|
186
|
+
return allRows.length;
|
|
187
|
+
}, [
|
|
188
|
+
editSession
|
|
189
|
+
]);
|
|
190
|
+
const checkSessionTableErrors = useCallback(async (sessionDs, expectedRowCount)=>waitForSessionErrors(sessionDs.isRemote ?? false, sessionErrorsRef.current, receivedRowKeysRef.current, expectedRowCount, sessionRowUpdateListenersRef.current), []);
|
|
191
|
+
return {
|
|
192
|
+
addAllRows,
|
|
193
|
+
beginEditSession,
|
|
194
|
+
checkSessionTableErrors,
|
|
195
|
+
closePendingEditSession,
|
|
196
|
+
editSession,
|
|
197
|
+
endEditSessionAndNotify,
|
|
198
|
+
releaseEditSessionOwnership,
|
|
199
|
+
sessionDataSourceRef,
|
|
200
|
+
sessionTable,
|
|
201
|
+
setActiveSessionDataSource
|
|
202
|
+
};
|
|
203
|
+
};
|
|
204
|
+
export { useImportSession };
|
|
@@ -1,203 +1,36 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
1
|
+
import { Range, isSessionTable } from "@vuu-ui/vuu-utils";
|
|
2
|
+
import { useCallback, useMemo, useRef, useState } from "react";
|
|
4
3
|
import { parseCsv } from "./parse/csv-parse.js";
|
|
5
|
-
import { validateCsvAgainstSchema } from "./parse/csv-schema-validation.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
4
|
+
import { CsvValidationErrorEnum, validateCsvAgainstSchema } from "./parse/csv-schema-validation.js";
|
|
5
|
+
import { createUploadError, hasFileParseErrors, isCsvParseError, mergeValidationWithParseErrors, toErrorMessage } from "./parse/csv-upload-utils.js";
|
|
6
|
+
import { useImportSchema } from "./session/useImportSchema.js";
|
|
7
|
+
import { useImportSession } from "./session/useImportSession.js";
|
|
8
8
|
const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importTable, onImportSessionEnded, onImportSessionReady, onError, onImported, onPreview, onProcessingStarted, maxRows, parseOptions, rowDefaults, validators })=>{
|
|
9
|
-
const { getServerAPI } = useData();
|
|
10
9
|
const [validation, setValidation] = useState();
|
|
11
|
-
const [sessionTable, setSessionTable] = useState();
|
|
12
10
|
const [isProcessingFile, setIsProcessingFile] = useState(false);
|
|
13
11
|
const [isImporting, setIsImporting] = useState(false);
|
|
14
|
-
const [fetchedImportSchema, setFetchedImportSchema] = useState();
|
|
15
12
|
const [error, setError] = useState();
|
|
13
|
+
const operationIdRef = useRef(0);
|
|
14
|
+
const processingPromiseRef = useRef(void 0);
|
|
16
15
|
const handleError = useCallback((errResult)=>{
|
|
17
16
|
setError(errResult);
|
|
18
17
|
onError?.(errResult);
|
|
19
18
|
}, [
|
|
20
19
|
onError
|
|
21
20
|
]);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
let cancelled = false;
|
|
25
|
-
(async ()=>{
|
|
26
|
-
try {
|
|
27
|
-
const server = await getServerAPI();
|
|
28
|
-
const tableSchema = await server.getTableSchema(importTable);
|
|
29
|
-
if (!cancelled) setFetchedImportSchema(tableSchema);
|
|
30
|
-
} catch (error) {
|
|
31
|
-
console.error("[useCsvUpload] failed to fetch import table schema", error);
|
|
32
|
-
}
|
|
33
|
-
})();
|
|
34
|
-
return ()=>{
|
|
35
|
-
cancelled = true;
|
|
36
|
-
};
|
|
37
|
-
}, [
|
|
38
|
-
getServerAPI,
|
|
21
|
+
const { schema, sessionOverrides } = useImportSchema({
|
|
22
|
+
dataSource,
|
|
39
23
|
importSchema,
|
|
40
24
|
importTable
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
const sessionOverrides = useMemo(()=>{
|
|
44
|
-
const columns = resolvedImportSchema?.columns.map(({ name })=>name);
|
|
45
|
-
return columns || importTable ? {
|
|
46
|
-
columns,
|
|
47
|
-
table: importTable
|
|
48
|
-
} : void 0;
|
|
49
|
-
}, [
|
|
50
|
-
resolvedImportSchema,
|
|
51
|
-
importTable
|
|
52
|
-
]);
|
|
53
|
-
const importDataSource = useMemo(()=>({
|
|
54
|
-
tableSchema: dataSource.tableSchema,
|
|
55
|
-
createSessionDataSource: async (copyOption, sessionType)=>{
|
|
56
|
-
if (!dataSource.createSessionDataSource) throw Error("[useCsvUpload] dataSource does not support createSessionDataSource");
|
|
57
|
-
const sessionDs = await dataSource.createSessionDataSource(copyOption, sessionType, sessionOverrides);
|
|
58
|
-
if (!sessionDs) throw Error("[useCsvUpload] Failed to create session datasource");
|
|
59
|
-
if (!sessionDs.columns.includes("vuuMsg")) sessionDs.columns = sessionDs.columns.concat("vuuMsg");
|
|
60
|
-
if (sessionDs.isRemote) return new Promise((resolve, reject)=>{
|
|
61
|
-
const handleSubscribed = ()=>{
|
|
62
|
-
sessionDs.removeListener("subscribed", handleSubscribed);
|
|
63
|
-
resolve(sessionDs);
|
|
64
|
-
};
|
|
65
|
-
sessionDs.on("subscribed", handleSubscribed);
|
|
66
|
-
try {
|
|
67
|
-
sessionDs.subscribe({
|
|
68
|
-
range: Range(0, 0)
|
|
69
|
-
}, ()=>{});
|
|
70
|
-
} catch (err) {
|
|
71
|
-
sessionDs.removeListener("subscribed", handleSubscribed);
|
|
72
|
-
reject(err);
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
return sessionDs;
|
|
76
|
-
}
|
|
77
|
-
}), [
|
|
25
|
+
});
|
|
26
|
+
const { addAllRows, beginEditSession, checkSessionTableErrors, closePendingEditSession, editSession, endEditSessionAndNotify, releaseEditSessionOwnership, sessionDataSourceRef, sessionTable, setActiveSessionDataSource } = useImportSession({
|
|
78
27
|
dataSource,
|
|
79
|
-
sessionOverrides
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
rowDefaults
|
|
85
|
-
}), [
|
|
86
|
-
importDataSource,
|
|
87
|
-
rowDefaults
|
|
88
|
-
]);
|
|
89
|
-
const ownsEditSessionRef = useRef(true);
|
|
90
|
-
const operationIdRef = useRef(0);
|
|
91
|
-
const processingPromiseRef = useRef(void 0);
|
|
92
|
-
const sessionDataSourceRef = useRef(void 0);
|
|
93
|
-
useEffect(()=>()=>{
|
|
94
|
-
operationIdRef.current++;
|
|
95
|
-
const processingPromise = processingPromiseRef.current;
|
|
96
|
-
(async ()=>{
|
|
97
|
-
try {
|
|
98
|
-
await processingPromise;
|
|
99
|
-
} finally{
|
|
100
|
-
if (ownsEditSessionRef.current) try {
|
|
101
|
-
await editSession.end(false);
|
|
102
|
-
} catch (error) {
|
|
103
|
-
console.error("[useCsvUpload] failed to discard edit session during cleanup", error);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
})();
|
|
107
|
-
}, [
|
|
108
|
-
editSession
|
|
109
|
-
]);
|
|
110
|
-
const setActiveSessionDataSource = useCallback((sessionDataSource)=>{
|
|
111
|
-
sessionDataSourceRef.current = sessionDataSource;
|
|
112
|
-
const table = sessionDataSource?.table;
|
|
113
|
-
setSessionTable(table && isSessionTable(table) ? table : void 0);
|
|
114
|
-
}, []);
|
|
115
|
-
const endEditSessionAndNotify = useCallback(async (save, reason)=>{
|
|
116
|
-
const sessionDataSource = sessionDataSourceRef.current;
|
|
117
|
-
if (!sessionDataSource) throw Error("CsvUpload has no active edit session.");
|
|
118
|
-
if (!sessionDataSource.endEditSession) throw Error("CsvUpload requires the session datasource to support endEditSession.");
|
|
119
|
-
const currentSessionTable = sessionDataSource.table;
|
|
120
|
-
try {
|
|
121
|
-
await editSession.end(save);
|
|
122
|
-
} finally{
|
|
123
|
-
if ("unsubscribed" !== sessionDataSource.status && "function" == typeof sessionDataSource.unsubscribe) sessionDataSource.unsubscribe();
|
|
124
|
-
setActiveSessionDataSource(void 0);
|
|
125
|
-
}
|
|
126
|
-
onImportSessionEnded?.({
|
|
127
|
-
reason,
|
|
128
|
-
sessionTable: currentSessionTable && isSessionTable(currentSessionTable) ? currentSessionTable : void 0
|
|
129
|
-
});
|
|
130
|
-
}, [
|
|
131
|
-
editSession,
|
|
132
|
-
onImportSessionEnded,
|
|
133
|
-
setActiveSessionDataSource
|
|
134
|
-
]);
|
|
28
|
+
sessionOverrides,
|
|
29
|
+
rowDefaults,
|
|
30
|
+
processingPromiseRef,
|
|
31
|
+
onImportSessionEnded
|
|
32
|
+
});
|
|
135
33
|
const table = dataSource.table;
|
|
136
|
-
const schema = importTable ? resolvedImportSchema : resolvedImportSchema ?? dataSource.tableSchema;
|
|
137
|
-
const addAllRows = useCallback(async (mergedValidation, operationId)=>{
|
|
138
|
-
const vuuMsgByRow = new Map();
|
|
139
|
-
for (const { rowNum, column, message } of mergedValidation.errors){
|
|
140
|
-
if (rowNum < CSV_FIRST_DATA_ROW_NUMBER) continue;
|
|
141
|
-
const existing = vuuMsgByRow.get(rowNum);
|
|
142
|
-
const columnError = `${column}: ${message}`;
|
|
143
|
-
vuuMsgByRow.set(rowNum, existing ? `${existing}; ${columnError}` : columnError);
|
|
144
|
-
}
|
|
145
|
-
const parsedRowCount = mergedValidation.rows.length;
|
|
146
|
-
const unparsedErrorRows = [
|
|
147
|
-
...vuuMsgByRow.keys()
|
|
148
|
-
].filter((rowNum)=>rowNum - CSV_FIRST_DATA_ROW_NUMBER >= parsedRowCount).map((rowNum)=>({
|
|
149
|
-
rowNum,
|
|
150
|
-
rowData: {},
|
|
151
|
-
vuuMsg: vuuMsgByRow.get(rowNum) ?? ""
|
|
152
|
-
}));
|
|
153
|
-
const allRows = [
|
|
154
|
-
...mergedValidation.rows.map((rowData, idx)=>({
|
|
155
|
-
rowNum: idx + CSV_FIRST_DATA_ROW_NUMBER,
|
|
156
|
-
rowData: rowData ?? {},
|
|
157
|
-
vuuMsg: vuuMsgByRow.get(idx + CSV_FIRST_DATA_ROW_NUMBER) ?? ""
|
|
158
|
-
})),
|
|
159
|
-
...unparsedErrorRows
|
|
160
|
-
];
|
|
161
|
-
const rpcErrors = [];
|
|
162
|
-
for (const { rowNum, rowData, vuuMsg } of allRows){
|
|
163
|
-
if (operationId !== operationIdRef.current) return false;
|
|
164
|
-
try {
|
|
165
|
-
const payload = vuuMsg ? {
|
|
166
|
-
vuuRowNum: rowNum,
|
|
167
|
-
vuuMsg
|
|
168
|
-
} : {
|
|
169
|
-
...rowData,
|
|
170
|
-
vuuRowNum: rowNum,
|
|
171
|
-
vuuMsg
|
|
172
|
-
};
|
|
173
|
-
const result = await editSession.addRow(payload);
|
|
174
|
-
if (isRpcError(result)) throw Error(result.errorMessage);
|
|
175
|
-
if ("string" == typeof result) throw Error(result);
|
|
176
|
-
} catch (error) {
|
|
177
|
-
rpcErrors.push(`${0 === rowNum ? "Header" : `Row ${rowNum}`}: ${toErrorMessage(error)}`);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
if (rpcErrors.length > 0) throw Error(buildRowErrorMessage("Import failed", rpcErrors));
|
|
181
|
-
return true;
|
|
182
|
-
}, [
|
|
183
|
-
editSession
|
|
184
|
-
]);
|
|
185
|
-
const beginEditSession = useCallback(async ()=>{
|
|
186
|
-
const sessionDataSource = await editSession.begin("Empty", "import");
|
|
187
|
-
const sessionVuuTable = sessionDataSource?.table;
|
|
188
|
-
if (void 0 === sessionDataSource || void 0 === sessionVuuTable || !isSessionTable(sessionVuuTable)) throw Error("CsvUpload createSessionDataSource returned no session datasource.");
|
|
189
|
-
setActiveSessionDataSource(sessionDataSource);
|
|
190
|
-
return sessionDataSource;
|
|
191
|
-
}, [
|
|
192
|
-
editSession,
|
|
193
|
-
setActiveSessionDataSource
|
|
194
|
-
]);
|
|
195
|
-
const closePendingEditSession = useCallback(async (save)=>{
|
|
196
|
-
if (void 0 === sessionDataSourceRef.current) return;
|
|
197
|
-
await endEditSessionAndNotify(save, save ? "saved" : "discarded");
|
|
198
|
-
}, [
|
|
199
|
-
endEditSessionAndNotify
|
|
200
|
-
]);
|
|
201
34
|
const cancelImport = useCallback(async ()=>{
|
|
202
35
|
operationIdRef.current++;
|
|
203
36
|
processingPromiseRef.current = void 0;
|
|
@@ -256,8 +89,28 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
256
89
|
if (mergedValidation.rows.length > 0) try {
|
|
257
90
|
const sessionDataSource = await beginEditSession();
|
|
258
91
|
if (operationId !== operationIdRef.current) return;
|
|
259
|
-
const
|
|
260
|
-
if (
|
|
92
|
+
const rowsAddedCount = await addAllRows(mergedValidation, ()=>operationId !== operationIdRef.current);
|
|
93
|
+
if (false === rowsAddedCount) return;
|
|
94
|
+
const expectedRowCount = rowsAddedCount;
|
|
95
|
+
sessionDataSource.range = Range(0, expectedRowCount);
|
|
96
|
+
const sessionErrors = await checkSessionTableErrors(sessionDataSource, expectedRowCount);
|
|
97
|
+
if (operationId !== operationIdRef.current) return;
|
|
98
|
+
if (sessionErrors.length > 0) {
|
|
99
|
+
const serverValidationErrors = sessionErrors.map(({ rowNum, message })=>({
|
|
100
|
+
rowNum,
|
|
101
|
+
column: "*",
|
|
102
|
+
message,
|
|
103
|
+
value: "",
|
|
104
|
+
errorEnum: CsvValidationErrorEnum.CUSTOM_VALIDATION
|
|
105
|
+
}));
|
|
106
|
+
setValidation((prev)=>prev ? {
|
|
107
|
+
...prev,
|
|
108
|
+
errors: [
|
|
109
|
+
...prev.errors,
|
|
110
|
+
...serverValidationErrors
|
|
111
|
+
]
|
|
112
|
+
} : void 0);
|
|
113
|
+
}
|
|
261
114
|
onImportSessionReady?.(sessionDataSource);
|
|
262
115
|
} catch (error) {
|
|
263
116
|
if (void 0 !== sessionDataSourceRef.current) await endEditSessionAndNotify(false, "failed");
|
|
@@ -277,6 +130,7 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
277
130
|
handleError,
|
|
278
131
|
editSession,
|
|
279
132
|
addAllRows,
|
|
133
|
+
checkSessionTableErrors,
|
|
280
134
|
maxRows,
|
|
281
135
|
parseOptions,
|
|
282
136
|
beginEditSession,
|
|
@@ -287,7 +141,8 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
287
141
|
endEditSessionAndNotify,
|
|
288
142
|
schema,
|
|
289
143
|
validators,
|
|
290
|
-
onImportSessionReady
|
|
144
|
+
onImportSessionReady,
|
|
145
|
+
sessionDataSourceRef
|
|
291
146
|
]);
|
|
292
147
|
const handleFiles = useCallback(async (files)=>{
|
|
293
148
|
const file = files[0];
|
|
@@ -355,7 +210,7 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
355
210
|
editSession,
|
|
356
211
|
tableData
|
|
357
212
|
});
|
|
358
|
-
|
|
213
|
+
releaseEditSessionOwnership();
|
|
359
214
|
} else {
|
|
360
215
|
await endEditSessionAndNotify(true, "saved");
|
|
361
216
|
onImported?.({
|
|
@@ -383,6 +238,8 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
383
238
|
onImported,
|
|
384
239
|
onPreview,
|
|
385
240
|
importMode,
|
|
241
|
+
releaseEditSessionOwnership,
|
|
242
|
+
sessionDataSourceRef,
|
|
386
243
|
validation
|
|
387
244
|
]);
|
|
388
245
|
return {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const css = `
|
|
2
2
|
.vuuFreezeControl {
|
|
3
3
|
--freeze-control-flash-duration: .25s;
|
|
4
|
-
--freeze-control-active-button-color: var(--salt-
|
|
5
|
-
--freeze-control-badge-color: var(--salt-
|
|
4
|
+
--freeze-control-active-button-color: var(--salt-status-error-background);
|
|
5
|
+
--freeze-control-badge-color: var(--salt-status-success-background);
|
|
6
6
|
height: fit-content;
|
|
7
7
|
display: inline-flex;
|
|
8
8
|
|
|
@@ -31,7 +31,7 @@ const css = `
|
|
|
31
31
|
|
|
32
32
|
& .vuuFreezeControl-buttonWrapper-active .saltToggleButton {
|
|
33
33
|
background-color: var(--freeze-control-active-button-color);
|
|
34
|
-
color: var(--salt-actionable-
|
|
34
|
+
color: var(--salt-actionable-subtle-foreground-active);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
& .saltToggleButtonGroup.vuuStateButtonGroup {
|
|
@@ -43,7 +43,7 @@ const css = `
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
& .vuuFreezeControl-customBadge {
|
|
46
|
-
color: var(--salt-
|
|
46
|
+
color: var(--salt-content-primary-foreground);
|
|
47
47
|
font-size: var(--salt-text-fontSize);
|
|
48
48
|
height: var(--salt-size-base);
|
|
49
49
|
width: var(--salt-size-base);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const css = `
|
|
2
2
|
.FrozenBanner {
|
|
3
|
-
--freeze-control-active-button-color: var(--salt-
|
|
3
|
+
--freeze-control-active-button-color: var(--salt-status-error-background);
|
|
4
4
|
background-color: var(--freeze-control-active-button-color);
|
|
5
|
-
color: var(--salt-actionable-
|
|
5
|
+
color: var(--salt-actionable-subtle-foreground-active);
|
|
6
6
|
font-size: var(--salt-text-fontSize);
|
|
7
7
|
height: var(--salt-size-base);
|
|
8
8
|
padding: 0 var(--salt-spacing-200);
|
|
@@ -9,4 +9,4 @@ export interface CalculatedColumnPanelProps extends HTMLAttributes<HTMLDivElemen
|
|
|
9
9
|
onChangeServerDataType?: (name: VuuColumnDataType) => void;
|
|
10
10
|
vuuTable: VuuTable;
|
|
11
11
|
}
|
|
12
|
-
export declare const CalculatedColumnPanel: ({ column: columnProp, columnModel, onChangeColumn, onChangeServerDataType: onChangeServerDataTypeProp, vuuTable, }: CalculatedColumnPanelProps) => import("react").JSX.Element;
|
|
12
|
+
export declare const CalculatedColumnPanel: ({ column: columnProp, columnModel, onChangeColumn, onChangeServerDataType: onChangeServerDataTypeProp, vuuTable, }: CalculatedColumnPanelProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { TableCellRendererProps } from "@vuu-ui/vuu-table-types";
|
|
2
|
-
export declare const BackgroundCell: import("react").MemoExoticComponent<({ column, dataRow, }: TableCellRendererProps) => import("react").JSX.Element>;
|
|
2
|
+
export declare const BackgroundCell: import("react").MemoExoticComponent<({ column, dataRow, }: TableCellRendererProps) => import("react/jsx-runtime").JSX.Element>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { ConfigurationEditorProps } from "@vuu-ui/vuu-utils";
|
|
2
|
-
export declare const BackgroundCellConfigurationEditor: ({ column, onChangeRendering, }: ConfigurationEditorProps) => import("react").JSX.Element;
|
|
2
|
+
export declare const BackgroundCellConfigurationEditor: ({ column, onChangeRendering, }: ConfigurationEditorProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,4 +3,4 @@ import { TableCellRendererProps } from "@vuu-ui/vuu-table-types";
|
|
|
3
3
|
* To assign an icon to the cell, give the columndescriptor
|
|
4
4
|
* a className. In css, assign an icon variable to --vuu-svg-icon.
|
|
5
5
|
*/
|
|
6
|
-
export declare const IconButtonCell: ({ column, dataRow }: TableCellRendererProps) => import("react").JSX.Element;
|
|
6
|
+
export declare const IconButtonCell: ({ column, dataRow }: TableCellRendererProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { TableCellRendererProps } from "@vuu-ui/vuu-table-types";
|
|
2
|
-
export declare const DropdownCell: import("react").MemoExoticComponent<({ column, dataRow, editedDuringCurrentSession, onEdit, }: TableCellRendererProps) => import("react").JSX.Element>;
|
|
2
|
+
export declare const DropdownCell: import("react").MemoExoticComponent<({ column, dataRow, editedDuringCurrentSession, onEdit, }: TableCellRendererProps) => import("react/jsx-runtime").JSX.Element>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { TableCellRendererProps } from "@vuu-ui/vuu-table-types";
|
|
2
|
-
export declare const LookupCell: import("react").MemoExoticComponent<({ column, dataRow, }: TableCellRendererProps) => import("react").JSX.Element>;
|
|
2
|
+
export declare const LookupCell: import("react").MemoExoticComponent<({ column, dataRow, }: TableCellRendererProps) => import("react/jsx-runtime").JSX.Element>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { TableCellProps } from "@vuu-ui/vuu-table-types";
|
|
2
|
-
export declare const PctProgressCell: ({ column, dataRow }: TableCellProps) => import("react").JSX.Element;
|
|
2
|
+
export declare const PctProgressCell: ({ column, dataRow }: TableCellProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -7,4 +7,4 @@ export interface ColumnExpressionInputProps extends ExpressionSuggestionConsumer
|
|
|
7
7
|
onSubmitExpression?: ColumnExpressionSubmitHandler;
|
|
8
8
|
source?: string;
|
|
9
9
|
}
|
|
10
|
-
export declare const ColumnExpressionInput: import("react").MemoExoticComponent<({ onChange, onSubmitExpression, source, suggestionProvider, }: ColumnExpressionInputProps) => import("react").JSX.Element>;
|
|
10
|
+
export declare const ColumnExpressionInput: import("react").MemoExoticComponent<({ onChange, onSubmitExpression, source, suggestionProvider, }: ColumnExpressionInputProps) => import("react/jsx-runtime").JSX.Element>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export declare const walkTree: (tree: any, source: any) => void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { FormattingSettingsProps } from "@vuu-ui/vuu-table-types";
|
|
2
|
-
export declare const BaseNumericFormattingSettings: ({ column, onChangeFormatting: onChange, }: FormattingSettingsProps) => import("react").JSX.Element;
|
|
2
|
+
export declare const BaseNumericFormattingSettings: ({ column, onChangeFormatting: onChange, }: FormattingSettingsProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -6,4 +6,4 @@ export interface ColumnFormattingPanelProps extends HTMLAttributes<HTMLDivElemen
|
|
|
6
6
|
column: ColumnDescriptor;
|
|
7
7
|
onChangeRendering: (renderProps: ColumnTypeRendering) => void;
|
|
8
8
|
}
|
|
9
|
-
export declare const ColumnFormattingPanel: ({ availableRenderers, className, column, onChangeFormatting, onChangeColumnType, onChangeRendering, ...htmlAttributes }: ColumnFormattingPanelProps) => import("react").JSX.Element;
|
|
9
|
+
export declare const ColumnFormattingPanel: ({ availableRenderers, className, column, onChangeFormatting, onChangeColumnType, onChangeRendering, ...htmlAttributes }: ColumnFormattingPanelProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,3 +1,2 @@
|
|
|
1
1
|
import { FormattingSettingsProps } from "@vuu-ui/vuu-table-types";
|
|
2
|
-
|
|
3
|
-
export declare const LongTypeFormattingSettings: (props: FormattingSettingsProps) => React.JSX.Element;
|
|
2
|
+
export declare const LongTypeFormattingSettings: (props: FormattingSettingsProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -7,4 +7,4 @@ export interface ColumnMenuProps extends HTMLAttributes<HTMLSpanElement> {
|
|
|
7
7
|
menuActionHandler?: MenuActionHandler<ColumnMenuActionType, ColumnDescriptor>;
|
|
8
8
|
menuPermissions?: ColumnMenuPermissions;
|
|
9
9
|
}
|
|
10
|
-
export declare const ColumnMenu: ({ className, column, menuActionHandler: menuActionHandlerProp, menuPermissions: { allowSort, allowGroup, allowAggregation, allowHide, allowRemove, allowPin, }, }: ColumnMenuProps) => import("react").JSX.Element;
|
|
10
|
+
export declare const ColumnMenu: ({ className, column, menuActionHandler: menuActionHandlerProp, menuPermissions: { allowSort, allowGroup, allowAggregation, allowHide, allowRemove, allowPin, }, }: ColumnMenuProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -2,4 +2,4 @@ import { IconButtonProps } from "@vuu-ui/vuu-ui-controls";
|
|
|
2
2
|
import { ColumnPickerHookProps } from "./useColumnPicker";
|
|
3
3
|
export interface ColumnPickerActionProps extends Partial<IconButtonProps>, ColumnPickerHookProps {
|
|
4
4
|
}
|
|
5
|
-
export declare const ColumnPickerAction: ({ appearance, columnModel, icon, sentiment, ...IconButtonProps }: ColumnPickerActionProps) => import("react").JSX.Element;
|
|
5
|
+
export declare const ColumnPickerAction: ({ appearance, columnModel, icon, sentiment, ...IconButtonProps }: ColumnPickerActionProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -4,4 +4,4 @@ export interface ColumnNameLabelProps {
|
|
|
4
4
|
column: ColumnDescriptor;
|
|
5
5
|
onClick?: MouseEventHandler;
|
|
6
6
|
}
|
|
7
|
-
export declare const ColumnNameLabel: ({ column, onClick }: ColumnNameLabelProps) => import("react").JSX.Element;
|
|
7
|
+
export declare const ColumnNameLabel: ({ column, onClick }: ColumnNameLabelProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -2,4 +2,4 @@ import { ColumnSettingsProps } from "./useColumnSettings";
|
|
|
2
2
|
export interface ColumnSettinsPanelProps extends ColumnSettingsProps {
|
|
3
3
|
onClickEditCalculatedColumn?: () => void;
|
|
4
4
|
}
|
|
5
|
-
export declare const ColumnSettingsPanel: ({ column: columnProp, columnModel, onClickEditCalculatedColumn, onConfigChange, }: ColumnSettinsPanelProps) => import("react").JSX.Element;
|
|
5
|
+
export declare const ColumnSettingsPanel: ({ column: columnProp, columnModel, onClickEditCalculatedColumn, onConfigChange, }: ColumnSettinsPanelProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -62,4 +62,4 @@ export interface CsvUploadProps {
|
|
|
62
62
|
rowDefaults?: RowDefaultDataItemValues;
|
|
63
63
|
validators?: Record<string, CsvColumnValidator>;
|
|
64
64
|
}
|
|
65
|
-
export declare const CsvUpload: (props: CsvUploadProps) => import("react").JSX.Element;
|
|
65
|
+
export declare const CsvUpload: (props: CsvUploadProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -7,4 +7,4 @@ export interface DataUploadPreviewProps extends Omit<HTMLAttributes<HTMLDivEleme
|
|
|
7
7
|
saveLabel?: string;
|
|
8
8
|
tableSchema: TableSchema;
|
|
9
9
|
}
|
|
10
|
-
export declare const DataUploadPreview: ({ className, editSession, onClose, saveLabel, tableSchema, ...htmlAttributes }: DataUploadPreviewProps) => import("react").JSX.Element;
|
|
10
|
+
export declare const DataUploadPreview: ({ className, editSession, onClose, saveLabel, tableSchema, ...htmlAttributes }: DataUploadPreviewProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { VuuRowDataItemType } from "@vuu-ui/vuu-protocol-types";
|
|
2
|
+
import type { DataSourceRow } from "@vuu-ui/vuu-data-types";
|
|
2
3
|
import type { CsvUploadError } from "../CsvUpload";
|
|
3
4
|
import type { CsvParseError } from "./csv-parse";
|
|
4
5
|
import type { CsvValidationError, CsvValidationResult } from "./csv-schema-validation";
|
|
@@ -19,3 +20,11 @@ export type RpcBatchResult = {
|
|
|
19
20
|
results: unknown[];
|
|
20
21
|
};
|
|
21
22
|
export declare const executeBatchRpcCalls: <T>(items: T[], executor: (item: T) => Promise<unknown>, errorFormatter: (item: T, error: string) => string) => Promise<RpcBatchResult>;
|
|
23
|
+
export type SessionRowError = {
|
|
24
|
+
rowNum: number;
|
|
25
|
+
message: string;
|
|
26
|
+
};
|
|
27
|
+
export type SessionRowUpdateListener = () => void;
|
|
28
|
+
export declare const getInlineRowErrorMessage: (result: unknown) => string | undefined;
|
|
29
|
+
export declare const getRowVuuMsgError: (row: DataSourceRow, vuuMsgDataIndex: number, vuuRowNumDataIndex: number) => SessionRowError | undefined;
|
|
30
|
+
export declare const waitForSessionErrors: (isRemote: boolean, sessionErrors: Map<string | number, SessionRowError>, receivedRowKeys: Set<string | number>, expectedRowCount: number, listeners: Set<SessionRowUpdateListener>, timeoutMs?: number) => Promise<SessionRowError[]>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DataSource, SessionDataSourceOverrides, TableSchema } from "@vuu-ui/vuu-data-types";
|
|
2
|
+
import type { VuuTable } from "@vuu-ui/vuu-protocol-types";
|
|
3
|
+
export interface UseImportSchemaProps {
|
|
4
|
+
dataSource: DataSource;
|
|
5
|
+
importSchema?: TableSchema;
|
|
6
|
+
importTable?: VuuTable;
|
|
7
|
+
}
|
|
8
|
+
export interface UseImportSchemaResult {
|
|
9
|
+
resolvedImportSchema: TableSchema | undefined;
|
|
10
|
+
schema: TableSchema | undefined;
|
|
11
|
+
sessionOverrides: SessionDataSourceOverrides | undefined;
|
|
12
|
+
}
|
|
13
|
+
export declare const useImportSchema: ({ dataSource, importSchema, importTable, }: UseImportSchemaProps) => UseImportSchemaResult;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { DataSource, SessionDataSourceOverrides } from "@vuu-ui/vuu-data-types";
|
|
2
|
+
import { EditSession, type RowDefaultDataItemValues } from "@vuu-ui/vuu-data-editing";
|
|
3
|
+
import { type RefObject } from "react";
|
|
4
|
+
import type { CsvValidationResult } from "../parse/csv-schema-validation";
|
|
5
|
+
import { type SessionRowError } from "../parse/csv-upload-utils";
|
|
6
|
+
import type { CsvUploadSessionEndReason, CsvUploadSessionEndResult, CsvUploadSessionTable } from "../CsvUpload";
|
|
7
|
+
export interface UseImportSessionProps {
|
|
8
|
+
dataSource: DataSource;
|
|
9
|
+
sessionOverrides?: SessionDataSourceOverrides;
|
|
10
|
+
rowDefaults?: RowDefaultDataItemValues;
|
|
11
|
+
processingPromiseRef?: RefObject<Promise<void> | undefined>;
|
|
12
|
+
onImportSessionEnded?: (result: CsvUploadSessionEndResult) => void;
|
|
13
|
+
}
|
|
14
|
+
export interface UseImportSessionReturn {
|
|
15
|
+
addAllRows: (mergedValidation: CsvValidationResult, isCancelled: () => boolean) => Promise<number | false>;
|
|
16
|
+
beginEditSession: () => Promise<DataSource>;
|
|
17
|
+
checkSessionTableErrors: (sessionDs: DataSource, expectedRowCount: number) => Promise<SessionRowError[]>;
|
|
18
|
+
closePendingEditSession: (save: boolean) => Promise<void>;
|
|
19
|
+
editSession: EditSession;
|
|
20
|
+
endEditSessionAndNotify: (save: boolean, reason: CsvUploadSessionEndReason) => Promise<void>;
|
|
21
|
+
releaseEditSessionOwnership: () => void;
|
|
22
|
+
sessionDataSourceRef: React.MutableRefObject<DataSource | undefined>;
|
|
23
|
+
sessionTable: CsvUploadSessionTable | undefined;
|
|
24
|
+
setActiveSessionDataSource: (sessionDataSource?: DataSource) => void;
|
|
25
|
+
}
|
|
26
|
+
export declare const useImportSession: ({ dataSource, sessionOverrides, rowDefaults, processingPromiseRef, onImportSessionEnded, }: UseImportSessionProps) => UseImportSessionReturn;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DataSource, TableSchema } from "@vuu-ui/vuu-data-types";
|
|
2
|
-
import {
|
|
2
|
+
import type { RowDefaultDataItemValues } from "@vuu-ui/vuu-data-editing";
|
|
3
3
|
import type { VuuTable } from "@vuu-ui/vuu-protocol-types";
|
|
4
4
|
import { type CsvParseOptions } from "./parse/csv-parse";
|
|
5
5
|
import { type CsvValidationResult, type CsvColumnValidator } from "./parse/csv-schema-validation";
|
|
@@ -14,4 +14,4 @@ export interface DataSourceStatsProps extends DatasourceStatsHookProps, Omit<HTM
|
|
|
14
14
|
selectionActions?: ReactNode;
|
|
15
15
|
tooltrayActions?: ReactNode;
|
|
16
16
|
}
|
|
17
|
-
export declare const DataSourceStats: ({ children, className, dataSource, showRowStats, tooltrayActions, ...htmlAttributes }: DataSourceStatsProps) => import("react").JSX.Element;
|
|
17
|
+
export declare const DataSourceStats: ({ children, className, dataSource, showRowStats, tooltrayActions, ...htmlAttributes }: DataSourceStatsProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -12,4 +12,4 @@ export interface FreezeControlProps extends HTMLAttributes<HTMLDivElement>, Free
|
|
|
12
12
|
*/
|
|
13
13
|
flashDuration?: number;
|
|
14
14
|
}
|
|
15
|
-
export declare const FreezeControl: ({ dataSource, className, newItemsLabel, flashDuration, ...htmlAttributes }: FreezeControlProps) => import("react").JSX.Element;
|
|
15
|
+
export declare const FreezeControl: ({ dataSource, className, newItemsLabel, flashDuration, ...htmlAttributes }: FreezeControlProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,4 +3,4 @@ import { DataSource } from "@vuu-ui/vuu-data-types";
|
|
|
3
3
|
export interface FrozenBannerProps extends HTMLAttributes<HTMLDivElement> {
|
|
4
4
|
dataSource: DataSource;
|
|
5
5
|
}
|
|
6
|
-
export declare const FrozenBanner: ({ dataSource, className, ...htmlAttributes }: FrozenBannerProps) => import("react").JSX.Element | null;
|
|
6
|
+
export declare const FrozenBanner: ({ dataSource, className, ...htmlAttributes }: FrozenBannerProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { BaseRowProps } from "@vuu-ui/vuu-table-types";
|
|
2
2
|
export type InlineAddRowProps = BaseRowProps;
|
|
3
|
-
export declare const InlineAddRow: ({ ariaRowIndex, className, columns, style, }: InlineAddRowProps) => import("react").JSX.Element;
|
|
3
|
+
export declare const InlineAddRow: ({ ariaRowIndex, className, columns, style, }: InlineAddRowProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -13,5 +13,5 @@ export interface TabbedTableConfigPanelProps extends ColumnPickerProps, Pick<Tab
|
|
|
13
13
|
selectedTab?: TabName;
|
|
14
14
|
vuuTable?: VuuTable;
|
|
15
15
|
}
|
|
16
|
-
export declare const TabbedTableConfigPanel: ({ allowCreateCalculatedColumn, className, columnModel, config, onDisplayAttributeChange, selectedTab, vuuTable, ...htmlAttributes }: TabbedTableConfigPanelProps) => import("react").JSX.Element;
|
|
16
|
+
export declare const TabbedTableConfigPanel: ({ allowCreateCalculatedColumn, className, columnModel, config, onDisplayAttributeChange, selectedTab, vuuTable, ...htmlAttributes }: TabbedTableConfigPanelProps) => import("react/jsx-runtime").JSX.Element;
|
|
17
17
|
export {};
|
|
@@ -4,4 +4,4 @@ import { TableDisplayAttributeChangeHandler } from "../table-settings-panel/Tabl
|
|
|
4
4
|
export interface TabbedTableSettingsActionProps extends Partial<IconButtonProps>, TabbedTableConfigPanelHookProps {
|
|
5
5
|
onDisplayAttributeChange: TableDisplayAttributeChangeHandler;
|
|
6
6
|
}
|
|
7
|
-
export declare const TabbedTableSettingsAction: ({ allowCreateCalculatedColumn, appearance, columnModel, config, icon, onDisplayAttributeChange, sentiment, vuuTable, ...IconButtonProps }: TabbedTableSettingsActionProps) => import("react").JSX.Element;
|
|
7
|
+
export declare const TabbedTableSettingsAction: ({ allowCreateCalculatedColumn, appearance, columnModel, config, icon, onDisplayAttributeChange, sentiment, vuuTable, ...IconButtonProps }: TabbedTableSettingsActionProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -6,5 +6,5 @@ export interface TableFooterProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
6
6
|
export declare const TableFooterTray: ({ children, position, }: {
|
|
7
7
|
children: ReactNode;
|
|
8
8
|
position?: "center" | "end";
|
|
9
|
-
}) => import("react").JSX.Element;
|
|
10
|
-
export declare const TableFooter: ({ children, className, onInvokeAction, tooltrayActions, ...htmlAttributes }: TableFooterProps) => import("react").JSX.Element;
|
|
9
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export declare const TableFooter: ({ children, className, onInvokeAction, tooltrayActions, ...htmlAttributes }: TableFooterProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -10,7 +10,7 @@ export interface TableContextProps extends Pick<TableProps, "dataSource" | "rowA
|
|
|
10
10
|
export declare const TableContext: import("react").Context<TableContextProps>;
|
|
11
11
|
export declare const TableProvider: ({ children, dataSource, menuActionHandler, rowActionHandlers, }: TableContextProps & {
|
|
12
12
|
children: ReactNode;
|
|
13
|
-
}) => import("react").JSX.Element;
|
|
13
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
14
14
|
export declare function useTableContext(throwIfNoDataSource?: boolean): {
|
|
15
15
|
dataSource: DataSource;
|
|
16
16
|
menuActionHandler: MenuActionHandler<ColumnMenuActionType, ColumnDescriptor>;
|
|
@@ -19,4 +19,4 @@ export interface TableSettingsPanelProps {
|
|
|
19
19
|
It updates the settings in state locally and notifies caller of
|
|
20
20
|
every change via onChange callback
|
|
21
21
|
*/
|
|
22
|
-
export declare const TableSettingsPanel: ({ onDisplayAttributeChange, tableDisplayAttributes: tableDisplayAttributesProp, permissions: permissionsProp, }: TableSettingsPanelProps) => import("react").JSX.Element;
|
|
22
|
+
export declare const TableSettingsPanel: ({ onDisplayAttributeChange, tableDisplayAttributes: tableDisplayAttributesProp, permissions: permissionsProp, }: TableSettingsPanelProps) => import("react/jsx-runtime").JSX.Element;
|