@ackplus/react-tanstack-data-table 1.1.11 → 1.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +143 -11
- package/dist/lib/components/droupdown/menu-dropdown.d.ts.map +1 -1
- package/dist/lib/components/droupdown/menu-dropdown.js +8 -1
- package/dist/lib/components/filters/filter-value-input.js +2 -2
- package/dist/lib/components/pagination/data-table-pagination.d.ts.map +1 -1
- package/dist/lib/components/pagination/data-table-pagination.js +10 -1
- package/dist/lib/components/toolbar/data-table-toolbar.d.ts.map +1 -1
- package/dist/lib/components/toolbar/data-table-toolbar.js +5 -2
- package/dist/lib/components/toolbar/table-export-control.d.ts.map +1 -1
- package/dist/lib/components/toolbar/table-export-control.js +46 -12
- package/dist/lib/components/toolbar/table-refresh-control.d.ts +15 -0
- package/dist/lib/components/toolbar/table-refresh-control.d.ts.map +1 -0
- package/dist/lib/components/toolbar/table-refresh-control.js +61 -0
- package/dist/lib/contexts/data-table-context.d.ts +7 -10
- package/dist/lib/contexts/data-table-context.d.ts.map +1 -1
- package/dist/lib/contexts/data-table-context.js +5 -1
- package/dist/lib/data-table.d.ts.map +1 -1
- package/dist/lib/data-table.js +1110 -946
- package/dist/lib/features/column-filter.feature.js +38 -21
- package/dist/lib/features/selection.feature.d.ts.map +1 -1
- package/dist/lib/features/selection.feature.js +11 -3
- package/dist/lib/types/column.types.d.ts +19 -0
- package/dist/lib/types/column.types.d.ts.map +1 -1
- package/dist/lib/types/data-table-api.d.ts +25 -18
- package/dist/lib/types/data-table-api.d.ts.map +1 -1
- package/dist/lib/types/data-table.types.d.ts +37 -10
- package/dist/lib/types/data-table.types.d.ts.map +1 -1
- package/dist/lib/types/export.types.d.ts +57 -13
- package/dist/lib/types/export.types.d.ts.map +1 -1
- package/dist/lib/types/slots.types.d.ts +12 -1
- package/dist/lib/types/slots.types.d.ts.map +1 -1
- package/dist/lib/types/table.types.d.ts +1 -3
- package/dist/lib/types/table.types.d.ts.map +1 -1
- package/dist/lib/utils/debounced-fetch.utils.d.ts +8 -4
- package/dist/lib/utils/debounced-fetch.utils.d.ts.map +1 -1
- package/dist/lib/utils/debounced-fetch.utils.js +63 -14
- package/dist/lib/utils/export-utils.d.ts +14 -4
- package/dist/lib/utils/export-utils.d.ts.map +1 -1
- package/dist/lib/utils/export-utils.js +362 -66
- package/dist/lib/utils/slot-helpers.d.ts +1 -1
- package/dist/lib/utils/slot-helpers.d.ts.map +1 -1
- package/package.json +4 -2
- package/src/lib/components/droupdown/menu-dropdown.tsx +9 -3
- package/src/lib/components/filters/filter-value-input.tsx +2 -2
- package/src/lib/components/pagination/data-table-pagination.tsx +14 -2
- package/src/lib/components/toolbar/data-table-toolbar.tsx +15 -1
- package/src/lib/components/toolbar/table-export-control.tsx +65 -9
- package/src/lib/components/toolbar/table-refresh-control.tsx +58 -0
- package/src/lib/contexts/data-table-context.tsx +16 -2
- package/src/lib/data-table.tsx +1282 -932
- package/src/lib/features/column-filter.feature.ts +40 -19
- package/src/lib/features/selection.feature.ts +11 -5
- package/src/lib/types/column.types.ts +20 -1
- package/src/lib/types/data-table-api.ts +37 -15
- package/src/lib/types/data-table.types.ts +59 -3
- package/src/lib/types/export.types.ts +79 -10
- package/src/lib/types/slots.types.ts +11 -1
- package/src/lib/types/table.types.ts +1 -3
- package/src/lib/utils/debounced-fetch.utils.ts +90 -18
- package/src/lib/utils/export-utils.ts +496 -69
- package/src/lib/utils/slot-helpers.tsx +1 -1
package/dist/lib/data-table.js
CHANGED
|
@@ -89,7 +89,7 @@ const DEFAULT_INITIAL_STATE = {
|
|
|
89
89
|
*/
|
|
90
90
|
exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, columns, data = [], totalRow = 0, idKey = 'id', extraFilter = null, footerFilter = null,
|
|
91
91
|
// Data management mode (MUI DataGrid style)
|
|
92
|
-
dataMode = 'client', initialLoadData = true, onFetchData, onDataStateChange,
|
|
92
|
+
dataMode = 'client', initialLoadData = true, onFetchData, onRefreshData, onDataChange, onDataStateChange,
|
|
93
93
|
// Selection props
|
|
94
94
|
enableRowSelection = false, enableMultiRowSelection = true, selectMode = 'page', isRowSelectable, onSelectionChange,
|
|
95
95
|
// Row click props
|
|
@@ -111,7 +111,7 @@ enablePagination = false, paginationMode = 'client',
|
|
|
111
111
|
// Filtering props
|
|
112
112
|
enableGlobalFilter = true, enableColumnFilter = false, filterMode = 'client',
|
|
113
113
|
// Sorting props
|
|
114
|
-
enableSorting = true, sortingMode = 'client', onSortingChange, exportFilename = 'export', onExportProgress, onExportComplete, onExportError, onServerExport, onExportCancel,
|
|
114
|
+
enableSorting = true, sortingMode = 'client', onSortingChange, exportFilename = 'export', exportConcurrency = 'cancelAndRestart', exportChunkSize = 1000, exportStrictTotalCheck = false, exportSanitizeCSV = true, onExportProgress, onExportComplete, onExportError, onServerExport, onExportCancel, onExportStateChange,
|
|
115
115
|
// Styling props
|
|
116
116
|
enableHover = true, enableStripes = false, tableProps = {}, fitToScreen = true, tableSize: initialTableSize = 'medium',
|
|
117
117
|
// Sticky header/footer props
|
|
@@ -119,7 +119,7 @@ enableStickyHeaderOrFooter = false, maxHeight = '400px',
|
|
|
119
119
|
// Virtualization props
|
|
120
120
|
enableVirtualization = false, estimateRowHeight = 52,
|
|
121
121
|
// Toolbar props
|
|
122
|
-
enableTableSizeControl = true, enableExport = false, enableReset = true,
|
|
122
|
+
enableTableSizeControl = true, enableExport = false, enableReset = true, enableRefresh = false,
|
|
123
123
|
// Loading and empty states
|
|
124
124
|
loading = false, emptyMessage = 'No data available', skeletonRows = 5,
|
|
125
125
|
// Column filters props
|
|
@@ -184,14 +184,24 @@ logging, }, ref) {
|
|
|
184
184
|
const [serverData, setServerData] = (0, react_1.useState)(null);
|
|
185
185
|
const [serverTotal, setServerTotal] = (0, react_1.useState)(0);
|
|
186
186
|
const [exportController, setExportController] = (0, react_1.useState)(null);
|
|
187
|
+
const [exportProgress, setExportProgress] = (0, react_1.useState)({});
|
|
188
|
+
const [exportPhase, setExportPhase] = (0, react_1.useState)(null);
|
|
189
|
+
const [queuedExportCount, setQueuedExportCount] = (0, react_1.useState)(0);
|
|
187
190
|
// -------------------------------
|
|
188
191
|
// Ref hooks (grouped together)
|
|
189
192
|
// -------------------------------
|
|
190
193
|
const tableContainerRef = (0, react_1.useRef)(null);
|
|
191
194
|
const internalApiRef = (0, react_1.useRef)(null);
|
|
195
|
+
const exportControllerRef = (0, react_1.useRef)(null);
|
|
196
|
+
const exportQueueRef = (0, react_1.useRef)(Promise.resolve());
|
|
197
|
+
const isExternallyControlledData = (0, react_1.useMemo)(() => !onFetchData && (!!onDataChange || !!onRefreshData), [onFetchData, onDataChange, onRefreshData]);
|
|
192
198
|
const { debouncedFetch, isLoading: fetchLoading } = (0, debounced_fetch_utils_1.useDebouncedFetch)(onFetchData);
|
|
193
|
-
const tableData = (0, react_1.useMemo)(() =>
|
|
194
|
-
|
|
199
|
+
const tableData = (0, react_1.useMemo)(() => {
|
|
200
|
+
if (isExternallyControlledData)
|
|
201
|
+
return data;
|
|
202
|
+
return serverData !== null ? serverData : data;
|
|
203
|
+
}, [isExternallyControlledData, serverData, data]);
|
|
204
|
+
const tableTotalRow = (0, react_1.useMemo)(() => (isExternallyControlledData ? (totalRow || data.length) : (serverData !== null ? serverTotal : totalRow || data.length)), [isExternallyControlledData, serverData, serverTotal, totalRow, data]);
|
|
195
205
|
const tableLoading = (0, react_1.useMemo)(() => onFetchData ? (loading || fetchLoading) : loading, [onFetchData, loading, fetchLoading]);
|
|
196
206
|
const enhancedColumns = (0, react_1.useMemo)(() => {
|
|
197
207
|
let columnsMap = [...columns];
|
|
@@ -239,7 +249,7 @@ logging, }, ref) {
|
|
|
239
249
|
// Callback hooks (grouped together)
|
|
240
250
|
// -------------------------------
|
|
241
251
|
const fetchData = (0, react_1.useCallback)(async (overrides = {}, options) => {
|
|
242
|
-
var _a, _b;
|
|
252
|
+
var _a, _b, _c, _d, _e;
|
|
243
253
|
if (!onFetchData) {
|
|
244
254
|
if (logger.isLevelEnabled('debug')) {
|
|
245
255
|
logger.debug('onFetchData not provided, skipping fetch', { overrides, columnFilter, sorting, pagination });
|
|
@@ -254,17 +264,25 @@ logging, }, ref) {
|
|
|
254
264
|
...overrides,
|
|
255
265
|
};
|
|
256
266
|
if (logger.isLevelEnabled('info')) {
|
|
257
|
-
logger.info('Requesting data', {
|
|
267
|
+
logger.info('Requesting data', {
|
|
268
|
+
filters,
|
|
269
|
+
reason: (_a = options === null || options === void 0 ? void 0 : options.meta) === null || _a === void 0 ? void 0 : _a.reason,
|
|
270
|
+
force: (_b = options === null || options === void 0 ? void 0 : options.meta) === null || _b === void 0 ? void 0 : _b.force,
|
|
271
|
+
});
|
|
258
272
|
}
|
|
259
273
|
try {
|
|
260
|
-
const
|
|
274
|
+
const delay = (_c = options === null || options === void 0 ? void 0 : options.delay) !== null && _c !== void 0 ? _c : 300; // respects 0
|
|
275
|
+
const result = await debouncedFetch(filters, {
|
|
276
|
+
debounceDelay: delay,
|
|
277
|
+
meta: options === null || options === void 0 ? void 0 : options.meta,
|
|
278
|
+
});
|
|
261
279
|
if (logger.isLevelEnabled('info')) {
|
|
262
280
|
logger.info('Fetch resolved', {
|
|
263
|
-
rows: (
|
|
281
|
+
rows: (_e = (_d = result === null || result === void 0 ? void 0 : result.data) === null || _d === void 0 ? void 0 : _d.length) !== null && _e !== void 0 ? _e : 0,
|
|
264
282
|
total: result === null || result === void 0 ? void 0 : result.total,
|
|
265
283
|
});
|
|
266
284
|
}
|
|
267
|
-
if (
|
|
285
|
+
if (result && Array.isArray(result.data) && result.total !== undefined) {
|
|
268
286
|
setServerData(result.data);
|
|
269
287
|
setServerTotal(result.total);
|
|
270
288
|
}
|
|
@@ -286,67 +304,35 @@ logging, }, ref) {
|
|
|
286
304
|
debouncedFetch,
|
|
287
305
|
logger,
|
|
288
306
|
]);
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
307
|
+
const normalizeRefreshOptions = (0, react_1.useCallback)((options, fallbackReason = 'refresh') => {
|
|
308
|
+
var _a, _b, _c;
|
|
309
|
+
if (typeof options === 'boolean') {
|
|
310
|
+
return {
|
|
311
|
+
resetPagination: options,
|
|
312
|
+
force: false,
|
|
313
|
+
reason: fallbackReason,
|
|
314
|
+
};
|
|
295
315
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
pagination,
|
|
301
|
-
columnOrder,
|
|
302
|
-
columnPinning,
|
|
303
|
-
columnVisibility,
|
|
304
|
-
columnSizing,
|
|
305
|
-
...overrides,
|
|
316
|
+
return {
|
|
317
|
+
resetPagination: (_a = options === null || options === void 0 ? void 0 : options.resetPagination) !== null && _a !== void 0 ? _a : false,
|
|
318
|
+
force: (_b = options === null || options === void 0 ? void 0 : options.force) !== null && _b !== void 0 ? _b : false,
|
|
319
|
+
reason: (_c = options === null || options === void 0 ? void 0 : options.reason) !== null && _c !== void 0 ? _c : fallbackReason,
|
|
306
320
|
};
|
|
307
|
-
|
|
308
|
-
logger.debug('Emitting tableStateChange', currentState);
|
|
309
|
-
}
|
|
310
|
-
onDataStateChange === null || onDataStateChange === void 0 ? void 0 : onDataStateChange(currentState);
|
|
311
|
-
}, [
|
|
312
|
-
onDataStateChange,
|
|
313
|
-
globalFilter,
|
|
314
|
-
columnFilter,
|
|
315
|
-
sorting,
|
|
316
|
-
pagination,
|
|
317
|
-
columnOrder,
|
|
318
|
-
columnPinning,
|
|
319
|
-
columnVisibility,
|
|
320
|
-
columnSizing,
|
|
321
|
-
logger,
|
|
322
|
-
]);
|
|
321
|
+
}, []);
|
|
323
322
|
const handleSelectionStateChange = (0, react_1.useCallback)((updaterOrValue) => {
|
|
324
323
|
setSelectionState((prevState) => {
|
|
325
|
-
const
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
setTimeout(() => {
|
|
329
|
-
if (onSelectionChange) {
|
|
330
|
-
onSelectionChange(newSelectionState);
|
|
331
|
-
}
|
|
332
|
-
if (onDataStateChange) {
|
|
333
|
-
tableStateChange({ selectionState: newSelectionState });
|
|
334
|
-
}
|
|
335
|
-
}, 0);
|
|
336
|
-
return newSelectionState;
|
|
324
|
+
const next = typeof updaterOrValue === 'function' ? updaterOrValue(prevState) : updaterOrValue;
|
|
325
|
+
onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange(next);
|
|
326
|
+
return next;
|
|
337
327
|
});
|
|
338
|
-
}, [onSelectionChange
|
|
328
|
+
}, [onSelectionChange]);
|
|
339
329
|
const handleColumnFilterStateChange = (0, react_1.useCallback)((filterState) => {
|
|
340
330
|
if (!filterState || typeof filterState !== 'object')
|
|
341
331
|
return;
|
|
342
332
|
setColumnFilter(filterState);
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
if (onDataStateChange) {
|
|
347
|
-
setTimeout(() => tableStateChange({ columnFilter: filterState }), 0);
|
|
348
|
-
}
|
|
349
|
-
}, [onColumnFiltersChange, onDataStateChange, tableStateChange]);
|
|
333
|
+
onColumnFiltersChange === null || onColumnFiltersChange === void 0 ? void 0 : onColumnFiltersChange(filterState);
|
|
334
|
+
return filterState;
|
|
335
|
+
}, [onColumnFiltersChange]);
|
|
350
336
|
const resetPageToFirst = (0, react_1.useCallback)(() => {
|
|
351
337
|
if (logger.isLevelEnabled('info')) {
|
|
352
338
|
logger.info('Resetting to first page due to state change', {
|
|
@@ -360,40 +346,17 @@ logging, }, ref) {
|
|
|
360
346
|
return newPagination;
|
|
361
347
|
}, [pagination, logger, onPaginationChange]);
|
|
362
348
|
const handleSortingChange = (0, react_1.useCallback)((updaterOrValue) => {
|
|
363
|
-
|
|
364
|
-
? updaterOrValue(
|
|
365
|
-
:
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
logger.debug('Sorting change applied', {
|
|
371
|
-
sorting: newSorting,
|
|
372
|
-
serverMode: isServerMode,
|
|
373
|
-
serverSorting: isServerSorting,
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
|
-
if (isServerMode || isServerSorting) {
|
|
377
|
-
const pagination = resetPageToFirst();
|
|
378
|
-
if (logger.isLevelEnabled('debug')) {
|
|
379
|
-
logger.debug('Sorting change triggered server fetch', { pagination, sorting: newSorting });
|
|
349
|
+
setSorting((prev) => {
|
|
350
|
+
const next = typeof updaterOrValue === 'function' ? updaterOrValue(prev) : updaterOrValue;
|
|
351
|
+
const cleaned = next.filter((s) => s === null || s === void 0 ? void 0 : s.id);
|
|
352
|
+
onSortingChange === null || onSortingChange === void 0 ? void 0 : onSortingChange(cleaned);
|
|
353
|
+
const nextPagination = resetPageToFirst();
|
|
354
|
+
if (isServerMode || isServerSorting) {
|
|
355
|
+
fetchData({ sorting: cleaned, pagination: nextPagination }, { delay: 0 });
|
|
380
356
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
pagination,
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
else if (onDataStateChange) {
|
|
388
|
-
const pagination = resetPageToFirst();
|
|
389
|
-
setTimeout(() => {
|
|
390
|
-
if (logger.isLevelEnabled('debug')) {
|
|
391
|
-
logger.debug('Sorting change notified client state change', { pagination, sorting: newSorting });
|
|
392
|
-
}
|
|
393
|
-
tableStateChange({ sorting: newSorting, pagination });
|
|
394
|
-
}, 0);
|
|
395
|
-
}
|
|
396
|
-
}, [sorting, onSortingChange, logger, isServerMode, isServerSorting, onDataStateChange, resetPageToFirst, tableStateChange, fetchData]);
|
|
357
|
+
return cleaned;
|
|
358
|
+
});
|
|
359
|
+
}, [onSortingChange, isServerMode, isServerSorting, resetPageToFirst, fetchData]);
|
|
397
360
|
const handleColumnOrderChange = (0, react_1.useCallback)((updatedColumnOrder) => {
|
|
398
361
|
const newColumnOrder = typeof updatedColumnOrder === 'function'
|
|
399
362
|
? updatedColumnOrder(columnOrder)
|
|
@@ -403,131 +366,52 @@ logging, }, ref) {
|
|
|
403
366
|
onColumnDragEnd(newColumnOrder);
|
|
404
367
|
}
|
|
405
368
|
}, [onColumnDragEnd, columnOrder]);
|
|
406
|
-
const handleColumnPinningChange = (0, react_1.useCallback)((
|
|
407
|
-
|
|
408
|
-
?
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
}, [onColumnPinningChange, columnPinning]);
|
|
369
|
+
const handleColumnPinningChange = (0, react_1.useCallback)((updater) => {
|
|
370
|
+
setColumnPinning((prev) => {
|
|
371
|
+
const next = typeof updater === "function" ? updater(prev) : updater;
|
|
372
|
+
// keep direct callback here (optional)
|
|
373
|
+
onColumnPinningChange === null || onColumnPinningChange === void 0 ? void 0 : onColumnPinningChange(next);
|
|
374
|
+
return next;
|
|
375
|
+
});
|
|
376
|
+
}, [onColumnPinningChange]);
|
|
415
377
|
// Column visibility change handler - same pattern as column order
|
|
416
378
|
const handleColumnVisibilityChange = (0, react_1.useCallback)((updater) => {
|
|
417
|
-
|
|
418
|
-
? updater(
|
|
419
|
-
:
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
onColumnVisibilityChange(newVisibility);
|
|
424
|
-
}, 0);
|
|
425
|
-
}
|
|
426
|
-
if (onDataStateChange) {
|
|
427
|
-
setTimeout(() => {
|
|
428
|
-
tableStateChange({ columnVisibility: newVisibility });
|
|
429
|
-
}, 0);
|
|
430
|
-
}
|
|
431
|
-
}, [onColumnVisibilityChange, onDataStateChange, tableStateChange, columnVisibility]);
|
|
379
|
+
setColumnVisibility((prev) => {
|
|
380
|
+
const next = typeof updater === 'function' ? updater(prev) : updater;
|
|
381
|
+
onColumnVisibilityChange === null || onColumnVisibilityChange === void 0 ? void 0 : onColumnVisibilityChange(next);
|
|
382
|
+
return next;
|
|
383
|
+
});
|
|
384
|
+
}, [onColumnVisibilityChange]);
|
|
432
385
|
// Column sizing change handler - same pattern as column order
|
|
433
386
|
const handleColumnSizingChange = (0, react_1.useCallback)((updater) => {
|
|
434
|
-
|
|
435
|
-
? updater(
|
|
436
|
-
:
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
onColumnSizingChange(newSizing);
|
|
441
|
-
}, 0);
|
|
442
|
-
}
|
|
443
|
-
if (onDataStateChange) {
|
|
444
|
-
setTimeout(() => {
|
|
445
|
-
tableStateChange({ columnSizing: newSizing });
|
|
446
|
-
}, 0);
|
|
447
|
-
}
|
|
448
|
-
}, [onColumnSizingChange, onDataStateChange, tableStateChange, columnSizing]);
|
|
387
|
+
setColumnSizing((prev) => {
|
|
388
|
+
const next = typeof updater === 'function' ? updater(prev) : updater;
|
|
389
|
+
onColumnSizingChange === null || onColumnSizingChange === void 0 ? void 0 : onColumnSizingChange(next);
|
|
390
|
+
return next;
|
|
391
|
+
});
|
|
392
|
+
}, [onColumnSizingChange]);
|
|
449
393
|
const handlePaginationChange = (0, react_1.useCallback)((updater) => {
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
next:
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
setPagination(newPagination);
|
|
460
|
-
onPaginationChange === null || onPaginationChange === void 0 ? void 0 : onPaginationChange(newPagination);
|
|
461
|
-
if (logger.isLevelEnabled('debug')) {
|
|
462
|
-
logger.debug('Pagination state updated', newPagination);
|
|
463
|
-
}
|
|
464
|
-
// Notify state change and fetch data if needed
|
|
465
|
-
if (isServerMode || isServerPagination) {
|
|
466
|
-
setTimeout(() => {
|
|
467
|
-
if (logger.isLevelEnabled('debug')) {
|
|
468
|
-
logger.debug('Notifying server-side pagination change', newPagination);
|
|
469
|
-
}
|
|
470
|
-
tableStateChange({ pagination: newPagination });
|
|
471
|
-
fetchData({ pagination: newPagination });
|
|
472
|
-
}, 0);
|
|
473
|
-
}
|
|
474
|
-
else if (onDataStateChange) {
|
|
475
|
-
setTimeout(() => {
|
|
476
|
-
if (logger.isLevelEnabled('debug')) {
|
|
477
|
-
logger.debug('Notifying client-side pagination change', newPagination);
|
|
478
|
-
}
|
|
479
|
-
tableStateChange({ pagination: newPagination });
|
|
480
|
-
}, 0);
|
|
481
|
-
}
|
|
482
|
-
}, [
|
|
483
|
-
pagination,
|
|
484
|
-
isServerMode,
|
|
485
|
-
isServerPagination,
|
|
486
|
-
onDataStateChange,
|
|
487
|
-
fetchData,
|
|
488
|
-
tableStateChange,
|
|
489
|
-
logger,
|
|
490
|
-
onPaginationChange,
|
|
491
|
-
]);
|
|
394
|
+
setPagination((prev) => {
|
|
395
|
+
const next = typeof updater === 'function' ? updater(prev) : updater;
|
|
396
|
+
onPaginationChange === null || onPaginationChange === void 0 ? void 0 : onPaginationChange(next);
|
|
397
|
+
if (isServerMode || isServerPagination) {
|
|
398
|
+
fetchData({ pagination: next }, { delay: 0 });
|
|
399
|
+
}
|
|
400
|
+
return next;
|
|
401
|
+
});
|
|
402
|
+
}, [isServerMode, isServerPagination, fetchData, onPaginationChange]);
|
|
492
403
|
const handleGlobalFilterChange = (0, react_1.useCallback)((updaterOrValue) => {
|
|
493
|
-
|
|
494
|
-
? updaterOrValue(
|
|
495
|
-
:
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
if (isServerMode || isServerFiltering) {
|
|
505
|
-
const pagination = resetPageToFirst();
|
|
506
|
-
setTimeout(() => {
|
|
507
|
-
if (logger.isLevelEnabled('debug')) {
|
|
508
|
-
logger.debug('Global filter change triggering server fetch', {
|
|
509
|
-
pagination,
|
|
510
|
-
value: newFilter,
|
|
511
|
-
});
|
|
512
|
-
}
|
|
513
|
-
tableStateChange({ globalFilter: newFilter, pagination });
|
|
514
|
-
fetchData({ globalFilter: newFilter, pagination });
|
|
515
|
-
}, 0);
|
|
516
|
-
}
|
|
517
|
-
else if (onDataStateChange) {
|
|
518
|
-
const pagination = resetPageToFirst();
|
|
519
|
-
setTimeout(() => {
|
|
520
|
-
if (logger.isLevelEnabled('debug')) {
|
|
521
|
-
logger.debug('Global filter change notifying client listeners', {
|
|
522
|
-
pagination,
|
|
523
|
-
value: newFilter,
|
|
524
|
-
});
|
|
525
|
-
}
|
|
526
|
-
tableStateChange({ globalFilter: newFilter, pagination });
|
|
527
|
-
}, 0);
|
|
528
|
-
}
|
|
529
|
-
onGlobalFilterChange === null || onGlobalFilterChange === void 0 ? void 0 : onGlobalFilterChange(newFilter);
|
|
530
|
-
}, [globalFilter, logger, isServerMode, isServerFiltering, onDataStateChange, onGlobalFilterChange, resetPageToFirst, tableStateChange, fetchData]);
|
|
404
|
+
setGlobalFilter((prev) => {
|
|
405
|
+
const next = typeof updaterOrValue === 'function' ? updaterOrValue(prev) : updaterOrValue;
|
|
406
|
+
onGlobalFilterChange === null || onGlobalFilterChange === void 0 ? void 0 : onGlobalFilterChange(next);
|
|
407
|
+
if (isServerMode || isServerFiltering) {
|
|
408
|
+
const nextPagination = { pageIndex: 0, pageSize: pagination.pageSize };
|
|
409
|
+
setPagination(nextPagination);
|
|
410
|
+
fetchData({ globalFilter: next, pagination: nextPagination }, { delay: 0 });
|
|
411
|
+
}
|
|
412
|
+
return next;
|
|
413
|
+
});
|
|
414
|
+
}, [isServerMode, isServerFiltering, onGlobalFilterChange, fetchData, pagination.pageSize]);
|
|
531
415
|
const onColumnFilterChangeHandler = (0, react_1.useCallback)((updater) => {
|
|
532
416
|
const currentState = columnFilter;
|
|
533
417
|
const newState = typeof updater === 'function'
|
|
@@ -544,22 +428,13 @@ logging, }, ref) {
|
|
|
544
428
|
const onColumnFilterApplyHandler = (0, react_1.useCallback)((appliedState) => {
|
|
545
429
|
const pagination = resetPageToFirst();
|
|
546
430
|
if (isServerFiltering) {
|
|
547
|
-
tableStateChange({
|
|
548
|
-
columnFilter: appliedState,
|
|
549
|
-
pagination,
|
|
550
|
-
});
|
|
551
431
|
fetchData({
|
|
552
432
|
columnFilter: appliedState,
|
|
553
433
|
pagination,
|
|
554
434
|
});
|
|
555
435
|
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
}
|
|
559
|
-
setTimeout(() => {
|
|
560
|
-
onColumnFiltersChange === null || onColumnFiltersChange === void 0 ? void 0 : onColumnFiltersChange(appliedState);
|
|
561
|
-
}, 0);
|
|
562
|
-
}, [resetPageToFirst, isServerFiltering, onDataStateChange, tableStateChange, fetchData, onColumnFiltersChange]);
|
|
436
|
+
onColumnFiltersChange === null || onColumnFiltersChange === void 0 ? void 0 : onColumnFiltersChange(appliedState);
|
|
437
|
+
}, [resetPageToFirst, isServerFiltering, fetchData, onColumnFiltersChange]);
|
|
563
438
|
// -------------------------------
|
|
564
439
|
// Table creation (after callbacks/memo)
|
|
565
440
|
// -------------------------------
|
|
@@ -681,12 +556,21 @@ logging, }, ref) {
|
|
|
681
556
|
// -------------------------------
|
|
682
557
|
// Effects (after callbacks)
|
|
683
558
|
// -------------------------------
|
|
559
|
+
(0, react_1.useEffect)(() => {
|
|
560
|
+
if (!isExternallyControlledData || serverData === null)
|
|
561
|
+
return;
|
|
562
|
+
setServerData(null);
|
|
563
|
+
setServerTotal(0);
|
|
564
|
+
}, [isExternallyControlledData, serverData]);
|
|
684
565
|
(0, react_1.useEffect)(() => {
|
|
685
566
|
if (initialLoadData && onFetchData) {
|
|
686
567
|
if (logger.isLevelEnabled('info')) {
|
|
687
568
|
logger.info('Initial data load triggered', { initialLoadData });
|
|
688
569
|
}
|
|
689
|
-
fetchData({}
|
|
570
|
+
fetchData({}, {
|
|
571
|
+
delay: 0,
|
|
572
|
+
meta: { reason: 'initial' },
|
|
573
|
+
});
|
|
690
574
|
}
|
|
691
575
|
else if (logger.isLevelEnabled('debug')) {
|
|
692
576
|
logger.debug('Skipping initial data load', {
|
|
@@ -710,502 +594,739 @@ logging, }, ref) {
|
|
|
710
594
|
setColumnOrder(initialOrder);
|
|
711
595
|
}
|
|
712
596
|
}, [enableColumnDragging, enhancedColumns, columnOrder.length]);
|
|
713
|
-
const
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
597
|
+
const lastSentRef = (0, react_1.useRef)("");
|
|
598
|
+
const emitTableState = (0, react_1.useCallback)(() => {
|
|
599
|
+
if (!onDataStateChange)
|
|
600
|
+
return;
|
|
601
|
+
const live = table.getState();
|
|
602
|
+
const liveColumnFilter = live.columnFilter;
|
|
603
|
+
// only keep what you persist/store
|
|
604
|
+
const payload = {
|
|
605
|
+
sorting: live.sorting,
|
|
606
|
+
pagination: live.pagination,
|
|
607
|
+
globalFilter: live.globalFilter,
|
|
608
|
+
columnFilter: liveColumnFilter,
|
|
609
|
+
columnVisibility: live.columnVisibility,
|
|
610
|
+
columnSizing: live.columnSizing,
|
|
611
|
+
columnOrder: live.columnOrder,
|
|
612
|
+
columnPinning: live.columnPinning,
|
|
613
|
+
};
|
|
614
|
+
const key = JSON.stringify(payload);
|
|
615
|
+
if (key === lastSentRef.current)
|
|
616
|
+
return;
|
|
617
|
+
lastSentRef.current = key;
|
|
618
|
+
onDataStateChange(payload);
|
|
619
|
+
}, [onDataStateChange, table]);
|
|
620
|
+
(0, react_1.useEffect)(() => {
|
|
621
|
+
emitTableState();
|
|
622
|
+
}, [
|
|
623
|
+
emitTableState,
|
|
624
|
+
sorting,
|
|
625
|
+
pagination,
|
|
626
|
+
globalFilter,
|
|
627
|
+
columnFilter,
|
|
628
|
+
columnVisibility,
|
|
629
|
+
columnSizing,
|
|
630
|
+
columnOrder,
|
|
631
|
+
columnPinning,
|
|
632
|
+
]);
|
|
633
|
+
const getResetState = (0, react_1.useCallback)(() => {
|
|
634
|
+
var _a;
|
|
635
|
+
const resetSorting = initialStateConfig.sorting || [];
|
|
636
|
+
const resetGlobalFilter = (_a = initialStateConfig.globalFilter) !== null && _a !== void 0 ? _a : '';
|
|
637
|
+
const resetColumnFilter = initialStateConfig.columnFilter;
|
|
638
|
+
const resetPagination = enablePagination
|
|
639
|
+
? (initialStateConfig.pagination || { pageIndex: 0, pageSize: 10 })
|
|
640
|
+
: undefined;
|
|
641
|
+
return {
|
|
642
|
+
sorting: resetSorting,
|
|
643
|
+
globalFilter: resetGlobalFilter,
|
|
644
|
+
columnFilter: resetColumnFilter,
|
|
645
|
+
...(resetPagination ? { pagination: resetPagination } : {}),
|
|
646
|
+
};
|
|
647
|
+
}, [initialStateConfig, enablePagination]);
|
|
648
|
+
const applyDataMutation = (0, react_1.useCallback)((action, updater, details = {}) => {
|
|
649
|
+
const previousData = [...tableData];
|
|
650
|
+
const nextData = updater(previousData);
|
|
651
|
+
if (nextData === previousData)
|
|
652
|
+
return nextData;
|
|
653
|
+
const nextTotal = Math.max(0, tableTotalRow + (nextData.length - previousData.length));
|
|
654
|
+
if (!isExternallyControlledData) {
|
|
655
|
+
setServerData(nextData);
|
|
656
|
+
setServerTotal(nextTotal);
|
|
657
|
+
}
|
|
658
|
+
onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(nextData, {
|
|
659
|
+
action,
|
|
660
|
+
previousData,
|
|
661
|
+
nextData,
|
|
662
|
+
totalRow: nextTotal,
|
|
663
|
+
...details,
|
|
664
|
+
});
|
|
665
|
+
if (logger.isLevelEnabled('debug')) {
|
|
666
|
+
logger.debug('Applied data mutation', {
|
|
667
|
+
action,
|
|
668
|
+
previousCount: previousData.length,
|
|
669
|
+
nextCount: nextData.length,
|
|
670
|
+
totalRow: nextTotal,
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
return nextData;
|
|
674
|
+
}, [isExternallyControlledData, logger, onDataChange, tableData, tableTotalRow]);
|
|
675
|
+
const buildRefreshContext = (0, react_1.useCallback)((options, paginationOverride) => {
|
|
676
|
+
const state = table.getState();
|
|
677
|
+
const nextPagination = paginationOverride || state.pagination || pagination;
|
|
678
|
+
return {
|
|
679
|
+
filters: {
|
|
680
|
+
globalFilter,
|
|
681
|
+
pagination: nextPagination,
|
|
682
|
+
columnFilter,
|
|
683
|
+
sorting,
|
|
684
|
+
},
|
|
685
|
+
state: {
|
|
686
|
+
sorting,
|
|
687
|
+
pagination: nextPagination,
|
|
688
|
+
globalFilter,
|
|
689
|
+
columnFilter,
|
|
690
|
+
columnVisibility: state.columnVisibility,
|
|
691
|
+
columnSizing: state.columnSizing,
|
|
692
|
+
columnOrder: state.columnOrder,
|
|
693
|
+
columnPinning: state.columnPinning,
|
|
694
|
+
},
|
|
695
|
+
options,
|
|
696
|
+
};
|
|
697
|
+
}, [table, pagination, globalFilter, columnFilter, sorting]);
|
|
698
|
+
const triggerRefresh = (0, react_1.useCallback)(async (options, fallbackReason = 'refresh') => {
|
|
699
|
+
const normalizedOptions = normalizeRefreshOptions(options, fallbackReason);
|
|
700
|
+
const nextPagination = enablePagination
|
|
701
|
+
? {
|
|
702
|
+
pageIndex: normalizedOptions.resetPagination ? 0 : pagination.pageIndex,
|
|
703
|
+
pageSize: pagination.pageSize,
|
|
704
|
+
}
|
|
705
|
+
: undefined;
|
|
706
|
+
const shouldUpdatePagination = !!nextPagination
|
|
707
|
+
&& (nextPagination.pageIndex !== pagination.pageIndex || nextPagination.pageSize !== pagination.pageSize);
|
|
708
|
+
if (nextPagination && shouldUpdatePagination) {
|
|
709
|
+
setPagination(nextPagination);
|
|
710
|
+
onPaginationChange === null || onPaginationChange === void 0 ? void 0 : onPaginationChange(nextPagination);
|
|
711
|
+
}
|
|
712
|
+
const refreshContext = buildRefreshContext(normalizedOptions, nextPagination);
|
|
713
|
+
if (onRefreshData) {
|
|
714
|
+
await onRefreshData(refreshContext);
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
if (onFetchData) {
|
|
718
|
+
await fetchData(nextPagination ? { pagination: nextPagination } : {}, {
|
|
719
|
+
delay: 0,
|
|
720
|
+
meta: {
|
|
721
|
+
reason: normalizedOptions.reason,
|
|
722
|
+
force: normalizedOptions.force,
|
|
723
|
+
},
|
|
724
|
+
});
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
if (logger.isLevelEnabled('debug')) {
|
|
728
|
+
logger.debug('Refresh skipped because no refresh handler is configured', refreshContext);
|
|
729
|
+
}
|
|
730
|
+
}, [
|
|
731
|
+
normalizeRefreshOptions,
|
|
732
|
+
enablePagination,
|
|
733
|
+
pagination,
|
|
734
|
+
onPaginationChange,
|
|
735
|
+
buildRefreshContext,
|
|
736
|
+
onRefreshData,
|
|
737
|
+
onFetchData,
|
|
738
|
+
fetchData,
|
|
739
|
+
logger,
|
|
740
|
+
]);
|
|
741
|
+
const resetAllAndReload = (0, react_1.useCallback)(() => {
|
|
742
|
+
var _a;
|
|
743
|
+
const resetState = getResetState();
|
|
744
|
+
setSorting(resetState.sorting || []);
|
|
745
|
+
setGlobalFilter((_a = resetState.globalFilter) !== null && _a !== void 0 ? _a : '');
|
|
746
|
+
setColumnFilter(resetState.columnFilter);
|
|
747
|
+
if (resetState.pagination) {
|
|
748
|
+
setPagination(resetState.pagination);
|
|
749
|
+
onPaginationChange === null || onPaginationChange === void 0 ? void 0 : onPaginationChange(resetState.pagination);
|
|
750
|
+
}
|
|
751
|
+
setSelectionState(initialSelectionState);
|
|
752
|
+
setExpanded({});
|
|
753
|
+
// layout state
|
|
754
|
+
setColumnVisibility(initialStateConfig.columnVisibility || {});
|
|
755
|
+
setColumnSizing(initialStateConfig.columnSizing || {});
|
|
756
|
+
setColumnOrder(initialStateConfig.columnOrder || []);
|
|
757
|
+
setColumnPinning(initialStateConfig.columnPinning || { left: [], right: [] });
|
|
758
|
+
const resetOptions = normalizeRefreshOptions({
|
|
759
|
+
resetPagination: true,
|
|
760
|
+
force: true,
|
|
761
|
+
reason: 'reset',
|
|
762
|
+
}, 'reset');
|
|
763
|
+
const refreshContext = buildRefreshContext(resetOptions, resetState.pagination);
|
|
764
|
+
if (onRefreshData) {
|
|
765
|
+
void onRefreshData(refreshContext);
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
if (onFetchData) {
|
|
769
|
+
void fetchData(resetState, {
|
|
770
|
+
delay: 0,
|
|
771
|
+
meta: {
|
|
772
|
+
reason: resetOptions.reason,
|
|
773
|
+
force: resetOptions.force,
|
|
774
|
+
},
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
}, [
|
|
778
|
+
getResetState,
|
|
779
|
+
initialSelectionState,
|
|
780
|
+
initialStateConfig,
|
|
781
|
+
onPaginationChange,
|
|
782
|
+
normalizeRefreshOptions,
|
|
783
|
+
buildRefreshContext,
|
|
784
|
+
onRefreshData,
|
|
785
|
+
onFetchData,
|
|
786
|
+
fetchData,
|
|
787
|
+
]);
|
|
788
|
+
const setExportControllerSafely = (0, react_1.useCallback)((value) => {
|
|
789
|
+
setExportController((current) => {
|
|
790
|
+
const next = typeof value === 'function' ? value(current) : value;
|
|
791
|
+
exportControllerRef.current = next;
|
|
792
|
+
return next;
|
|
793
|
+
});
|
|
794
|
+
}, []);
|
|
795
|
+
const handleExportProgressInternal = (0, react_1.useCallback)((progress) => {
|
|
796
|
+
setExportProgress(progress || {});
|
|
797
|
+
onExportProgress === null || onExportProgress === void 0 ? void 0 : onExportProgress(progress);
|
|
798
|
+
}, [onExportProgress]);
|
|
799
|
+
const handleExportStateChangeInternal = (0, react_1.useCallback)((state) => {
|
|
800
|
+
setExportPhase(state.phase);
|
|
801
|
+
if (state.processedRows !== undefined
|
|
802
|
+
|| state.totalRows !== undefined
|
|
803
|
+
|| state.percentage !== undefined) {
|
|
804
|
+
setExportProgress({
|
|
805
|
+
processedRows: state.processedRows,
|
|
806
|
+
totalRows: state.totalRows,
|
|
807
|
+
percentage: state.percentage,
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
onExportStateChange === null || onExportStateChange === void 0 ? void 0 : onExportStateChange(state);
|
|
811
|
+
}, [onExportStateChange]);
|
|
812
|
+
const runExportWithPolicy = (0, react_1.useCallback)(async (options) => {
|
|
813
|
+
const { format, filename, mode, execute } = options;
|
|
814
|
+
const startExecution = async () => {
|
|
815
|
+
const controller = new AbortController();
|
|
816
|
+
setExportProgress({});
|
|
817
|
+
setExportControllerSafely(controller);
|
|
818
|
+
try {
|
|
819
|
+
await execute(controller);
|
|
820
|
+
}
|
|
821
|
+
finally {
|
|
822
|
+
setExportControllerSafely((current) => (current === controller ? null : current));
|
|
823
|
+
}
|
|
824
|
+
};
|
|
825
|
+
if (exportConcurrency === 'queue') {
|
|
826
|
+
setQueuedExportCount((prev) => prev + 1);
|
|
827
|
+
const runQueued = async () => {
|
|
828
|
+
setQueuedExportCount((prev) => Math.max(0, prev - 1));
|
|
829
|
+
await startExecution();
|
|
830
|
+
};
|
|
831
|
+
const queuedPromise = exportQueueRef.current
|
|
832
|
+
.catch(() => undefined)
|
|
833
|
+
.then(runQueued);
|
|
834
|
+
exportQueueRef.current = queuedPromise;
|
|
835
|
+
return queuedPromise;
|
|
836
|
+
}
|
|
837
|
+
const activeController = exportControllerRef.current;
|
|
838
|
+
if (activeController) {
|
|
839
|
+
if (exportConcurrency === 'ignoreIfRunning') {
|
|
840
|
+
handleExportStateChangeInternal({
|
|
841
|
+
phase: 'error',
|
|
842
|
+
mode,
|
|
843
|
+
format,
|
|
844
|
+
filename,
|
|
845
|
+
message: 'An export is already running',
|
|
846
|
+
code: 'EXPORT_IN_PROGRESS',
|
|
847
|
+
endedAt: Date.now(),
|
|
893
848
|
});
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
filters: [],
|
|
898
|
-
logic: 'AND',
|
|
899
|
-
pendingFilters: [],
|
|
900
|
-
pendingLogic: 'AND',
|
|
849
|
+
onExportError === null || onExportError === void 0 ? void 0 : onExportError({
|
|
850
|
+
message: 'An export is already running',
|
|
851
|
+
code: 'EXPORT_IN_PROGRESS',
|
|
901
852
|
});
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
}
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
if (exportConcurrency === 'cancelAndRestart') {
|
|
856
|
+
activeController.abort();
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
await startExecution();
|
|
860
|
+
}, [
|
|
861
|
+
exportConcurrency,
|
|
862
|
+
handleExportStateChangeInternal,
|
|
863
|
+
onExportError,
|
|
864
|
+
setExportControllerSafely,
|
|
865
|
+
]);
|
|
866
|
+
const dataTableApi = (0, react_1.useMemo)(() => {
|
|
867
|
+
// helpers (avoid repeating boilerplate)
|
|
868
|
+
const buildInitialOrder = () => enhancedColumns.map((col, index) => {
|
|
869
|
+
if (col.id)
|
|
870
|
+
return col.id;
|
|
871
|
+
const anyCol = col;
|
|
872
|
+
if (anyCol.accessorKey && typeof anyCol.accessorKey === "string")
|
|
873
|
+
return anyCol.accessorKey;
|
|
874
|
+
return `column_${index}`;
|
|
875
|
+
});
|
|
876
|
+
const applyColumnOrder = (next) => {
|
|
877
|
+
// handleColumnOrderChange supports both Updater<ColumnOrderState> and array in your impl
|
|
878
|
+
handleColumnOrderChange(next);
|
|
879
|
+
};
|
|
880
|
+
const applyPinning = (next) => {
|
|
881
|
+
handleColumnPinningChange(next);
|
|
882
|
+
};
|
|
883
|
+
const applyVisibility = (next) => {
|
|
884
|
+
handleColumnVisibilityChange(next);
|
|
885
|
+
};
|
|
886
|
+
const applySizing = (next) => {
|
|
887
|
+
handleColumnSizingChange(next);
|
|
888
|
+
};
|
|
889
|
+
const applyPagination = (next) => {
|
|
890
|
+
handlePaginationChange(next);
|
|
891
|
+
};
|
|
892
|
+
const applySorting = (next) => {
|
|
893
|
+
handleSortingChange(next);
|
|
894
|
+
};
|
|
895
|
+
const applyGlobalFilter = (next) => {
|
|
896
|
+
handleGlobalFilterChange(next);
|
|
897
|
+
};
|
|
898
|
+
const getRowIndexById = (rowsToSearch, rowId) => rowsToSearch.findIndex((row, index) => String((0, utils_1.generateRowId)(row, index, idKey)) === rowId);
|
|
899
|
+
const clampInsertIndex = (rowsToMutate, insertIndex) => {
|
|
900
|
+
if (insertIndex === undefined)
|
|
901
|
+
return rowsToMutate.length;
|
|
902
|
+
return Math.max(0, Math.min(insertIndex, rowsToMutate.length));
|
|
903
|
+
};
|
|
904
|
+
return {
|
|
905
|
+
table: {
|
|
906
|
+
getTable: () => table,
|
|
907
|
+
},
|
|
908
|
+
// -------------------------------
|
|
909
|
+
// Column Management
|
|
910
|
+
// -------------------------------
|
|
911
|
+
columnVisibility: {
|
|
912
|
+
showColumn: (columnId) => {
|
|
913
|
+
applyVisibility({ ...table.getState().columnVisibility, [columnId]: true });
|
|
914
|
+
},
|
|
915
|
+
hideColumn: (columnId) => {
|
|
916
|
+
applyVisibility({ ...table.getState().columnVisibility, [columnId]: false });
|
|
917
|
+
},
|
|
918
|
+
toggleColumn: (columnId) => {
|
|
919
|
+
var _a, _b;
|
|
920
|
+
const curr = (_b = (_a = table.getState().columnVisibility) === null || _a === void 0 ? void 0 : _a[columnId]) !== null && _b !== void 0 ? _b : true;
|
|
921
|
+
applyVisibility({ ...table.getState().columnVisibility, [columnId]: !curr });
|
|
922
|
+
},
|
|
923
|
+
showAllColumns: () => {
|
|
924
|
+
// set all known columns true
|
|
925
|
+
const all = {};
|
|
926
|
+
table.getAllLeafColumns().forEach((c) => (all[c.id] = true));
|
|
927
|
+
applyVisibility(all);
|
|
928
|
+
},
|
|
929
|
+
hideAllColumns: () => {
|
|
930
|
+
const all = {};
|
|
931
|
+
table.getAllLeafColumns().forEach((c) => (all[c.id] = false));
|
|
932
|
+
applyVisibility(all);
|
|
933
|
+
},
|
|
934
|
+
resetColumnVisibility: () => {
|
|
935
|
+
const initialVisibility = initialStateConfig.columnVisibility || {};
|
|
936
|
+
applyVisibility(initialVisibility);
|
|
937
|
+
},
|
|
938
|
+
},
|
|
939
|
+
// -------------------------------
|
|
940
|
+
// Column Ordering
|
|
941
|
+
// -------------------------------
|
|
942
|
+
columnOrdering: {
|
|
943
|
+
setColumnOrder: (nextOrder) => {
|
|
944
|
+
applyColumnOrder(nextOrder);
|
|
945
|
+
},
|
|
946
|
+
moveColumn: (columnId, toIndex) => {
|
|
947
|
+
var _a;
|
|
948
|
+
const currentOrder = (((_a = table.getState().columnOrder) === null || _a === void 0 ? void 0 : _a.length) ? table.getState().columnOrder : buildInitialOrder()) || [];
|
|
949
|
+
const fromIndex = currentOrder.indexOf(columnId);
|
|
950
|
+
if (fromIndex === -1)
|
|
951
|
+
return;
|
|
952
|
+
const next = [...currentOrder];
|
|
953
|
+
next.splice(fromIndex, 1);
|
|
954
|
+
next.splice(toIndex, 0, columnId);
|
|
955
|
+
applyColumnOrder(next);
|
|
956
|
+
},
|
|
957
|
+
resetColumnOrder: () => {
|
|
958
|
+
applyColumnOrder(buildInitialOrder());
|
|
959
|
+
},
|
|
960
|
+
},
|
|
961
|
+
// -------------------------------
|
|
962
|
+
// Column Pinning
|
|
963
|
+
// -------------------------------
|
|
964
|
+
columnPinning: {
|
|
965
|
+
pinColumnLeft: (columnId) => {
|
|
966
|
+
const current = table.getState().columnPinning || { left: [], right: [] };
|
|
967
|
+
const next = {
|
|
968
|
+
left: [...(current.left || []).filter((id) => id !== columnId), columnId],
|
|
969
|
+
right: (current.right || []).filter((id) => id !== columnId),
|
|
970
|
+
};
|
|
971
|
+
applyPinning(next);
|
|
972
|
+
},
|
|
973
|
+
pinColumnRight: (columnId) => {
|
|
974
|
+
const current = table.getState().columnPinning || { left: [], right: [] };
|
|
975
|
+
const next = {
|
|
976
|
+
left: (current.left || []).filter((id) => id !== columnId),
|
|
977
|
+
// keep your "prepend" behavior
|
|
978
|
+
right: [columnId, ...(current.right || []).filter((id) => id !== columnId)],
|
|
979
|
+
};
|
|
980
|
+
applyPinning(next);
|
|
981
|
+
},
|
|
982
|
+
unpinColumn: (columnId) => {
|
|
983
|
+
const current = table.getState().columnPinning || { left: [], right: [] };
|
|
984
|
+
const next = {
|
|
985
|
+
left: (current.left || []).filter((id) => id !== columnId),
|
|
986
|
+
right: (current.right || []).filter((id) => id !== columnId),
|
|
987
|
+
};
|
|
988
|
+
applyPinning(next);
|
|
989
|
+
},
|
|
990
|
+
setPinning: (pinning) => {
|
|
991
|
+
applyPinning(pinning);
|
|
992
|
+
},
|
|
993
|
+
resetColumnPinning: () => {
|
|
994
|
+
const initialPinning = initialStateConfig.columnPinning || { left: [], right: [] };
|
|
995
|
+
applyPinning(initialPinning);
|
|
996
|
+
},
|
|
997
|
+
},
|
|
998
|
+
// -------------------------------
|
|
999
|
+
// Column Resizing
|
|
1000
|
+
// -------------------------------
|
|
1001
|
+
columnResizing: {
|
|
1002
|
+
resizeColumn: (columnId, width) => {
|
|
1003
|
+
const currentSizing = table.getState().columnSizing || {};
|
|
1004
|
+
applySizing({ ...currentSizing, [columnId]: width });
|
|
1005
|
+
},
|
|
1006
|
+
autoSizeColumn: (columnId) => {
|
|
1007
|
+
// safe to call tanstack helper; it will feed into onColumnSizingChange if wired,
|
|
1008
|
+
// but since you're controlled, we still prefer to update through handler:
|
|
1009
|
+
const col = table.getColumn(columnId);
|
|
1010
|
+
if (!col)
|
|
1011
|
+
return;
|
|
1012
|
+
col.resetSize();
|
|
1013
|
+
// after resetSize, read state and emit via handler so controlled stays synced
|
|
1014
|
+
applySizing({ ...(table.getState().columnSizing || {}) });
|
|
1015
|
+
},
|
|
1016
|
+
autoSizeAllColumns: () => {
|
|
1017
|
+
const initialSizing = initialStateConfig.columnSizing || {};
|
|
1018
|
+
applySizing(initialSizing);
|
|
1019
|
+
},
|
|
1020
|
+
resetColumnSizing: () => {
|
|
1021
|
+
const initialSizing = initialStateConfig.columnSizing || {};
|
|
1022
|
+
applySizing(initialSizing);
|
|
1023
|
+
},
|
|
1024
|
+
},
|
|
1025
|
+
// -------------------------------
|
|
1026
|
+
// Filtering
|
|
1027
|
+
// -------------------------------
|
|
1028
|
+
filtering: {
|
|
1029
|
+
setGlobalFilter: (filter) => {
|
|
1030
|
+
applyGlobalFilter(filter);
|
|
1031
|
+
},
|
|
1032
|
+
clearGlobalFilter: () => {
|
|
1033
|
+
applyGlobalFilter("");
|
|
1034
|
+
},
|
|
1035
|
+
setColumnFilters: (filters) => {
|
|
1036
|
+
handleColumnFilterStateChange(filters);
|
|
1037
|
+
},
|
|
1038
|
+
addColumnFilter: (columnId, operator, value) => {
|
|
1039
|
+
const newFilter = {
|
|
1040
|
+
id: `filter_${Date.now()}`,
|
|
1041
|
+
columnId,
|
|
1042
|
+
operator,
|
|
1043
|
+
value,
|
|
1044
|
+
};
|
|
1045
|
+
const current = table.getState().columnFilter;
|
|
1046
|
+
const currentFilters = (current === null || current === void 0 ? void 0 : current.filters) || [];
|
|
1047
|
+
const nextFilters = [...currentFilters, newFilter];
|
|
1048
|
+
handleColumnFilterStateChange({
|
|
1049
|
+
filters: nextFilters,
|
|
1050
|
+
logic: current === null || current === void 0 ? void 0 : current.logic,
|
|
1051
|
+
pendingFilters: (current === null || current === void 0 ? void 0 : current.pendingFilters) || [],
|
|
1052
|
+
pendingLogic: (current === null || current === void 0 ? void 0 : current.pendingLogic) || "AND",
|
|
1053
|
+
});
|
|
1054
|
+
if (logger.isLevelEnabled("debug")) {
|
|
1055
|
+
logger.debug(`Adding column filter ${columnId} ${operator} ${value}`, nextFilters);
|
|
976
1056
|
}
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
toggleRowSelection: (rowId) => { var _a; return (_a = table.toggleRowSelected) === null || _a === void 0 ? void 0 : _a.call(table, rowId); },
|
|
991
|
-
selectAll: () => { var _a; return (_a = table.selectAll) === null || _a === void 0 ? void 0 : _a.call(table); },
|
|
992
|
-
deselectAll: () => { var _a; return (_a = table.deselectAll) === null || _a === void 0 ? void 0 : _a.call(table); },
|
|
993
|
-
toggleSelectAll: () => { var _a; return (_a = table.toggleAllRowsSelected) === null || _a === void 0 ? void 0 : _a.call(table); },
|
|
994
|
-
getSelectionState: () => { var _a; return ((_a = table.getSelectionState) === null || _a === void 0 ? void 0 : _a.call(table)) || { ids: [], type: 'include' }; },
|
|
995
|
-
getSelectedRows: () => table.getSelectedRows(),
|
|
996
|
-
getSelectedCount: () => table.getSelectedCount(),
|
|
997
|
-
isRowSelected: (rowId) => table.getIsRowSelected(rowId) || false,
|
|
998
|
-
},
|
|
999
|
-
// Data Management
|
|
1000
|
-
data: {
|
|
1001
|
-
refresh: (resetPagination = false) => {
|
|
1002
|
-
var _a, _b, _c;
|
|
1003
|
-
const filters = table.getState();
|
|
1004
|
-
const pagination = {
|
|
1005
|
-
pageIndex: resetPagination ? 0 : ((_a = initialStateConfig.pagination) === null || _a === void 0 ? void 0 : _a.pageIndex) || 0,
|
|
1006
|
-
pageSize: ((_b = filters.pagination) === null || _b === void 0 ? void 0 : _b.pageSize) || ((_c = initialStateConfig.pagination) === null || _c === void 0 ? void 0 : _c.pageSize) || 10,
|
|
1007
|
-
};
|
|
1008
|
-
const allState = table.getState();
|
|
1009
|
-
setPagination(pagination);
|
|
1010
|
-
onDataStateChange === null || onDataStateChange === void 0 ? void 0 : onDataStateChange({ ...allState, pagination });
|
|
1011
|
-
fetchData === null || fetchData === void 0 ? void 0 : fetchData({ pagination });
|
|
1012
|
-
if (logger.isLevelEnabled('debug')) {
|
|
1013
|
-
logger.debug('Refreshing data using Ref', { pagination, allState });
|
|
1014
|
-
}
|
|
1015
|
-
},
|
|
1016
|
-
reload: () => {
|
|
1017
|
-
const allState = table.getState();
|
|
1018
|
-
onDataStateChange === null || onDataStateChange === void 0 ? void 0 : onDataStateChange(allState);
|
|
1019
|
-
fetchData === null || fetchData === void 0 ? void 0 : fetchData({});
|
|
1020
|
-
if (logger.isLevelEnabled('debug')) {
|
|
1021
|
-
logger.info('Reloading data', allState);
|
|
1022
|
-
}
|
|
1023
|
-
},
|
|
1024
|
-
// Data CRUD operations
|
|
1025
|
-
getAllData: () => {
|
|
1026
|
-
var _a;
|
|
1027
|
-
return ((_a = table.getRowModel().rows) === null || _a === void 0 ? void 0 : _a.map(row => row.original)) || [];
|
|
1028
|
-
},
|
|
1029
|
-
getRowData: (rowId) => {
|
|
1030
|
-
var _a, _b;
|
|
1031
|
-
return (_b = (_a = table.getRowModel().rows) === null || _a === void 0 ? void 0 : _a.find(row => String(row.original[idKey]) === rowId)) === null || _b === void 0 ? void 0 : _b.original;
|
|
1032
|
-
},
|
|
1033
|
-
getRowByIndex: (index) => {
|
|
1034
|
-
var _a, _b;
|
|
1035
|
-
return (_b = (_a = table.getRowModel().rows) === null || _a === void 0 ? void 0 : _a[index]) === null || _b === void 0 ? void 0 : _b.original;
|
|
1036
|
-
},
|
|
1037
|
-
updateRow: (rowId, updates) => {
|
|
1038
|
-
var _a;
|
|
1039
|
-
const newData = (_a = table.getRowModel().rows) === null || _a === void 0 ? void 0 : _a.map(row => String(row.original[idKey]) === rowId
|
|
1040
|
-
? {
|
|
1041
|
-
...row.original,
|
|
1042
|
-
...updates,
|
|
1057
|
+
},
|
|
1058
|
+
removeColumnFilter: (filterId) => {
|
|
1059
|
+
const current = table.getState().columnFilter;
|
|
1060
|
+
const currentFilters = (current === null || current === void 0 ? void 0 : current.filters) || [];
|
|
1061
|
+
const nextFilters = currentFilters.filter((f) => f.id !== filterId);
|
|
1062
|
+
handleColumnFilterStateChange({
|
|
1063
|
+
filters: nextFilters,
|
|
1064
|
+
logic: current === null || current === void 0 ? void 0 : current.logic,
|
|
1065
|
+
pendingFilters: (current === null || current === void 0 ? void 0 : current.pendingFilters) || [],
|
|
1066
|
+
pendingLogic: (current === null || current === void 0 ? void 0 : current.pendingLogic) || "AND",
|
|
1067
|
+
});
|
|
1068
|
+
if (logger.isLevelEnabled("debug")) {
|
|
1069
|
+
logger.debug(`Removing column filter ${filterId}`, nextFilters);
|
|
1043
1070
|
}
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1071
|
+
},
|
|
1072
|
+
clearAllFilters: () => {
|
|
1073
|
+
applyGlobalFilter("");
|
|
1074
|
+
handleColumnFilterStateChange({
|
|
1075
|
+
filters: [],
|
|
1076
|
+
logic: "AND",
|
|
1077
|
+
pendingFilters: [],
|
|
1078
|
+
pendingLogic: "AND",
|
|
1079
|
+
});
|
|
1080
|
+
},
|
|
1081
|
+
resetFilters: () => {
|
|
1082
|
+
handleColumnFilterStateChange({
|
|
1083
|
+
filters: [],
|
|
1084
|
+
logic: "AND",
|
|
1085
|
+
pendingFilters: [],
|
|
1086
|
+
pendingLogic: "AND",
|
|
1087
|
+
});
|
|
1088
|
+
if (logger.isLevelEnabled("debug")) {
|
|
1089
|
+
logger.debug("Resetting filters");
|
|
1061
1090
|
}
|
|
1062
|
-
}
|
|
1063
|
-
},
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
}
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
setServerData === null || setServerData === void 0 ? void 0 : setServerData((newData === null || newData === void 0 ? void 0 : newData.map(row => row.original)) || []);
|
|
1082
|
-
if (logger.isLevelEnabled('debug')) {
|
|
1083
|
-
logger.debug(`Deleting row ${rowId}`);
|
|
1084
|
-
}
|
|
1085
|
-
},
|
|
1086
|
-
deleteRowByIndex: (index) => {
|
|
1087
|
-
var _a;
|
|
1088
|
-
const newData = (_a = (table.getRowModel().rows || [])) === null || _a === void 0 ? void 0 : _a.map(row => row.original);
|
|
1089
|
-
newData.splice(index, 1);
|
|
1090
|
-
setServerData(newData);
|
|
1091
|
-
if (logger.isLevelEnabled('debug')) {
|
|
1092
|
-
logger.debug(`Deleting row by index ${index}`);
|
|
1093
|
-
}
|
|
1094
|
-
},
|
|
1095
|
-
deleteSelectedRows: () => {
|
|
1096
|
-
var _a, _b, _c;
|
|
1097
|
-
const selectedRows = ((_a = table.getSelectedRows) === null || _a === void 0 ? void 0 : _a.call(table)) || [];
|
|
1098
|
-
if (selectedRows.length === 0)
|
|
1099
|
-
return;
|
|
1100
|
-
const selectedIds = new Set(selectedRows.map(row => String(row.original[idKey])));
|
|
1101
|
-
const newData = (_b = (table.getRowModel().rows || [])) === null || _b === void 0 ? void 0 : _b.filter(row => !selectedIds.has(String(row.original[idKey])));
|
|
1102
|
-
setServerData((newData === null || newData === void 0 ? void 0 : newData.map(row => row.original)) || []);
|
|
1103
|
-
(_c = table.deselectAll) === null || _c === void 0 ? void 0 : _c.call(table);
|
|
1104
|
-
if (logger.isLevelEnabled('debug')) {
|
|
1105
|
-
logger.debug('Deleting selected rows');
|
|
1106
|
-
}
|
|
1107
|
-
},
|
|
1108
|
-
replaceAllData: (newData) => {
|
|
1109
|
-
setServerData === null || setServerData === void 0 ? void 0 : setServerData(newData);
|
|
1110
|
-
},
|
|
1111
|
-
// Bulk operations
|
|
1112
|
-
updateMultipleRows: (updates) => {
|
|
1113
|
-
var _a;
|
|
1114
|
-
const updateMap = new Map(updates.map(u => [u.rowId, u.data]));
|
|
1115
|
-
const newData = (_a = (table.getRowModel().rows || [])) === null || _a === void 0 ? void 0 : _a.map(row => {
|
|
1116
|
-
const rowId = String(row.original[idKey]);
|
|
1117
|
-
const updateData = updateMap.get(rowId);
|
|
1118
|
-
return updateData ? {
|
|
1119
|
-
...row.original,
|
|
1120
|
-
...updateData,
|
|
1121
|
-
} : row.original;
|
|
1122
|
-
});
|
|
1123
|
-
setServerData(newData || []);
|
|
1124
|
-
},
|
|
1125
|
-
insertMultipleRows: (newRows, startIndex) => {
|
|
1126
|
-
var _a;
|
|
1127
|
-
const newData = (_a = (table.getRowModel().rows || [])) === null || _a === void 0 ? void 0 : _a.map(row => row.original);
|
|
1128
|
-
if (startIndex !== undefined) {
|
|
1129
|
-
newData.splice(startIndex, 0, ...newRows);
|
|
1130
|
-
}
|
|
1131
|
-
else {
|
|
1132
|
-
newData.push(...newRows);
|
|
1133
|
-
}
|
|
1134
|
-
setServerData === null || setServerData === void 0 ? void 0 : setServerData(newData);
|
|
1135
|
-
},
|
|
1136
|
-
deleteMultipleRows: (rowIds) => {
|
|
1137
|
-
var _a, _b;
|
|
1138
|
-
const idsToDelete = new Set(rowIds);
|
|
1139
|
-
const newData = (_b = (_a = (table.getRowModel().rows || [])) === null || _a === void 0 ? void 0 : _a.filter(row => !idsToDelete.has(String(row.original[idKey])))) === null || _b === void 0 ? void 0 : _b.map(row => row.original);
|
|
1140
|
-
setServerData(newData);
|
|
1141
|
-
},
|
|
1142
|
-
// Field-specific updates
|
|
1143
|
-
updateField: (rowId, fieldName, value) => {
|
|
1144
|
-
var _a;
|
|
1145
|
-
const newData = (_a = (table.getRowModel().rows || [])) === null || _a === void 0 ? void 0 : _a.map(row => String(row.original[idKey]) === rowId
|
|
1146
|
-
? {
|
|
1147
|
-
...row.original,
|
|
1148
|
-
[fieldName]: value,
|
|
1091
|
+
},
|
|
1092
|
+
},
|
|
1093
|
+
// -------------------------------
|
|
1094
|
+
// Sorting
|
|
1095
|
+
// -------------------------------
|
|
1096
|
+
sorting: {
|
|
1097
|
+
setSorting: (sortingState) => {
|
|
1098
|
+
applySorting(sortingState);
|
|
1099
|
+
if (logger.isLevelEnabled("debug"))
|
|
1100
|
+
logger.debug("Setting sorting", sortingState);
|
|
1101
|
+
},
|
|
1102
|
+
// NOTE: toggleSorting is okay, but can become "one behind" in controlled server mode.
|
|
1103
|
+
// So we implement deterministic sorting through handler.
|
|
1104
|
+
sortColumn: (columnId, direction) => {
|
|
1105
|
+
const current = table.getState().sorting || [];
|
|
1106
|
+
const filtered = current.filter((s) => s.id !== columnId);
|
|
1107
|
+
if (direction === false) {
|
|
1108
|
+
applySorting(filtered);
|
|
1109
|
+
return;
|
|
1149
1110
|
}
|
|
1150
|
-
:
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1111
|
+
applySorting([{ id: columnId, desc: direction === "desc" }, ...filtered]);
|
|
1112
|
+
},
|
|
1113
|
+
clearSorting: () => {
|
|
1114
|
+
applySorting([]);
|
|
1115
|
+
},
|
|
1116
|
+
resetSorting: () => {
|
|
1117
|
+
const initialSorting = initialStateConfig.sorting || [];
|
|
1118
|
+
applySorting(initialSorting);
|
|
1119
|
+
},
|
|
1120
|
+
},
|
|
1121
|
+
// -------------------------------
|
|
1122
|
+
// Pagination
|
|
1123
|
+
// -------------------------------
|
|
1124
|
+
pagination: {
|
|
1125
|
+
goToPage: (pageIndex) => {
|
|
1126
|
+
applyPagination((prev) => ({ ...prev, pageIndex }));
|
|
1127
|
+
if (logger.isLevelEnabled("debug"))
|
|
1128
|
+
logger.debug(`Going to page ${pageIndex}`);
|
|
1129
|
+
},
|
|
1130
|
+
nextPage: () => {
|
|
1131
|
+
applyPagination((prev) => { var _a; return ({ ...prev, pageIndex: ((_a = prev === null || prev === void 0 ? void 0 : prev.pageIndex) !== null && _a !== void 0 ? _a : 0) + 1 }); });
|
|
1132
|
+
if (logger.isLevelEnabled("debug"))
|
|
1133
|
+
logger.debug("Next page");
|
|
1134
|
+
},
|
|
1135
|
+
previousPage: () => {
|
|
1136
|
+
applyPagination((prev) => { var _a; return ({ ...prev, pageIndex: Math.max(0, ((_a = prev === null || prev === void 0 ? void 0 : prev.pageIndex) !== null && _a !== void 0 ? _a : 0) - 1) }); });
|
|
1137
|
+
if (logger.isLevelEnabled("debug"))
|
|
1138
|
+
logger.debug("Previous page");
|
|
1139
|
+
},
|
|
1140
|
+
setPageSize: (pageSize) => {
|
|
1141
|
+
// usually want pageIndex reset
|
|
1142
|
+
applyPagination(() => ({ pageIndex: 0, pageSize }));
|
|
1143
|
+
if (logger.isLevelEnabled("debug"))
|
|
1144
|
+
logger.debug(`Setting page size to ${pageSize}`);
|
|
1145
|
+
},
|
|
1146
|
+
goToFirstPage: () => {
|
|
1147
|
+
applyPagination((prev) => ({ ...prev, pageIndex: 0 }));
|
|
1148
|
+
if (logger.isLevelEnabled("debug"))
|
|
1149
|
+
logger.debug("Going to first page");
|
|
1150
|
+
},
|
|
1151
|
+
goToLastPage: () => {
|
|
1152
|
+
var _a, _b;
|
|
1153
|
+
// pageCount can be derived; keep safe fallback
|
|
1154
|
+
const pageCount = (_b = (_a = table.getPageCount) === null || _a === void 0 ? void 0 : _a.call(table)) !== null && _b !== void 0 ? _b : 0;
|
|
1155
|
+
if (pageCount > 0) {
|
|
1156
|
+
applyPagination((prev) => ({ ...prev, pageIndex: pageCount - 1 }));
|
|
1157
|
+
if (logger.isLevelEnabled("debug"))
|
|
1158
|
+
logger.debug(`Going to last page ${pageCount - 1}`);
|
|
1159
|
+
}
|
|
1160
|
+
},
|
|
1161
|
+
resetPagination: () => {
|
|
1162
|
+
const initialPagination = initialStateConfig.pagination || { pageIndex: 0, pageSize: 10 };
|
|
1163
|
+
applyPagination(initialPagination);
|
|
1164
|
+
},
|
|
1165
|
+
},
|
|
1166
|
+
// -------------------------------
|
|
1167
|
+
// Selection
|
|
1168
|
+
// -------------------------------
|
|
1169
|
+
selection: {
|
|
1170
|
+
selectRow: (rowId) => { var _a; return (_a = table.selectRow) === null || _a === void 0 ? void 0 : _a.call(table, rowId); },
|
|
1171
|
+
deselectRow: (rowId) => { var _a; return (_a = table.deselectRow) === null || _a === void 0 ? void 0 : _a.call(table, rowId); },
|
|
1172
|
+
toggleRowSelection: (rowId) => { var _a; return (_a = table.toggleRowSelected) === null || _a === void 0 ? void 0 : _a.call(table, rowId); },
|
|
1173
|
+
selectAll: () => { var _a; return (_a = table.selectAll) === null || _a === void 0 ? void 0 : _a.call(table); },
|
|
1174
|
+
deselectAll: () => { var _a; return (_a = table.deselectAll) === null || _a === void 0 ? void 0 : _a.call(table); },
|
|
1175
|
+
toggleSelectAll: () => { var _a; return (_a = table.toggleAllRowsSelected) === null || _a === void 0 ? void 0 : _a.call(table); },
|
|
1176
|
+
getSelectionState: () => { var _a; return ((_a = table.getSelectionState) === null || _a === void 0 ? void 0 : _a.call(table)) || { ids: [], type: "include" }; },
|
|
1177
|
+
getSelectedRows: () => table.getSelectedRows(),
|
|
1178
|
+
getSelectedCount: () => table.getSelectedCount(),
|
|
1179
|
+
isRowSelected: (rowId) => table.getIsRowSelected(rowId) || false,
|
|
1180
|
+
},
|
|
1181
|
+
// -------------------------------
|
|
1182
|
+
// Data Management (kept same, but ensure state changes go through handlers)
|
|
1183
|
+
// -------------------------------
|
|
1184
|
+
data: {
|
|
1185
|
+
refresh: (options) => {
|
|
1186
|
+
void triggerRefresh(options, 'refresh');
|
|
1187
|
+
},
|
|
1188
|
+
reload: (options = {}) => {
|
|
1189
|
+
var _a, _b;
|
|
1190
|
+
void triggerRefresh({
|
|
1191
|
+
...options,
|
|
1192
|
+
resetPagination: (_a = options.resetPagination) !== null && _a !== void 0 ? _a : false,
|
|
1193
|
+
reason: (_b = options.reason) !== null && _b !== void 0 ? _b : 'reload',
|
|
1194
|
+
}, 'reload');
|
|
1195
|
+
},
|
|
1196
|
+
resetAll: () => resetAllAndReload(),
|
|
1197
|
+
getAllData: () => [...tableData],
|
|
1198
|
+
getRowData: (rowId) => {
|
|
1199
|
+
const rowIndex = getRowIndexById(tableData, rowId);
|
|
1200
|
+
return rowIndex === -1 ? undefined : tableData[rowIndex];
|
|
1201
|
+
},
|
|
1202
|
+
getRowByIndex: (index) => tableData[index],
|
|
1203
|
+
updateRow: (rowId, updates) => {
|
|
1204
|
+
applyDataMutation('updateRow', (rowsToMutate) => {
|
|
1205
|
+
const rowIndex = getRowIndexById(rowsToMutate, rowId);
|
|
1206
|
+
if (rowIndex === -1)
|
|
1207
|
+
return rowsToMutate;
|
|
1208
|
+
const nextData = [...rowsToMutate];
|
|
1209
|
+
nextData[rowIndex] = { ...nextData[rowIndex], ...updates };
|
|
1210
|
+
return nextData;
|
|
1211
|
+
}, { rowId });
|
|
1212
|
+
},
|
|
1213
|
+
updateRowByIndex: (index, updates) => {
|
|
1214
|
+
applyDataMutation('updateRowByIndex', (rowsToMutate) => {
|
|
1215
|
+
if (!rowsToMutate[index])
|
|
1216
|
+
return rowsToMutate;
|
|
1217
|
+
const nextData = [...rowsToMutate];
|
|
1218
|
+
nextData[index] = { ...nextData[index], ...updates };
|
|
1219
|
+
return nextData;
|
|
1220
|
+
}, { index });
|
|
1221
|
+
},
|
|
1222
|
+
insertRow: (newRow, index) => {
|
|
1223
|
+
applyDataMutation('insertRow', (rowsToMutate) => {
|
|
1224
|
+
const nextData = [...rowsToMutate];
|
|
1225
|
+
nextData.splice(clampInsertIndex(nextData, index), 0, newRow);
|
|
1226
|
+
return nextData;
|
|
1227
|
+
}, { index });
|
|
1228
|
+
},
|
|
1229
|
+
deleteRow: (rowId) => {
|
|
1230
|
+
applyDataMutation('deleteRow', (rowsToMutate) => {
|
|
1231
|
+
const rowIndex = getRowIndexById(rowsToMutate, rowId);
|
|
1232
|
+
if (rowIndex === -1)
|
|
1233
|
+
return rowsToMutate;
|
|
1234
|
+
const nextData = [...rowsToMutate];
|
|
1235
|
+
nextData.splice(rowIndex, 1);
|
|
1236
|
+
return nextData;
|
|
1237
|
+
}, { rowId });
|
|
1238
|
+
},
|
|
1239
|
+
deleteRowByIndex: (index) => {
|
|
1240
|
+
applyDataMutation('deleteRowByIndex', (rowsToMutate) => {
|
|
1241
|
+
if (index < 0 || index >= rowsToMutate.length)
|
|
1242
|
+
return rowsToMutate;
|
|
1243
|
+
const nextData = [...rowsToMutate];
|
|
1244
|
+
nextData.splice(index, 1);
|
|
1245
|
+
return nextData;
|
|
1246
|
+
}, { index });
|
|
1247
|
+
},
|
|
1248
|
+
deleteSelectedRows: () => {
|
|
1249
|
+
var _a, _b, _c;
|
|
1250
|
+
const currentSelection = ((_a = table.getSelectionState) === null || _a === void 0 ? void 0 : _a.call(table)) || selectionState;
|
|
1251
|
+
const selectedIds = new Set((currentSelection.ids || []).map((id) => String(id)));
|
|
1252
|
+
const loadedRowIds = tableData.map((row, index) => String((0, utils_1.generateRowId)(row, index, idKey)));
|
|
1253
|
+
const deletableRowIds = currentSelection.type === 'exclude'
|
|
1254
|
+
? loadedRowIds.filter((rowId) => !selectedIds.has(rowId))
|
|
1255
|
+
: loadedRowIds.filter((rowId) => selectedIds.has(rowId));
|
|
1256
|
+
if (deletableRowIds.length === 0)
|
|
1257
|
+
return;
|
|
1258
|
+
if (currentSelection.type === 'exclude'
|
|
1259
|
+
&& table.getRowCount() > loadedRowIds.length
|
|
1260
|
+
&& logger.isLevelEnabled('info')) {
|
|
1261
|
+
logger.info('deleteSelectedRows in exclude mode removed currently loaded rows only', {
|
|
1262
|
+
removedRows: deletableRowIds.length,
|
|
1263
|
+
totalSelected: (_b = table.getSelectedCount) === null || _b === void 0 ? void 0 : _b.call(table),
|
|
1264
|
+
});
|
|
1265
|
+
}
|
|
1266
|
+
const deletableRowIdSet = new Set(deletableRowIds);
|
|
1267
|
+
applyDataMutation('deleteSelectedRows', (rowsToMutate) => rowsToMutate.filter((row, index) => !deletableRowIdSet.has(String((0, utils_1.generateRowId)(row, index, idKey)))), { rowIds: deletableRowIds });
|
|
1268
|
+
(_c = table.deselectAll) === null || _c === void 0 ? void 0 : _c.call(table);
|
|
1269
|
+
},
|
|
1270
|
+
replaceAllData: (newData) => {
|
|
1271
|
+
applyDataMutation('replaceAllData', () => [...newData]);
|
|
1272
|
+
},
|
|
1273
|
+
updateMultipleRows: (updates) => {
|
|
1274
|
+
const updateMap = new Map(updates.map((update) => [update.rowId, update.data]));
|
|
1275
|
+
applyDataMutation('updateMultipleRows', (rowsToMutate) => rowsToMutate.map((row, index) => {
|
|
1276
|
+
const currentRowId = String((0, utils_1.generateRowId)(row, index, idKey));
|
|
1277
|
+
const updateData = updateMap.get(currentRowId);
|
|
1278
|
+
return updateData ? { ...row, ...updateData } : row;
|
|
1279
|
+
}));
|
|
1280
|
+
},
|
|
1281
|
+
insertMultipleRows: (newRows, startIndex) => {
|
|
1282
|
+
applyDataMutation('insertMultipleRows', (rowsToMutate) => {
|
|
1283
|
+
const nextData = [...rowsToMutate];
|
|
1284
|
+
nextData.splice(clampInsertIndex(nextData, startIndex), 0, ...newRows);
|
|
1285
|
+
return nextData;
|
|
1286
|
+
}, { index: startIndex });
|
|
1287
|
+
},
|
|
1288
|
+
deleteMultipleRows: (rowIds) => {
|
|
1289
|
+
const idsToDelete = new Set(rowIds);
|
|
1290
|
+
applyDataMutation('deleteMultipleRows', (rowsToMutate) => rowsToMutate.filter((row, index) => !idsToDelete.has(String((0, utils_1.generateRowId)(row, index, idKey)))), { rowIds });
|
|
1291
|
+
},
|
|
1292
|
+
updateField: (rowId, fieldName, value) => {
|
|
1293
|
+
applyDataMutation('updateField', (rowsToMutate) => {
|
|
1294
|
+
const rowIndex = getRowIndexById(rowsToMutate, rowId);
|
|
1295
|
+
if (rowIndex === -1)
|
|
1296
|
+
return rowsToMutate;
|
|
1297
|
+
const nextData = [...rowsToMutate];
|
|
1298
|
+
nextData[rowIndex] = { ...nextData[rowIndex], [fieldName]: value };
|
|
1299
|
+
return nextData;
|
|
1300
|
+
}, { rowId });
|
|
1301
|
+
},
|
|
1302
|
+
updateFieldByIndex: (index, fieldName, value) => {
|
|
1303
|
+
applyDataMutation('updateFieldByIndex', (rowsToMutate) => {
|
|
1304
|
+
if (!rowsToMutate[index])
|
|
1305
|
+
return rowsToMutate;
|
|
1306
|
+
const nextData = [...rowsToMutate];
|
|
1307
|
+
nextData[index] = { ...nextData[index], [fieldName]: value };
|
|
1308
|
+
return nextData;
|
|
1309
|
+
}, { index });
|
|
1310
|
+
},
|
|
1311
|
+
findRows: (predicate) => tableData.filter(predicate),
|
|
1312
|
+
findRowIndex: (predicate) => tableData.findIndex(predicate),
|
|
1313
|
+
getDataCount: () => tableData.length,
|
|
1314
|
+
getFilteredDataCount: () => table.getFilteredRowModel().rows.length,
|
|
1315
|
+
},
|
|
1316
|
+
// -------------------------------
|
|
1317
|
+
// Layout Management
|
|
1318
|
+
// -------------------------------
|
|
1319
|
+
layout: {
|
|
1320
|
+
resetLayout: () => {
|
|
1321
|
+
var _a;
|
|
1322
|
+
// go through handlers so controlled state updates + emit works
|
|
1323
|
+
applySizing(initialStateConfig.columnSizing || {});
|
|
1324
|
+
applyVisibility(initialStateConfig.columnVisibility || {});
|
|
1325
|
+
applySorting(initialStateConfig.sorting || []);
|
|
1326
|
+
applyGlobalFilter((_a = initialStateConfig.globalFilter) !== null && _a !== void 0 ? _a : "");
|
|
1327
|
+
},
|
|
1328
|
+
resetAll: () => resetAllAndReload(),
|
|
1329
|
+
saveLayout: () => ({
|
|
1209
1330
|
columnVisibility: table.getState().columnVisibility,
|
|
1210
1331
|
columnSizing: table.getState().columnSizing,
|
|
1211
1332
|
columnOrder: table.getState().columnOrder,
|
|
@@ -1214,249 +1335,289 @@ logging, }, ref) {
|
|
|
1214
1335
|
pagination: table.getState().pagination,
|
|
1215
1336
|
globalFilter: table.getState().globalFilter,
|
|
1216
1337
|
columnFilter: table.getState().columnFilter,
|
|
1217
|
-
}
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1338
|
+
}),
|
|
1339
|
+
restoreLayout: (layout) => {
|
|
1340
|
+
if (layout.columnVisibility)
|
|
1341
|
+
applyVisibility(layout.columnVisibility);
|
|
1342
|
+
if (layout.columnSizing)
|
|
1343
|
+
applySizing(layout.columnSizing);
|
|
1344
|
+
if (layout.columnOrder)
|
|
1345
|
+
applyColumnOrder(layout.columnOrder);
|
|
1346
|
+
if (layout.columnPinning)
|
|
1347
|
+
applyPinning(layout.columnPinning);
|
|
1348
|
+
if (layout.sorting)
|
|
1349
|
+
applySorting(layout.sorting);
|
|
1350
|
+
if (layout.pagination && enablePagination)
|
|
1351
|
+
applyPagination(layout.pagination);
|
|
1352
|
+
if (layout.globalFilter !== undefined)
|
|
1353
|
+
applyGlobalFilter(layout.globalFilter);
|
|
1354
|
+
if (layout.columnFilter)
|
|
1355
|
+
handleColumnFilterStateChange(layout.columnFilter);
|
|
1356
|
+
},
|
|
1357
|
+
},
|
|
1358
|
+
// -------------------------------
|
|
1359
|
+
// Table State
|
|
1360
|
+
// -------------------------------
|
|
1361
|
+
state: {
|
|
1362
|
+
getTableState: () => table.getState(),
|
|
1363
|
+
getCurrentFilters: () => table.getState().columnFilter,
|
|
1364
|
+
getCurrentSorting: () => table.getState().sorting,
|
|
1365
|
+
getCurrentPagination: () => table.getState().pagination,
|
|
1366
|
+
getCurrentSelection: () => { var _a; return (_a = table.getSelectionState) === null || _a === void 0 ? void 0 : _a.call(table); },
|
|
1367
|
+
},
|
|
1368
|
+
// -------------------------------
|
|
1369
|
+
// Export (unchanged mostly)
|
|
1370
|
+
// -------------------------------
|
|
1371
|
+
export: {
|
|
1372
|
+
exportCSV: async (options = {}) => {
|
|
1373
|
+
const { filename = exportFilename, chunkSize = exportChunkSize, strictTotalCheck = exportStrictTotalCheck, sanitizeCSV = exportSanitizeCSV, } = options;
|
|
1374
|
+
const mode = dataMode === "server" && !!onServerExport ? 'server' : 'client';
|
|
1375
|
+
await runExportWithPolicy({
|
|
1376
|
+
format: 'csv',
|
|
1377
|
+
filename,
|
|
1378
|
+
mode,
|
|
1379
|
+
execute: async (controller) => {
|
|
1380
|
+
var _a;
|
|
1381
|
+
const toStateChange = (state) => {
|
|
1382
|
+
const isFinalPhase = state.phase === 'completed' || state.phase === 'cancelled' || state.phase === 'error';
|
|
1383
|
+
handleExportStateChangeInternal({
|
|
1384
|
+
phase: state.phase,
|
|
1385
|
+
mode,
|
|
1386
|
+
format: 'csv',
|
|
1387
|
+
filename,
|
|
1388
|
+
processedRows: state.processedRows,
|
|
1389
|
+
totalRows: state.totalRows,
|
|
1390
|
+
percentage: state.percentage,
|
|
1391
|
+
message: state.message,
|
|
1392
|
+
code: state.code,
|
|
1393
|
+
startedAt: state.phase === 'starting' ? Date.now() : undefined,
|
|
1394
|
+
endedAt: isFinalPhase ? Date.now() : undefined,
|
|
1395
|
+
queueLength: queuedExportCount,
|
|
1396
|
+
});
|
|
1397
|
+
if (state.phase === 'cancelled') {
|
|
1398
|
+
onExportCancel === null || onExportCancel === void 0 ? void 0 : onExportCancel();
|
|
1399
|
+
}
|
|
1400
|
+
};
|
|
1401
|
+
if (mode === 'server' && onServerExport) {
|
|
1402
|
+
const currentFilters = {
|
|
1403
|
+
globalFilter: table.getState().globalFilter,
|
|
1404
|
+
columnFilter: table.getState().columnFilter,
|
|
1405
|
+
sorting: table.getState().sorting,
|
|
1406
|
+
pagination: table.getState().pagination,
|
|
1407
|
+
};
|
|
1408
|
+
if (logger.isLevelEnabled("debug"))
|
|
1409
|
+
logger.debug("Server export CSV", { currentFilters });
|
|
1410
|
+
await (0, utils_1.exportServerData)(table, {
|
|
1411
|
+
format: "csv",
|
|
1412
|
+
filename,
|
|
1413
|
+
fetchData: (filters, selection, signal) => onServerExport(filters, selection, signal),
|
|
1414
|
+
currentFilters,
|
|
1415
|
+
selection: (_a = table.getSelectionState) === null || _a === void 0 ? void 0 : _a.call(table),
|
|
1416
|
+
onProgress: handleExportProgressInternal,
|
|
1417
|
+
onComplete: onExportComplete,
|
|
1418
|
+
onError: onExportError,
|
|
1419
|
+
onStateChange: toStateChange,
|
|
1420
|
+
signal: controller.signal,
|
|
1421
|
+
chunkSize,
|
|
1422
|
+
strictTotalCheck,
|
|
1423
|
+
sanitizeCSV,
|
|
1424
|
+
});
|
|
1425
|
+
return;
|
|
1426
|
+
}
|
|
1427
|
+
await (0, utils_1.exportClientData)(table, {
|
|
1428
|
+
format: "csv",
|
|
1429
|
+
filename,
|
|
1430
|
+
onProgress: handleExportProgressInternal,
|
|
1431
|
+
onComplete: onExportComplete,
|
|
1432
|
+
onError: onExportError,
|
|
1433
|
+
onStateChange: toStateChange,
|
|
1434
|
+
signal: controller.signal,
|
|
1435
|
+
sanitizeCSV,
|
|
1436
|
+
});
|
|
1437
|
+
if (logger.isLevelEnabled("debug"))
|
|
1438
|
+
logger.debug("Client export CSV", filename);
|
|
1308
1439
|
}
|
|
1309
|
-
}
|
|
1310
|
-
}
|
|
1311
|
-
catch (error) {
|
|
1312
|
-
onExportError === null || onExportError === void 0 ? void 0 : onExportError({
|
|
1313
|
-
message: error.message || 'Export failed',
|
|
1314
|
-
code: 'EXPORT_ERROR',
|
|
1315
1440
|
});
|
|
1316
|
-
}
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1441
|
+
},
|
|
1442
|
+
exportExcel: async (options = {}) => {
|
|
1443
|
+
const { filename = exportFilename, chunkSize = exportChunkSize, strictTotalCheck = exportStrictTotalCheck, sanitizeCSV = exportSanitizeCSV, } = options;
|
|
1444
|
+
const mode = dataMode === "server" && !!onServerExport ? 'server' : 'client';
|
|
1445
|
+
await runExportWithPolicy({
|
|
1446
|
+
format: 'excel',
|
|
1447
|
+
filename,
|
|
1448
|
+
mode,
|
|
1449
|
+
execute: async (controller) => {
|
|
1450
|
+
var _a;
|
|
1451
|
+
const toStateChange = (state) => {
|
|
1452
|
+
const isFinalPhase = state.phase === 'completed' || state.phase === 'cancelled' || state.phase === 'error';
|
|
1453
|
+
handleExportStateChangeInternal({
|
|
1454
|
+
phase: state.phase,
|
|
1455
|
+
mode,
|
|
1456
|
+
format: 'excel',
|
|
1457
|
+
filename,
|
|
1458
|
+
processedRows: state.processedRows,
|
|
1459
|
+
totalRows: state.totalRows,
|
|
1460
|
+
percentage: state.percentage,
|
|
1461
|
+
message: state.message,
|
|
1462
|
+
code: state.code,
|
|
1463
|
+
startedAt: state.phase === 'starting' ? Date.now() : undefined,
|
|
1464
|
+
endedAt: isFinalPhase ? Date.now() : undefined,
|
|
1465
|
+
queueLength: queuedExportCount,
|
|
1466
|
+
});
|
|
1467
|
+
if (state.phase === 'cancelled') {
|
|
1468
|
+
onExportCancel === null || onExportCancel === void 0 ? void 0 : onExportCancel();
|
|
1469
|
+
}
|
|
1470
|
+
};
|
|
1471
|
+
if (mode === 'server' && onServerExport) {
|
|
1472
|
+
const currentFilters = {
|
|
1473
|
+
globalFilter: table.getState().globalFilter,
|
|
1474
|
+
columnFilter: table.getState().columnFilter,
|
|
1475
|
+
sorting: table.getState().sorting,
|
|
1476
|
+
pagination: table.getState().pagination,
|
|
1477
|
+
};
|
|
1478
|
+
if (logger.isLevelEnabled("debug"))
|
|
1479
|
+
logger.debug("Server export Excel", { currentFilters });
|
|
1480
|
+
await (0, utils_1.exportServerData)(table, {
|
|
1481
|
+
format: "excel",
|
|
1482
|
+
filename,
|
|
1483
|
+
fetchData: (filters, selection, signal) => onServerExport(filters, selection, signal),
|
|
1484
|
+
currentFilters,
|
|
1485
|
+
selection: (_a = table.getSelectionState) === null || _a === void 0 ? void 0 : _a.call(table),
|
|
1486
|
+
onProgress: handleExportProgressInternal,
|
|
1487
|
+
onComplete: onExportComplete,
|
|
1488
|
+
onError: onExportError,
|
|
1489
|
+
onStateChange: toStateChange,
|
|
1490
|
+
signal: controller.signal,
|
|
1491
|
+
chunkSize,
|
|
1492
|
+
strictTotalCheck,
|
|
1493
|
+
sanitizeCSV,
|
|
1494
|
+
});
|
|
1495
|
+
return;
|
|
1496
|
+
}
|
|
1497
|
+
await (0, utils_1.exportClientData)(table, {
|
|
1498
|
+
format: "excel",
|
|
1499
|
+
filename,
|
|
1500
|
+
onProgress: handleExportProgressInternal,
|
|
1501
|
+
onComplete: onExportComplete,
|
|
1502
|
+
onError: onExportError,
|
|
1503
|
+
onStateChange: toStateChange,
|
|
1504
|
+
signal: controller.signal,
|
|
1505
|
+
sanitizeCSV,
|
|
1506
|
+
});
|
|
1507
|
+
if (logger.isLevelEnabled("debug"))
|
|
1508
|
+
logger.debug("Client export Excel", filename);
|
|
1361
1509
|
}
|
|
1362
|
-
}
|
|
1363
|
-
}
|
|
1364
|
-
catch (error) {
|
|
1365
|
-
onExportError === null || onExportError === void 0 ? void 0 : onExportError({
|
|
1366
|
-
message: error.message || 'Export failed',
|
|
1367
|
-
code: 'EXPORT_ERROR',
|
|
1368
|
-
});
|
|
1369
|
-
if (logger.isLevelEnabled('debug')) {
|
|
1370
|
-
logger.debug('Server export Excel failed', error);
|
|
1371
|
-
}
|
|
1372
|
-
}
|
|
1373
|
-
finally {
|
|
1374
|
-
setExportController === null || setExportController === void 0 ? void 0 : setExportController(null);
|
|
1375
|
-
}
|
|
1376
|
-
},
|
|
1377
|
-
exportServerData: async (options) => {
|
|
1378
|
-
var _a;
|
|
1379
|
-
const { format, filename = exportFilename, fetchData = onServerExport, } = options;
|
|
1380
|
-
if (!fetchData) {
|
|
1381
|
-
onExportError === null || onExportError === void 0 ? void 0 : onExportError({
|
|
1382
|
-
message: 'No server export function provided',
|
|
1383
|
-
code: 'NO_SERVER_EXPORT',
|
|
1384
1510
|
});
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
}
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
setExportController === null || setExportController === void 0 ? void 0 : setExportController(controller);
|
|
1394
|
-
const currentFilters = {
|
|
1395
|
-
globalFilter: table.getState().globalFilter,
|
|
1396
|
-
columnFilter: table.getState().columnFilter,
|
|
1397
|
-
sorting: table.getState().sorting,
|
|
1398
|
-
pagination: table.getState().pagination,
|
|
1399
|
-
};
|
|
1400
|
-
if (logger.isLevelEnabled('debug')) {
|
|
1401
|
-
logger.debug('Server export data', { currentFilters });
|
|
1511
|
+
},
|
|
1512
|
+
exportServerData: async (options) => {
|
|
1513
|
+
const { format, filename = exportFilename, fetchData: fetchFn = onServerExport, chunkSize = exportChunkSize, strictTotalCheck = exportStrictTotalCheck, sanitizeCSV = exportSanitizeCSV, } = options;
|
|
1514
|
+
if (!fetchFn) {
|
|
1515
|
+
onExportError === null || onExportError === void 0 ? void 0 : onExportError({ message: "No server export function provided", code: "NO_SERVER_EXPORT" });
|
|
1516
|
+
if (logger.isLevelEnabled("debug"))
|
|
1517
|
+
logger.debug("Server export data failed", "No server export function provided");
|
|
1518
|
+
return;
|
|
1402
1519
|
}
|
|
1403
|
-
await (
|
|
1520
|
+
await runExportWithPolicy({
|
|
1404
1521
|
format,
|
|
1405
1522
|
filename,
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1523
|
+
mode: 'server',
|
|
1524
|
+
execute: async (controller) => {
|
|
1525
|
+
var _a;
|
|
1526
|
+
const currentFilters = {
|
|
1527
|
+
globalFilter: table.getState().globalFilter,
|
|
1528
|
+
columnFilter: table.getState().columnFilter,
|
|
1529
|
+
sorting: table.getState().sorting,
|
|
1530
|
+
pagination: table.getState().pagination,
|
|
1531
|
+
};
|
|
1532
|
+
if (logger.isLevelEnabled("debug"))
|
|
1533
|
+
logger.debug("Server export data", { currentFilters });
|
|
1534
|
+
await (0, utils_1.exportServerData)(table, {
|
|
1535
|
+
format,
|
|
1536
|
+
filename,
|
|
1537
|
+
fetchData: (filters, selection, signal) => fetchFn(filters, selection, signal),
|
|
1538
|
+
currentFilters,
|
|
1539
|
+
selection: (_a = table.getSelectionState) === null || _a === void 0 ? void 0 : _a.call(table),
|
|
1540
|
+
onProgress: handleExportProgressInternal,
|
|
1541
|
+
onComplete: onExportComplete,
|
|
1542
|
+
onError: onExportError,
|
|
1543
|
+
onStateChange: (state) => {
|
|
1544
|
+
const isFinalPhase = state.phase === 'completed' || state.phase === 'cancelled' || state.phase === 'error';
|
|
1545
|
+
handleExportStateChangeInternal({
|
|
1546
|
+
phase: state.phase,
|
|
1547
|
+
mode: 'server',
|
|
1548
|
+
format,
|
|
1549
|
+
filename,
|
|
1550
|
+
processedRows: state.processedRows,
|
|
1551
|
+
totalRows: state.totalRows,
|
|
1552
|
+
percentage: state.percentage,
|
|
1553
|
+
message: state.message,
|
|
1554
|
+
code: state.code,
|
|
1555
|
+
startedAt: state.phase === 'starting' ? Date.now() : undefined,
|
|
1556
|
+
endedAt: isFinalPhase ? Date.now() : undefined,
|
|
1557
|
+
queueLength: queuedExportCount,
|
|
1558
|
+
});
|
|
1559
|
+
if (state.phase === 'cancelled') {
|
|
1560
|
+
onExportCancel === null || onExportCancel === void 0 ? void 0 : onExportCancel();
|
|
1561
|
+
}
|
|
1562
|
+
},
|
|
1563
|
+
signal: controller.signal,
|
|
1564
|
+
chunkSize,
|
|
1565
|
+
strictTotalCheck,
|
|
1566
|
+
sanitizeCSV,
|
|
1567
|
+
});
|
|
1568
|
+
}
|
|
1418
1569
|
});
|
|
1419
|
-
|
|
1420
|
-
|
|
1570
|
+
},
|
|
1571
|
+
isExporting: () => isExporting || false,
|
|
1572
|
+
cancelExport: () => {
|
|
1573
|
+
const activeController = exportControllerRef.current;
|
|
1574
|
+
if (!activeController) {
|
|
1575
|
+
return;
|
|
1421
1576
|
}
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1577
|
+
activeController.abort();
|
|
1578
|
+
setExportControllerSafely((current) => (current === activeController ? null : current));
|
|
1579
|
+
if (logger.isLevelEnabled("debug"))
|
|
1580
|
+
logger.debug("Export cancelled");
|
|
1581
|
+
},
|
|
1426
1582
|
},
|
|
1427
|
-
|
|
1428
|
-
isExporting: () => isExporting || false,
|
|
1429
|
-
cancelExport: () => {
|
|
1430
|
-
exportController === null || exportController === void 0 ? void 0 : exportController.abort();
|
|
1431
|
-
setExportController === null || setExportController === void 0 ? void 0 : setExportController(null);
|
|
1432
|
-
if (logger.isLevelEnabled('debug')) {
|
|
1433
|
-
logger.debug('Export cancelled');
|
|
1434
|
-
}
|
|
1435
|
-
},
|
|
1436
|
-
},
|
|
1583
|
+
};
|
|
1437
1584
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1438
|
-
}
|
|
1585
|
+
}, [
|
|
1439
1586
|
table,
|
|
1440
1587
|
enhancedColumns,
|
|
1588
|
+
handleColumnOrderChange,
|
|
1589
|
+
handleColumnPinningChange,
|
|
1590
|
+
handleColumnVisibilityChange,
|
|
1591
|
+
handleColumnSizingChange,
|
|
1592
|
+
handlePaginationChange,
|
|
1593
|
+
handleSortingChange,
|
|
1594
|
+
handleGlobalFilterChange,
|
|
1441
1595
|
handleColumnFilterStateChange,
|
|
1442
|
-
|
|
1443
|
-
onDataStateChange,
|
|
1444
|
-
fetchData,
|
|
1445
|
-
enableColumnPinning,
|
|
1596
|
+
initialStateConfig,
|
|
1446
1597
|
enablePagination,
|
|
1447
|
-
|
|
1598
|
+
idKey,
|
|
1599
|
+
triggerRefresh,
|
|
1600
|
+
applyDataMutation,
|
|
1601
|
+
tableData,
|
|
1602
|
+
selectionState,
|
|
1603
|
+
// export
|
|
1448
1604
|
exportFilename,
|
|
1449
|
-
|
|
1605
|
+
exportChunkSize,
|
|
1606
|
+
exportStrictTotalCheck,
|
|
1607
|
+
exportSanitizeCSV,
|
|
1450
1608
|
onExportComplete,
|
|
1451
1609
|
onExportError,
|
|
1610
|
+
onExportCancel,
|
|
1452
1611
|
onServerExport,
|
|
1453
|
-
|
|
1454
|
-
setExportController,
|
|
1612
|
+
queuedExportCount,
|
|
1455
1613
|
isExporting,
|
|
1456
1614
|
dataMode,
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1615
|
+
handleExportProgressInternal,
|
|
1616
|
+
handleExportStateChangeInternal,
|
|
1617
|
+
runExportWithPolicy,
|
|
1618
|
+
setExportControllerSafely,
|
|
1619
|
+
logger,
|
|
1620
|
+
resetAllAndReload,
|
|
1460
1621
|
]);
|
|
1461
1622
|
internalApiRef.current = dataTableApi;
|
|
1462
1623
|
(0, react_1.useImperativeHandle)(ref, () => dataTableApi, [dataTableApi]);
|
|
@@ -1515,14 +1676,12 @@ logging, }, ref) {
|
|
|
1515
1676
|
// Export cancel callback
|
|
1516
1677
|
// -------------------------------
|
|
1517
1678
|
const handleCancelExport = (0, react_1.useCallback)(() => {
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
onExportCancel();
|
|
1523
|
-
}
|
|
1679
|
+
const activeController = exportControllerRef.current;
|
|
1680
|
+
if (activeController) {
|
|
1681
|
+
activeController.abort();
|
|
1682
|
+
setExportControllerSafely((current) => (current === activeController ? null : current));
|
|
1524
1683
|
}
|
|
1525
|
-
}, [
|
|
1684
|
+
}, [setExportControllerSafely]);
|
|
1526
1685
|
// -------------------------------
|
|
1527
1686
|
// Slot components
|
|
1528
1687
|
// -------------------------------
|
|
@@ -1539,7 +1698,12 @@ logging, }, ref) {
|
|
|
1539
1698
|
// -------------------------------
|
|
1540
1699
|
return ((0, jsx_runtime_1.jsx)(data_table_context_1.DataTableProvider, { table: table, apiRef: internalApiRef, dataMode: dataMode, tableSize: tableSize, onTableSizeChange: (size) => {
|
|
1541
1700
|
setTableSize(size);
|
|
1542
|
-
}, columnFilter: columnFilter, onChangeColumnFilter: handleColumnFilterStateChange, slots: slots, slotProps: slotProps, isExporting: isExporting, exportController: exportController, onCancelExport: handleCancelExport, exportFilename: exportFilename, onExportProgress: onExportProgress, onExportComplete: onExportComplete, onExportError: onExportError, onServerExport: onServerExport, children: (0, jsx_runtime_1.jsxs)(RootComponent, { ...rootSlotProps, children: [(enableGlobalFilter || extraFilter) ? ((0, jsx_runtime_1.jsx)(ToolbarComponent, { extraFilter: extraFilter, enableGlobalFilter: enableGlobalFilter, enableColumnVisibility: enableColumnVisibility, enableColumnFilter: enableColumnFilter, enableExport: enableExport, enableReset: enableReset, enableTableSizeControl: enableTableSizeControl, enableColumnPinning: enableColumnPinning,
|
|
1701
|
+
}, columnFilter: columnFilter, onChangeColumnFilter: handleColumnFilterStateChange, slots: slots, slotProps: slotProps, isExporting: isExporting, exportController: exportController, exportPhase: exportPhase, exportProgress: exportProgress, onCancelExport: handleCancelExport, exportFilename: exportFilename, onExportProgress: onExportProgress, onExportComplete: onExportComplete, onExportError: onExportError, onServerExport: onServerExport, children: (0, jsx_runtime_1.jsxs)(RootComponent, { ...rootSlotProps, children: [(enableGlobalFilter || extraFilter) ? ((0, jsx_runtime_1.jsx)(ToolbarComponent, { extraFilter: extraFilter, enableGlobalFilter: enableGlobalFilter, enableColumnVisibility: enableColumnVisibility, enableColumnFilter: enableColumnFilter, enableExport: enableExport, enableReset: enableReset, enableTableSizeControl: enableTableSizeControl, enableColumnPinning: enableColumnPinning, enableRefresh: enableRefresh, ...toolbarSlotProps, refreshButtonProps: {
|
|
1702
|
+
loading: tableLoading, // disable while fetching
|
|
1703
|
+
showSpinnerWhileLoading: false,
|
|
1704
|
+
onRefresh: () => { var _a, _b, _c; return (_c = (_b = (_a = internalApiRef.current) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.refresh) === null || _c === void 0 ? void 0 : _c.call(_b, true); },
|
|
1705
|
+
...toolbarSlotProps.refreshButtonProps,
|
|
1706
|
+
} })) : null, enableBulkActions && enableRowSelection && isSomeRowsSelected ? ((0, jsx_runtime_1.jsx)(BulkActionsComponent, { selectionState: selectionState, selectedRowCount: selectedRowCount, bulkActions: bulkActions, sx: {
|
|
1543
1707
|
position: 'relative',
|
|
1544
1708
|
zIndex: 2,
|
|
1545
1709
|
...bulkActionsSlotProps.sx,
|