@vuu-ui/vuu-table-extras 4.0.0-alpha.2 → 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 +18 -17
- package/src/calculated-column/CalculatedColumnPanel.js +2 -2
- package/src/calculated-column/useEditCalculatedColumn.js +1 -1
- 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-expression-input/useColumnExpressionSuggestionProvider.js +2 -2
- package/src/column-formatting-settings/ColumnFormattingPanel.js +12 -9
- package/src/column-formatting-settings/DateTimeFormattingSettings.js +107 -3
- package/src/column-formatting-settings/LongTypeFormattingSettings.js +8 -3
- package/src/column-picker/ColumnModel.js +14 -25
- package/src/column-picker/ColumnPicker.css.js +0 -86
- package/src/column-picker/ColumnPicker.js +12 -180
- package/src/column-picker/useColumnPicker.js +28 -22
- package/src/column-settings-panel/ColumnNameLabel.css.js +1 -1
- package/src/csv-export/export-utils.js +76 -20
- package/src/csv-export/index.js +1 -1
- package/src/csv-export/useCsvExport.js +9 -1
- package/src/csv-upload/CsvUpload.css.js +36 -2
- package/src/csv-upload/CsvUpload.js +107 -63
- package/src/csv-upload/parse/csv-errors.js +1 -1
- package/src/csv-upload/parse/csv-parse.js +1 -1
- package/src/csv-upload/parse/csv-schema-validation.js +46 -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 +54 -199
- package/src/freeze-control/FreezeControl.css.js +4 -4
- package/src/freeze-control/FrozenBanner.css.js +2 -2
- package/src/tabbed-table-config-panel/TabbedTableConfigPanel.js +17 -8
- package/src/tabbed-table-config-panel/useTabbedTableConfigPanel.js +1 -1
- package/src/table-footer/TableFooter.js +3 -3
- package/types/calculated-column/CalculatedColumnPanel.d.ts +3 -3
- 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/DateTimeFormattingSettings.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/ColumnModel.d.ts +4 -3
- package/types/column-picker/ColumnPicker.d.ts +4 -6
- package/types/column-picker/ColumnPickerAction.d.ts +1 -1
- package/types/column-picker/useColumnPicker.d.ts +7 -10
- package/types/column-settings-panel/ColumnNameLabel.d.ts +1 -1
- package/types/column-settings-panel/ColumnSettingsPanel.d.ts +1 -1
- package/types/column-settings-panel/useColumnSettings.d.ts +3 -3
- package/types/csv-export/export-utils.d.ts +22 -9
- package/types/csv-export/index.d.ts +1 -1
- package/types/csv-export/useCsvExport.d.ts +5 -2
- package/types/csv-upload/CsvUpload.d.ts +2 -6
- package/types/csv-upload/data-upload-preview/DataUploadPreview.d.ts +1 -1
- package/types/csv-upload/parse/csv-errors.d.ts +1 -1
- package/types/csv-upload/parse/csv-schema-validation.d.ts +8 -2
- 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 +3 -3
- 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/index.d.ts +0 -1
- package/types/inline-add-row/InlineAddRow.d.ts +1 -1
- package/types/inline-add-row/useInlineAddRow.d.ts +2 -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/tabbed-table-config-panel/useTabbedTableConfigPanel.d.ts +4 -3
- package/types/table-footer/TableFooter.d.ts +4 -4
- package/types/table-provider/TableProvider.d.ts +1 -1
- package/types/table-settings-panel/TableSettingsPanel.d.ts +1 -1
|
@@ -1,205 +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 {
|
|
8
|
-
|
|
9
|
-
|
|
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
|
+
const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importTable, onImportSessionEnded, onImportSessionReady, onError, onImported, onPreview, onProcessingStarted, maxRows, parseOptions, rowDefaults, validators })=>{
|
|
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) 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}` : `${0 === rowNum ? "Header" : `Row ${rowNum}`}: ${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
|
-
onImportSessionStarted?.(sessionDataSource);
|
|
191
|
-
return sessionDataSource;
|
|
192
|
-
}, [
|
|
193
|
-
editSession,
|
|
194
|
-
onImportSessionStarted,
|
|
195
|
-
setActiveSessionDataSource
|
|
196
|
-
]);
|
|
197
|
-
const closePendingEditSession = useCallback(async (save)=>{
|
|
198
|
-
if (void 0 === sessionDataSourceRef.current) return;
|
|
199
|
-
await endEditSessionAndNotify(save, save ? "saved" : "discarded");
|
|
200
|
-
}, [
|
|
201
|
-
endEditSessionAndNotify
|
|
202
|
-
]);
|
|
203
34
|
const cancelImport = useCallback(async ()=>{
|
|
204
35
|
operationIdRef.current++;
|
|
205
36
|
processingPromiseRef.current = void 0;
|
|
@@ -245,13 +76,10 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
245
76
|
});
|
|
246
77
|
if (Object.keys(schemaValidation.errorMap.fileErrors).length > 0) {
|
|
247
78
|
setValidation(schemaValidation);
|
|
79
|
+
const detailedMessage = `CSV validation failed: ${schemaValidation.errors.map((e)=>"*" === e.column ? e.message : `${e.column}: ${e.message}`).join("; ")}`;
|
|
248
80
|
handleError({
|
|
249
81
|
errors: {
|
|
250
|
-
schemaError: createUploadError("schema",
|
|
251
|
-
errorMap: schemaValidation.errorMap,
|
|
252
|
-
errors: schemaValidation.errors,
|
|
253
|
-
message: "CSV validation failed."
|
|
254
|
-
})
|
|
82
|
+
schemaError: createUploadError("schema", detailedMessage, parsedCsv.error, schemaValidation)
|
|
255
83
|
}
|
|
256
84
|
});
|
|
257
85
|
return;
|
|
@@ -259,10 +87,31 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
259
87
|
const mergedValidation = mergeValidationWithParseErrors(schemaValidation, parsedCsv.error);
|
|
260
88
|
setValidation(mergedValidation);
|
|
261
89
|
if (mergedValidation.rows.length > 0) try {
|
|
262
|
-
await beginEditSession();
|
|
90
|
+
const sessionDataSource = await beginEditSession();
|
|
263
91
|
if (operationId !== operationIdRef.current) return;
|
|
264
|
-
const
|
|
265
|
-
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
|
+
}
|
|
114
|
+
onImportSessionReady?.(sessionDataSource);
|
|
266
115
|
} catch (error) {
|
|
267
116
|
if (void 0 !== sessionDataSourceRef.current) await endEditSessionAndNotify(false, "failed");
|
|
268
117
|
else try {
|
|
@@ -281,6 +130,7 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
281
130
|
handleError,
|
|
282
131
|
editSession,
|
|
283
132
|
addAllRows,
|
|
133
|
+
checkSessionTableErrors,
|
|
284
134
|
maxRows,
|
|
285
135
|
parseOptions,
|
|
286
136
|
beginEditSession,
|
|
@@ -290,7 +140,9 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
290
140
|
table,
|
|
291
141
|
endEditSessionAndNotify,
|
|
292
142
|
schema,
|
|
293
|
-
validators
|
|
143
|
+
validators,
|
|
144
|
+
onImportSessionReady,
|
|
145
|
+
sessionDataSourceRef
|
|
294
146
|
]);
|
|
295
147
|
const handleFiles = useCallback(async (files)=>{
|
|
296
148
|
const file = files[0];
|
|
@@ -333,10 +185,11 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
333
185
|
}, [
|
|
334
186
|
handleFiles
|
|
335
187
|
]);
|
|
336
|
-
const canImport = useMemo(()=>void 0 !== validation && 0 === validation.errors.length && validation.rows.length > 0 && !isProcessingFile && !isImporting, [
|
|
188
|
+
const canImport = useMemo(()=>void 0 !== validation && 0 === validation.errors.length && validation.rows.length > 0 && !isProcessingFile && !isImporting && void 0 === error, [
|
|
337
189
|
isImporting,
|
|
338
190
|
isProcessingFile,
|
|
339
|
-
validation
|
|
191
|
+
validation,
|
|
192
|
+
error
|
|
340
193
|
]);
|
|
341
194
|
const importData = useCallback(async ()=>{
|
|
342
195
|
if (!canImport || void 0 === validation) return false;
|
|
@@ -357,7 +210,7 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
357
210
|
editSession,
|
|
358
211
|
tableData
|
|
359
212
|
});
|
|
360
|
-
|
|
213
|
+
releaseEditSessionOwnership();
|
|
361
214
|
} else {
|
|
362
215
|
await endEditSessionAndNotify(true, "saved");
|
|
363
216
|
onImported?.({
|
|
@@ -385,6 +238,8 @@ const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importT
|
|
|
385
238
|
onImported,
|
|
386
239
|
onPreview,
|
|
387
240
|
importMode,
|
|
241
|
+
releaseEditSessionOwnership,
|
|
242
|
+
sessionDataSourceRef,
|
|
388
243
|
validation
|
|
389
244
|
]);
|
|
390
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);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Tab, TabBar, TabList, TabPanel, TabTrigger, Tabs } from "@salt-ds/core";
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, Tab, TabBar, TabList, TabPanel, TabTrigger, Tabs } from "@salt-ds/core";
|
|
3
3
|
import { useComponentCssInjection } from "@salt-ds/styles";
|
|
4
4
|
import { useWindow } from "@salt-ds/window";
|
|
5
5
|
import clsx from "clsx";
|
|
@@ -78,12 +78,21 @@ const TabbedTableConfigPanel_TabbedTableConfigPanel = ({ allowCreateCalculatedCo
|
|
|
78
78
|
}),
|
|
79
79
|
/*#__PURE__*/ jsx(TabPanel, {
|
|
80
80
|
value: "table-columns",
|
|
81
|
-
children: /*#__PURE__*/
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
81
|
+
children: /*#__PURE__*/ jsxs(Fragment, {
|
|
82
|
+
children: [
|
|
83
|
+
/*#__PURE__*/ jsx(ColumnPicker, {
|
|
84
|
+
columnModel: columnModel,
|
|
85
|
+
onSelectionChange: handleSelectionChange,
|
|
86
|
+
selected: columns
|
|
87
|
+
}),
|
|
88
|
+
allowCreateCalculatedColumn ? /*#__PURE__*/ jsx("div", {
|
|
89
|
+
className: `${classBase}-column-buttons`,
|
|
90
|
+
children: /*#__PURE__*/ jsx(Button, {
|
|
91
|
+
onClick: onCreateCalculatedColumn,
|
|
92
|
+
children: "Create calculated column"
|
|
93
|
+
})
|
|
94
|
+
}) : null
|
|
95
|
+
]
|
|
87
96
|
})
|
|
88
97
|
}),
|
|
89
98
|
/*#__PURE__*/ jsx(TabPanel, {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useCallback, useRef } from "react";
|
|
3
2
|
import { useContextPanel } from "@vuu-ui/vuu-ui-controls";
|
|
3
|
+
import { useCallback, useRef } from "react";
|
|
4
4
|
import { TabbedTableConfigPanel } from "./TabbedTableConfigPanel.js";
|
|
5
5
|
const useTabbedTableConfigPanel = ({ allowCreateCalculatedColumn, columnModel, config, onDisplayAttributeChange, vuuTable })=>{
|
|
6
6
|
const showContextPanel = useContextPanel();
|
|
@@ -4,10 +4,10 @@ import { useComponentCssInjection } from "@salt-ds/styles";
|
|
|
4
4
|
import { useWindow } from "@salt-ds/window";
|
|
5
5
|
import TableFooter from "./TableFooter.css";
|
|
6
6
|
const classBase = "vuuTableFooter";
|
|
7
|
-
const TableFooterTray = ({ children, position =
|
|
7
|
+
const TableFooterTray = ({ children, position = "end" })=>/*#__PURE__*/ jsx("div", {
|
|
8
8
|
className: clsx(`${classBase}Tray`, {
|
|
9
|
-
[`${classBase}Tray-center`]:
|
|
10
|
-
[`${classBase}Tray-end`]:
|
|
9
|
+
[`${classBase}Tray-center`]: "center" === position,
|
|
10
|
+
[`${classBase}Tray-end`]: "end" === position
|
|
11
11
|
}),
|
|
12
12
|
children: children
|
|
13
13
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { HTMLAttributes } from "react";
|
|
2
|
-
import { ColumnDescriptor } from "@vuu-ui/vuu-table-types";
|
|
3
1
|
import { VuuColumnDataType, VuuTable } from "@vuu-ui/vuu-protocol-types";
|
|
2
|
+
import { ColumnDescriptor } from "@vuu-ui/vuu-table-types";
|
|
3
|
+
import { HTMLAttributes } from "react";
|
|
4
4
|
import { ColumnModel } from "../column-picker/ColumnModel";
|
|
5
5
|
export interface CalculatedColumnPanelProps extends HTMLAttributes<HTMLDivElement> {
|
|
6
6
|
column: ColumnDescriptor;
|
|
@@ -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;
|
|
@@ -58,12 +58,13 @@ export declare class ColumnModel extends EventEmitter<ColumnEvents> {
|
|
|
58
58
|
* Columns already selected and rendered in Table.
|
|
59
59
|
*/
|
|
60
60
|
selectedColumns: readonly ColumnDescriptor[]);
|
|
61
|
-
get availableColumns(): ColumnDescriptor[];
|
|
62
|
-
set searchPattern(pattern: string);
|
|
63
|
-
get searchPattern(): string;
|
|
64
61
|
get selectedColumns(): readonly ColumnDescriptor[];
|
|
65
62
|
setSelectedColumns(selectedColumns: readonly ColumnDescriptor[], source: ColumnChangeSource, changeDescriptor?: SelectedColumnChangeDescriptor): void;
|
|
66
63
|
getColumn(name: string): ColumnDescriptor;
|
|
64
|
+
/**
|
|
65
|
+
* Introduced for use by ColumnPicker
|
|
66
|
+
*/
|
|
67
|
+
addRemoveOrReorderSelectedColumns(newSelectedColumns: readonly ColumnDescriptor[], source: ColumnChangeSource): void;
|
|
67
68
|
addItemToSelectedColumns(name: string, source: ColumnChangeSource): void;
|
|
68
69
|
removeItemFromSelectedColumns(name: string, source: ColumnChangeSource): void;
|
|
69
70
|
reorderSelectedColumns(orderedColumnNames: string[], source: ColumnChangeSource): void;
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { ColumnPickerHookProps } from "./useColumnPicker";
|
|
1
|
+
import type { ListBoxProps } from "@salt-ds/core";
|
|
2
|
+
import type { ColumnDescriptor } from "@vuu-ui/vuu-table-types";
|
|
3
|
+
import { type HTMLAttributes } from "react";
|
|
4
|
+
import { type ColumnPickerHookProps } from "./useColumnPicker";
|
|
5
5
|
export declare const classBaseListItem = "vuuColumnPickerListItem";
|
|
6
6
|
export interface ColumnPickerProps extends ColumnPickerHookProps, Pick<ListBoxProps<ColumnDescriptor>, "selected" | "onSelectionChange">, HTMLAttributes<HTMLDivElement> {
|
|
7
|
-
allowCreateCalculatedColumn?: boolean;
|
|
8
|
-
onClickCreateCalculatedColumn?: MouseEventHandler<HTMLButtonElement>;
|
|
9
7
|
}
|
|
10
8
|
export declare const ColumnPicker: import("react").ForwardRefExoticComponent<ColumnPickerProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -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;
|
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { ColumnModel
|
|
1
|
+
import { TableSelectionModel } from "@vuu-ui/vuu-table-types";
|
|
2
|
+
import { ItemDescriptor } from "@vuu-ui/vuu-ui-controls";
|
|
3
|
+
import { ColumnModel } from "./ColumnModel";
|
|
4
4
|
export type ColumnSelectionModel = Extract<TableSelectionModel, "none" | "single">;
|
|
5
|
-
export type SelectedColumnsChangeHandler = (columns: ColumnDescriptor[], changeType: SelectedColumnChangeType) => void;
|
|
6
5
|
export interface ColumnPickerHookProps {
|
|
7
6
|
columnModel: ColumnModel;
|
|
8
7
|
}
|
|
9
8
|
export declare const useColumnPicker: ({ columnModel: model, }: ColumnPickerHookProps) => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
searchText: string;
|
|
15
|
-
selectedColumns: readonly ColumnDescriptor[];
|
|
9
|
+
allItems: ItemDescriptor[];
|
|
10
|
+
selectedItems: ItemDescriptor[];
|
|
11
|
+
oneOrMoreColumnsIsCalculated: boolean;
|
|
12
|
+
handleSelectedItemsChange: (newSelectedItems: readonly ItemDescriptor[]) => void;
|
|
16
13
|
};
|
|
@@ -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;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ColumnDescriptor,
|
|
2
|
-
import {
|
|
1
|
+
import { ColumnDescriptor, ColumnTypeFormatting, TableConfig } from "@vuu-ui/vuu-table-types";
|
|
2
|
+
import { DataValueTypeSimple } from "@vuu-ui/vuu-data-types";
|
|
3
3
|
import { VuuColumnDataType, VuuTable } from "@vuu-ui/vuu-protocol-types";
|
|
4
|
+
import { CellRendererDescriptor, ColumnRenderPropsChangeHandler } from "@vuu-ui/vuu-utils";
|
|
4
5
|
import { FormEventHandler } from "react";
|
|
5
|
-
import { DataValueTypeSimple } from "@vuu-ui/vuu-data-types";
|
|
6
6
|
import { ColumnModel } from "../column-picker/ColumnModel";
|
|
7
7
|
/**
|
|
8
8
|
* Describes the props for a Column Configuration Editor, for which
|