@vuu-ui/vuu-table-extras 3.3.0 → 3.3.2
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 +12 -12
- package/src/csv-export/export-utils.js +164 -0
- package/src/csv-export/index.js +1 -0
- package/src/csv-upload/useCsvUpload.js +56 -5
- package/src/index.js +1 -0
- package/types/csv-export/export-utils.d.ts +20 -0
- package/types/csv-export/index.d.ts +1 -0
- package/types/csv-upload/CsvUpload.d.ts +12 -3
- package/types/csv-upload/useCsvUpload.d.ts +13 -1
- package/types/index.d.ts +2 -1
- package/types/inline-add-row/useInlineAddRow.d.ts +1 -0
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "3.3.
|
|
2
|
+
"version": "3.3.2",
|
|
3
3
|
"author": "heswell",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"license": "Apache-2.0",
|
|
@@ -11,19 +11,19 @@
|
|
|
11
11
|
"lezer-generate:column": "lezer-generator --output ./src/column-expression-input/column-language-parser/generated/column-parser.js ./src/column-expression-input/column-language-parser/grammar/column.grammar"
|
|
12
12
|
},
|
|
13
13
|
"devDependencies": {
|
|
14
|
-
"@vuu-ui/vuu-filter-types": "3.3.
|
|
15
|
-
"@vuu-ui/vuu-protocol-types": "3.3.
|
|
14
|
+
"@vuu-ui/vuu-filter-types": "3.3.2",
|
|
15
|
+
"@vuu-ui/vuu-protocol-types": "3.3.2"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@vuu-ui/vuu-codemirror": "3.3.
|
|
19
|
-
"@vuu-ui/vuu-data-editing": "3.3.
|
|
20
|
-
"@vuu-ui/vuu-data-react": "3.3.
|
|
21
|
-
"@vuu-ui/vuu-data-types": "3.3.
|
|
22
|
-
"@vuu-ui/vuu-table-types": "3.3.
|
|
23
|
-
"@vuu-ui/vuu-popups": "3.3.
|
|
24
|
-
"@vuu-ui/vuu-table": "3.3.
|
|
25
|
-
"@vuu-ui/vuu-utils": "3.3.
|
|
26
|
-
"@vuu-ui/vuu-ui-controls": "3.3.
|
|
18
|
+
"@vuu-ui/vuu-codemirror": "3.3.2",
|
|
19
|
+
"@vuu-ui/vuu-data-editing": "3.3.2",
|
|
20
|
+
"@vuu-ui/vuu-data-react": "3.3.2",
|
|
21
|
+
"@vuu-ui/vuu-data-types": "3.3.2",
|
|
22
|
+
"@vuu-ui/vuu-table-types": "3.3.2",
|
|
23
|
+
"@vuu-ui/vuu-popups": "3.3.2",
|
|
24
|
+
"@vuu-ui/vuu-table": "3.3.2",
|
|
25
|
+
"@vuu-ui/vuu-utils": "3.3.2",
|
|
26
|
+
"@vuu-ui/vuu-ui-controls": "3.3.2",
|
|
27
27
|
"@lezer/lr": "1.4.2",
|
|
28
28
|
"@salt-ds/core": "1.54.1",
|
|
29
29
|
"@salt-ds/lab": "1.0.0-alpha.83",
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { Range, isSessionTable, metadataKeys } from "@vuu-ui/vuu-utils";
|
|
2
|
+
const EXPORT_EXCLUDED_COLUMNS = new Set([
|
|
3
|
+
"vuuMsg",
|
|
4
|
+
"vuuAction",
|
|
5
|
+
"vuuRowNum"
|
|
6
|
+
]);
|
|
7
|
+
const MAX_EXPORT_ROWS = 10000;
|
|
8
|
+
const CHUNK_SIZE = 1000;
|
|
9
|
+
const csvCell = (value)=>{
|
|
10
|
+
const s = null == value ? "" : String(value);
|
|
11
|
+
return s.includes(",") || s.includes('"') || s.includes("\n") ? `"${s.replace(/"/g, '""')}` : s;
|
|
12
|
+
};
|
|
13
|
+
const triggerCsvDownload = (csv, filename)=>{
|
|
14
|
+
const blob = new Blob([
|
|
15
|
+
csv
|
|
16
|
+
], {
|
|
17
|
+
type: "text/csv;charset=utf-8;"
|
|
18
|
+
});
|
|
19
|
+
const url = URL.createObjectURL(blob);
|
|
20
|
+
const a = document.createElement("a");
|
|
21
|
+
a.href = url;
|
|
22
|
+
a.download = filename;
|
|
23
|
+
a.style.display = "none";
|
|
24
|
+
document.body.appendChild(a);
|
|
25
|
+
a.click();
|
|
26
|
+
document.body.removeChild(a);
|
|
27
|
+
setTimeout(()=>URL.revokeObjectURL(url), 10000);
|
|
28
|
+
};
|
|
29
|
+
const exportCsvTemplate = async (dataSource, filename = "template.csv", excludeColumns = [], columns, overrides)=>{
|
|
30
|
+
const sessionOverrides = overrides ?? (columns ? {
|
|
31
|
+
columns
|
|
32
|
+
} : void 0);
|
|
33
|
+
if (!isSessionTable(dataSource.table) && dataSource.createSessionDataSource) try {
|
|
34
|
+
const sessionDataSource = await dataSource.createSessionDataSource("Empty", "export", sessionOverrides);
|
|
35
|
+
if (sessionDataSource) return new Promise((resolve)=>{
|
|
36
|
+
const excluded = new Set([
|
|
37
|
+
...EXPORT_EXCLUDED_COLUMNS,
|
|
38
|
+
...excludeColumns
|
|
39
|
+
]);
|
|
40
|
+
sessionDataSource.subscribe({
|
|
41
|
+
range: Range(0, 0),
|
|
42
|
+
columns: sessionOverrides?.columns
|
|
43
|
+
}, (message)=>{
|
|
44
|
+
if ("subscribed" === message.type) {
|
|
45
|
+
const { columns: subColumns } = message;
|
|
46
|
+
const exportCols = subColumns.filter((name)=>!excluded.has(name));
|
|
47
|
+
const header = exportCols.map(csvCell).join(",");
|
|
48
|
+
triggerCsvDownload(`${header}\r\n`, filename);
|
|
49
|
+
sessionDataSource.unsubscribe();
|
|
50
|
+
resolve();
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.warn("[exportCsvTemplate] createSessionDataSource failed, falling back to tableSchema", error);
|
|
56
|
+
}
|
|
57
|
+
const schema = dataSource.tableSchema;
|
|
58
|
+
const targetColumns = columns ?? overrides?.columns;
|
|
59
|
+
if (void 0 !== targetColumns) {
|
|
60
|
+
if (schema) {
|
|
61
|
+
const schemaColumnNames = new Set(schema.columns.map((col)=>col.name));
|
|
62
|
+
const unknown = targetColumns.filter((name)=>!schemaColumnNames.has(name));
|
|
63
|
+
if (unknown.length > 0) console.warn(`[exportCsvTemplate] unknown column(s) in view tableSchema: ${unknown.join(", ")}`);
|
|
64
|
+
}
|
|
65
|
+
} else if (!schema) throw Error("exportCsvTemplate: tableSchema not available on dataSource");
|
|
66
|
+
const excluded = new Set([
|
|
67
|
+
...EXPORT_EXCLUDED_COLUMNS,
|
|
68
|
+
...excludeColumns
|
|
69
|
+
]);
|
|
70
|
+
const exportCols = targetColumns ? targetColumns.filter((name)=>!excluded.has(name)) : schema?.columns.filter((col)=>!excluded.has(col.name)).map((col)=>col.name) ?? [];
|
|
71
|
+
if (0 === exportCols.length) throw Error("exportCsvTemplate: no columns available for export");
|
|
72
|
+
const header = exportCols.map(csvCell).join(",");
|
|
73
|
+
triggerCsvDownload(`${header}\r\n`, filename);
|
|
74
|
+
};
|
|
75
|
+
const exportSessionTableToCsv = async (dataSource, filename = "export.csv", excludeColumns = [], onError, onSuccess, maxRows = MAX_EXPORT_ROWS, columnDescriptors, copyOption = "All", overrides)=>{
|
|
76
|
+
let sessionDataSource;
|
|
77
|
+
if (!isSessionTable(dataSource.table) && dataSource.createSessionDataSource) try {
|
|
78
|
+
sessionDataSource = await dataSource.createSessionDataSource(copyOption, "export", overrides);
|
|
79
|
+
} catch (err) {
|
|
80
|
+
onError?.(err instanceof Error ? err : new Error(String(err)));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
else sessionDataSource = dataSource;
|
|
84
|
+
if (!sessionDataSource) return void onError?.(new Error("exportSessionTableToCsv: unable to obtain sessionDataSource"));
|
|
85
|
+
const activeSessionDataSource = sessionDataSource;
|
|
86
|
+
const excluded = new Set([
|
|
87
|
+
...EXPORT_EXCLUDED_COLUMNS,
|
|
88
|
+
...excludeColumns
|
|
89
|
+
]);
|
|
90
|
+
let exportCols = [];
|
|
91
|
+
let colNameToRowIdx = {};
|
|
92
|
+
let descriptorMap = {};
|
|
93
|
+
let totalSize = 0;
|
|
94
|
+
const collectedRows = [];
|
|
95
|
+
return new Promise((resolve)=>{
|
|
96
|
+
const handleMessage = (message)=>{
|
|
97
|
+
if ("subscribed" === message.type) {
|
|
98
|
+
const { columns } = message;
|
|
99
|
+
if (columnDescriptors) {
|
|
100
|
+
const subscribedSet = new Set(columns);
|
|
101
|
+
const unknown = columnDescriptors.filter((d)=>!excluded.has(d.name) && !subscribedSet.has(d.name)).map((d)=>d.name);
|
|
102
|
+
if (unknown.length > 0) {
|
|
103
|
+
activeSessionDataSource.unsubscribe();
|
|
104
|
+
onError?.(new Error(`exportToCsv: unknown column(s) in columnDescriptors: ${unknown.join(", ")}`));
|
|
105
|
+
resolve();
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
descriptorMap = Object.fromEntries(columnDescriptors.map((d)=>[
|
|
109
|
+
d.name,
|
|
110
|
+
d
|
|
111
|
+
]));
|
|
112
|
+
}
|
|
113
|
+
exportCols = columns.filter((name)=>!excluded.has(name));
|
|
114
|
+
colNameToRowIdx = Object.fromEntries(columns.map((name, i)=>[
|
|
115
|
+
name,
|
|
116
|
+
metadataKeys.count + i
|
|
117
|
+
]));
|
|
118
|
+
} else if ("viewport-update" === message.type) {
|
|
119
|
+
if ("size-only" === message.mode) {
|
|
120
|
+
totalSize = message.size ?? 0;
|
|
121
|
+
if (0 === totalSize) {
|
|
122
|
+
activeSessionDataSource.unsubscribe();
|
|
123
|
+
onSuccess?.();
|
|
124
|
+
resolve();
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (totalSize > maxRows) {
|
|
128
|
+
activeSessionDataSource.unsubscribe();
|
|
129
|
+
onError?.(new Error(`exportToCsv: row count ${totalSize} exceeds the ${maxRows} row limit`));
|
|
130
|
+
resolve();
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
activeSessionDataSource.range = Range(0, Math.min(CHUNK_SIZE, totalSize));
|
|
134
|
+
} else if ("batch" === message.mode && message.rows) {
|
|
135
|
+
collectedRows.push(...message.rows);
|
|
136
|
+
if (void 0 !== message.size) totalSize = message.size;
|
|
137
|
+
if (collectedRows.length >= totalSize) {
|
|
138
|
+
activeSessionDataSource.unsubscribe();
|
|
139
|
+
const lines = [
|
|
140
|
+
exportCols.map((name)=>csvCell(descriptorMap[name]?.label ?? name)).join(",")
|
|
141
|
+
];
|
|
142
|
+
for (const row of collectedRows)lines.push(exportCols.map((c)=>{
|
|
143
|
+
const raw = row[colNameToRowIdx[c]];
|
|
144
|
+
const formatter = descriptorMap[c]?.exportFormatter;
|
|
145
|
+
return csvCell(formatter ? formatter(raw) : raw);
|
|
146
|
+
}).join(","));
|
|
147
|
+
triggerCsvDownload(lines.join("\r\n"), filename);
|
|
148
|
+
onSuccess?.();
|
|
149
|
+
resolve();
|
|
150
|
+
} else {
|
|
151
|
+
const nextFrom = collectedRows.length;
|
|
152
|
+
activeSessionDataSource.range = Range(nextFrom, Math.min(nextFrom + CHUNK_SIZE, totalSize));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
activeSessionDataSource.subscribe({
|
|
158
|
+
range: Range(0, 0),
|
|
159
|
+
columns: overrides?.columns
|
|
160
|
+
}, handleMessage);
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
const exportToCsv = async (dataSource, copyOption = "All", filename = "export.csv", excludeColumns = [], onError, onSuccess, maxRows = MAX_EXPORT_ROWS, columnDescriptors, overrides)=>exportSessionTableToCsv(dataSource, filename, excludeColumns, onError, onSuccess, maxRows, columnDescriptors, copyOption, overrides);
|
|
164
|
+
export { exportCsvTemplate, exportSessionTableToCsv, exportToCsv };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { exportCsvTemplate, exportSessionTableToCsv, exportToCsv } from "./export-utils.js";
|
|
@@ -1,17 +1,68 @@
|
|
|
1
1
|
import { EditSession } from "@vuu-ui/vuu-data-editing";
|
|
2
|
-
import { isRpcError, isSessionTable } from "@vuu-ui/vuu-utils";
|
|
2
|
+
import { isRpcError, isSessionTable, useData } from "@vuu-ui/vuu-utils";
|
|
3
3
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { parseCsv } from "./parse/csv-parse.js";
|
|
5
5
|
import { validateCsvAgainstSchema } from "./parse/csv-schema-validation.js";
|
|
6
6
|
import { buildRowErrorMessage, createUploadError, hasFileParseErrors, isCsvParseError, mergeValidationWithParseErrors, toErrorMessage } from "./parse/csv-upload-utils.js";
|
|
7
7
|
import { CSV_FIRST_DATA_ROW_NUMBER } from "./parse/csv-constants.js";
|
|
8
|
-
const useCsvUpload = ({ dataSource, importMode = "direct", onImportSessionEnded, onImportSessionStarted, onError, onImported, onPreview, onProcessingStarted, maxRows, parseOptions })=>{
|
|
8
|
+
const useCsvUpload = ({ dataSource, importMode = "direct", importSchema, importTable, onImportSessionEnded, onImportSessionStarted, onError, onImported, onPreview, onProcessingStarted, maxRows, parseOptions, rowDefaults })=>{
|
|
9
|
+
const { getServerAPI } = useData();
|
|
9
10
|
const [validation, setValidation] = useState();
|
|
10
11
|
const [sessionTable, setSessionTable] = useState();
|
|
11
12
|
const [isProcessingFile, setIsProcessingFile] = useState(false);
|
|
12
13
|
const [isImporting, setIsImporting] = useState(false);
|
|
13
|
-
const
|
|
14
|
-
|
|
14
|
+
const [fetchedImportSchema, setFetchedImportSchema] = useState();
|
|
15
|
+
useEffect(()=>{
|
|
16
|
+
if (importSchema || void 0 === importTable) return void setFetchedImportSchema(void 0);
|
|
17
|
+
let cancelled = false;
|
|
18
|
+
(async ()=>{
|
|
19
|
+
try {
|
|
20
|
+
const server = await getServerAPI();
|
|
21
|
+
const tableSchema = await server.getTableSchema(importTable);
|
|
22
|
+
if (!cancelled) setFetchedImportSchema(tableSchema);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error("[useCsvUpload] failed to fetch import table schema", error);
|
|
25
|
+
}
|
|
26
|
+
})();
|
|
27
|
+
return ()=>{
|
|
28
|
+
cancelled = true;
|
|
29
|
+
};
|
|
30
|
+
}, [
|
|
31
|
+
getServerAPI,
|
|
32
|
+
importSchema,
|
|
33
|
+
importTable
|
|
34
|
+
]);
|
|
35
|
+
const resolvedImportSchema = importSchema ?? fetchedImportSchema;
|
|
36
|
+
const sessionOverrides = useMemo(()=>{
|
|
37
|
+
const columns = resolvedImportSchema?.columns.map(({ name })=>name);
|
|
38
|
+
return columns || importTable ? {
|
|
39
|
+
columns,
|
|
40
|
+
table: importTable
|
|
41
|
+
} : void 0;
|
|
42
|
+
}, [
|
|
43
|
+
resolvedImportSchema,
|
|
44
|
+
importTable
|
|
45
|
+
]);
|
|
46
|
+
const importDataSource = useMemo(()=>{
|
|
47
|
+
if (!sessionOverrides) return dataSource;
|
|
48
|
+
return {
|
|
49
|
+
tableSchema: dataSource.tableSchema,
|
|
50
|
+
createSessionDataSource: async (copyOption, sessionType)=>{
|
|
51
|
+
if (!dataSource.createSessionDataSource) throw Error("[useCsvUpload] dataSource does not support createSessionDataSource");
|
|
52
|
+
return dataSource.createSessionDataSource(copyOption, sessionType, sessionOverrides);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}, [
|
|
56
|
+
dataSource,
|
|
57
|
+
sessionOverrides
|
|
58
|
+
]);
|
|
59
|
+
const editSession = useMemo(()=>new EditSession({
|
|
60
|
+
dataSource: importDataSource,
|
|
61
|
+
editSessionApi: "createSessionDataSource",
|
|
62
|
+
rowDefaults
|
|
63
|
+
}), [
|
|
64
|
+
importDataSource,
|
|
65
|
+
rowDefaults
|
|
15
66
|
]);
|
|
16
67
|
const ownsEditSessionRef = useRef(true);
|
|
17
68
|
const operationIdRef = useRef(0);
|
|
@@ -56,7 +107,7 @@ const useCsvUpload = ({ dataSource, importMode = "direct", onImportSessionEnded,
|
|
|
56
107
|
setActiveSessionDataSource
|
|
57
108
|
]);
|
|
58
109
|
const table = dataSource.table;
|
|
59
|
-
const schema = dataSource.tableSchema;
|
|
110
|
+
const schema = importTable ? resolvedImportSchema : resolvedImportSchema ?? dataSource.tableSchema;
|
|
60
111
|
const addAllRows = useCallback(async (mergedValidation, operationId)=>{
|
|
61
112
|
const vuuMsgByRow = new Map();
|
|
62
113
|
for (const { rowNum, column, message } of mergedValidation.errors){
|
package/src/index.js
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CopyOption, DataSource, SessionDataSourceOverrides } from "@vuu-ui/vuu-data-types";
|
|
2
|
+
export type ExportColumnDescriptor<TName extends string = string> = {
|
|
3
|
+
name: TName;
|
|
4
|
+
/** Override the column name used as the CSV header label. */
|
|
5
|
+
label?: string;
|
|
6
|
+
exportFormatter?: (value: unknown) => string;
|
|
7
|
+
};
|
|
8
|
+
/** Downloads a single-row CSV containing only the column headers, for use as an import template. */
|
|
9
|
+
export declare const exportCsvTemplate: (dataSource: DataSource, filename?: string, excludeColumns?: string[], columns?: string[], overrides?: SessionDataSourceOverrides) => Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Subscribes to `dataSource` (creating an export session data source if a view data source is passed)
|
|
12
|
+
* with a full-range request to drain all rows, serialises them to CSV (excluding internal session columns),
|
|
13
|
+
* then triggers a browser download. The session data source is unsubscribed automatically once the download
|
|
14
|
+
* is initiated.
|
|
15
|
+
*/
|
|
16
|
+
export declare const exportSessionTableToCsv: <TName extends string = string>(dataSource: DataSource, filename?: string, excludeColumns?: string[], onError?: (error: Error) => void, onSuccess?: () => void, maxRows?: number, columnDescriptors?: ExportColumnDescriptor<TName>[], copyOption?: CopyOption, overrides?: SessionDataSourceOverrides) => Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Creates an export session table from `dataSource` then streams all rows to a CSV download.
|
|
19
|
+
*/
|
|
20
|
+
export declare const exportToCsv: <TName extends string = string>(dataSource: DataSource, copyOption?: CopyOption, filename?: string, excludeColumns?: string[], onError?: (error: Error) => void, onSuccess?: () => void, maxRows?: number, columnDescriptors?: ExportColumnDescriptor<TName>[], overrides?: SessionDataSourceOverrides) => Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { exportCsvTemplate, exportSessionTableToCsv, exportToCsv, type ExportColumnDescriptor, } from "./export-utils";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
|
-
import type {
|
|
3
|
-
import type { EditSession } from "@vuu-ui/vuu-data-editing";
|
|
4
|
-
import type { VuuTable } from "@vuu-ui/vuu-protocol-types";
|
|
2
|
+
import type { RowDefaultDataItemValues, EditSession } from "@vuu-ui/vuu-data-editing";
|
|
5
3
|
import type { CsvParseError, CsvParseOptions } from "./parse/csv-parse";
|
|
6
4
|
import type { CsvValidationStructuredError } from "./parse/csv-schema-validation";
|
|
5
|
+
import type { DataSource, TableSchema } from "@vuu-ui/vuu-data-types";
|
|
6
|
+
import type { VuuTable } from "@vuu-ui/vuu-protocol-types";
|
|
7
7
|
import type { CsvUploadTableData } from "./parse/csv-upload-utils";
|
|
8
8
|
export type CsvUploadImportedResult = {
|
|
9
9
|
tableData: CsvUploadTableData;
|
|
@@ -38,6 +38,14 @@ export interface CsvUploadProps {
|
|
|
38
38
|
children?: ReactNode;
|
|
39
39
|
dataSource: DataSource;
|
|
40
40
|
embedded?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Schema of the import table, where it differs from the target table. Used to validate
|
|
43
|
+
* the CSV and to determine the session datasource columns. If omitted and importTable is
|
|
44
|
+
* provided, the schema is fetched via getTableSchema. Pass a stable reference.
|
|
45
|
+
*/
|
|
46
|
+
importSchema?: TableSchema;
|
|
47
|
+
/** Expected import table, used to validate the session table returned by the server. */
|
|
48
|
+
importTable?: VuuTable;
|
|
41
49
|
onImportSessionStarted?: (dataSource: DataSource) => void;
|
|
42
50
|
onImportSessionEnded?: (result: CsvUploadSessionEndResult) => void;
|
|
43
51
|
onError?: (result: CsvUploadErrorResult | undefined) => void;
|
|
@@ -51,5 +59,6 @@ export interface CsvUploadProps {
|
|
|
51
59
|
open?: boolean;
|
|
52
60
|
parseOptions?: CsvParseOptions;
|
|
53
61
|
importMode?: "direct" | "preview";
|
|
62
|
+
rowDefaults?: RowDefaultDataItemValues;
|
|
54
63
|
}
|
|
55
64
|
export declare const CsvUpload: (props: CsvUploadProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import type { DataSource, TableSchema } from "@vuu-ui/vuu-data-types";
|
|
2
|
+
import { type RowDefaultDataItemValues } from "@vuu-ui/vuu-data-editing";
|
|
3
|
+
import type { VuuTable } from "@vuu-ui/vuu-protocol-types";
|
|
2
4
|
import { type CsvParseOptions } from "./parse/csv-parse";
|
|
3
5
|
import { type CsvValidationResult } from "./parse/csv-schema-validation";
|
|
4
6
|
import type { CsvUploadErrorResult, CsvUploadImportedResult, CsvUploadPreviewResult, CsvUploadSessionEndResult, CsvUploadSessionTable } from "./CsvUpload";
|
|
5
7
|
export interface CsvUploadHookProps {
|
|
6
8
|
dataSource: DataSource;
|
|
7
9
|
importMode?: "direct" | "preview";
|
|
10
|
+
/**
|
|
11
|
+
* Schema of the import table, where it differs from the target table. Used to validate
|
|
12
|
+
* the CSV and to determine the session datasource columns. If omitted and importTable is
|
|
13
|
+
* provided, the schema is fetched via getTableSchema. Pass a stable reference.
|
|
14
|
+
*/
|
|
15
|
+
importSchema?: TableSchema;
|
|
16
|
+
/** Expected import table, used to validate the session table returned by the server. */
|
|
17
|
+
importTable?: VuuTable;
|
|
8
18
|
maxRows?: number;
|
|
9
19
|
onImportSessionEnded?: (result: CsvUploadSessionEndResult) => void;
|
|
10
20
|
onImportSessionStarted?: (dataSource: DataSource) => void;
|
|
@@ -13,6 +23,8 @@ export interface CsvUploadHookProps {
|
|
|
13
23
|
onPreview?: (result: CsvUploadPreviewResult) => void;
|
|
14
24
|
onProcessingStarted?: () => void;
|
|
15
25
|
parseOptions?: CsvParseOptions;
|
|
26
|
+
/** Default column values applied to every addRow call. Pass a stable reference — a new object triggers EditSession recreation. */
|
|
27
|
+
rowDefaults?: RowDefaultDataItemValues;
|
|
16
28
|
}
|
|
17
29
|
export type UseCsvUploadReturn = {
|
|
18
30
|
canImport: boolean;
|
|
@@ -26,4 +38,4 @@ export type UseCsvUploadReturn = {
|
|
|
26
38
|
schema: TableSchema | undefined;
|
|
27
39
|
validation: CsvValidationResult | undefined;
|
|
28
40
|
};
|
|
29
|
-
export declare const useCsvUpload: ({ dataSource, importMode, onImportSessionEnded, onImportSessionStarted, onError, onImported, onPreview, onProcessingStarted, maxRows, parseOptions, }: CsvUploadHookProps) => UseCsvUploadReturn;
|
|
41
|
+
export declare const useCsvUpload: ({ dataSource, importMode, importSchema, importTable, onImportSessionEnded, onImportSessionStarted, onError, onImported, onPreview, onProcessingStarted, maxRows, parseOptions, rowDefaults, }: CsvUploadHookProps) => UseCsvUploadReturn;
|
package/types/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { CalculatedColumnPanel } from "./calculated-column/CalculatedColumnPanel";
|
|
2
|
+
export * from "./csv-export";
|
|
2
3
|
export * from "./csv-upload";
|
|
3
4
|
export * from "./cell-edit-validators";
|
|
4
5
|
export * from "./cell-renderers";
|
|
@@ -10,7 +11,7 @@ export { useColumnActions } from "./column-menu/useColumnActions";
|
|
|
10
11
|
export { ColumnChangeSource, ColumnModel, isColumnAdded, isColumnRemoved, isColumnsReordered, SelectedColumnChangeType, type ColumnEvents, type ColumnsChangeHandler, } from "./column-picker/ColumnModel";
|
|
11
12
|
export { ColumnPicker, type ColumnPickerProps, } from "./column-picker/ColumnPicker";
|
|
12
13
|
export { ColumnPickerAction } from "./column-picker/ColumnPickerAction";
|
|
13
|
-
export {
|
|
14
|
+
export type { SelectedColumnsChangeHandler } from "./column-picker/useColumnPicker";
|
|
14
15
|
export { useTableColumnPicker } from "./column-picker/useTableColumnPicker";
|
|
15
16
|
export { ColumnSettingsPanel } from "./column-settings-panel/ColumnSettingsPanel";
|
|
16
17
|
export { useColumnSettings } from "./column-settings-panel/useColumnSettings";
|
|
@@ -38,6 +38,7 @@ export declare const useInlineAddRow: ({ columns }: UseInlineAddRowProps) => {
|
|
|
38
38
|
allowColumnHeaderMenu?: false;
|
|
39
39
|
colHeaderContentRenderer?: string;
|
|
40
40
|
colHeaderLabelRenderer?: string;
|
|
41
|
+
exportFormatter?: (value: unknown) => string;
|
|
41
42
|
getIcon?: (row: DataRow) => string | undefined;
|
|
42
43
|
groupable?: boolean;
|
|
43
44
|
hidden?: boolean;
|