@ackplus/react-tanstack-data-table 1.0.22 → 1.0.24-b-1

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 CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  A powerful, feature-rich, and highly customizable React data table component built with Material-UI (MUI) and TanStack Table. Perfect for building modern data-intensive applications with advanced table functionality.
4
4
 
5
+ ## 🚀 Live Demo
6
+
7
+ **[View Live Demo](https://ack-solutions.github.io/react-tanstack-data-table/)**
8
+
9
+ Experience all the features in action with our interactive demo showcasing advanced table functionality, filtering, sorting, pagination, and more.
10
+
5
11
  ## ✨ Features
6
12
 
7
13
  - 🚀 **High Performance**: Built on TanStack Table for excellent performance with large datasets
@@ -18,6 +24,7 @@ A powerful, feature-rich, and highly customizable React data table component bui
18
24
  - 🎛️ **Highly Customizable**: Extensive customization through slots and props
19
25
  - 📝 **TypeScript**: Full TypeScript support with comprehensive type definitions
20
26
  - 🔌 **Extensible**: Plugin architecture with custom components and hooks
27
+ - 🛠️ **Debug Logging**: Configurable console instrumentation with global or per-table controls
21
28
 
22
29
  ## 📦 Installation
23
30
 
@@ -1359,6 +1366,34 @@ const handleClick = useCallback(() => {
1359
1366
  />
1360
1367
  ```
1361
1368
 
1369
+ ### Logging & Debugging
1370
+
1371
+ Use the built-in logger to trace pagination, server calls, and state transitions without sprinkling `console.log` statements throughout your app.
1372
+
1373
+ ```tsx
1374
+ import { DataTable, configureDataTableLogging } from '@ackplus/react-tanstack-data-table';
1375
+
1376
+ configureDataTableLogging({
1377
+ enabled: true,
1378
+ level: 'debug',
1379
+ includeTimestamp: true,
1380
+ });
1381
+
1382
+ <DataTable
1383
+ columns={columns}
1384
+ data={rows}
1385
+ logging={{
1386
+ enabled: true,
1387
+ level: 'info',
1388
+ prefix: 'OrdersTable',
1389
+ }}
1390
+ />
1391
+ ```
1392
+
1393
+ - Call `configureDataTableLogging` once (for example in your app bootstrap) to set global defaults.
1394
+ - Use the `logging` prop to override settings per table or disable instrumentation for specific instances.
1395
+ - When `logging` is omitted, instances inherit the global configuration.
1396
+
1362
1397
  ### Troubleshooting
1363
1398
 
1364
1399
  #### Common Issues
@@ -1422,6 +1457,7 @@ MIT © [ACK Solutions](https://github.com/ack-solutions)
1422
1457
 
1423
1458
  ## 🆘 Support
1424
1459
 
1460
+ - 🚀 [Live Demo](https://ack-solutions.github.io/react-tanstack-data-table/) - Interactive examples and playground
1425
1461
  - 📖 [Documentation](https://github.com/ack-solutions/react-tanstack-data-table)
1426
1462
  - 🐛 [Issue Tracker](https://github.com/ack-solutions/react-tanstack-data-table/issues)
1427
1463
  - 💬 [Discussions](https://github.com/ack-solutions/react-tanstack-data-table/discussions)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ackplus/react-tanstack-data-table",
3
3
  "type": "commonjs",
4
- "version": "1.0.22",
4
+ "version": "1.0.24-b-1",
5
5
  "description": "A powerful React data table component built with MUI and TanStack Table",
6
6
  "keywords": [
7
7
  "react",
package/src/index.d.ts CHANGED
@@ -10,6 +10,7 @@ export type { BulkActionsToolbarProps } from './lib/components/toolbar';
10
10
  export * from './lib/utils/styling-helpers';
11
11
  export * from './lib/utils/column-helpers';
12
12
  export * from './lib/utils/table-helpers';
13
+ export * from './lib/utils/logger';
13
14
  export * from './lib/hooks';
14
15
  export * from './lib/types';
15
16
  export type { Column, ColumnDef, Row, Table, Header, Cell, SortingState, ColumnFiltersState, VisibilityState, ColumnOrderState, ColumnPinningState, PaginationState, } from '@tanstack/react-table';
package/src/index.js CHANGED
@@ -20,6 +20,7 @@ Object.defineProperty(exports, "DataTableToolbar", { enumerable: true, get: func
20
20
  tslib_1.__exportStar(require("./lib/utils/styling-helpers"), exports);
21
21
  tslib_1.__exportStar(require("./lib/utils/column-helpers"), exports);
22
22
  tslib_1.__exportStar(require("./lib/utils/table-helpers"), exports);
23
+ tslib_1.__exportStar(require("./lib/utils/logger"), exports);
23
24
  tslib_1.__exportStar(require("./lib/hooks"), exports);
24
25
  tslib_1.__exportStar(require("./lib/types"), exports);
25
26
  tslib_1.__exportStar(require("./lib/features"), exports);
@@ -10,7 +10,6 @@ const features_1 = require("../../features");
10
10
  const react_virtual_1 = require("@tanstack/react-virtual");
11
11
  const react_1 = require("react");
12
12
  const data_table_context_1 = require("../../contexts/data-table-context");
13
- const use_data_table_api_1 = require("../../hooks/use-data-table-api");
14
13
  const utils_1 = require("../../utils");
15
14
  const debounced_fetch_utils_1 = require("../../utils/debounced-fetch.utils");
16
15
  const slot_helpers_1 = require("../../utils/slot-helpers");
@@ -19,6 +18,7 @@ const pagination_1 = require("../pagination");
19
18
  const rows_1 = require("../rows");
20
19
  const toolbar_1 = require("../toolbar");
21
20
  const special_columns_utils_1 = require("../../utils/special-columns.utils");
21
+ const lodash_1 = require("lodash");
22
22
  const DEFAULT_INITIAL_STATE = {
23
23
  sorting: [],
24
24
  pagination: {
@@ -40,12 +40,31 @@ const DEFAULT_INITIAL_STATE = {
40
40
  pendingLogic: 'AND',
41
41
  },
42
42
  };
43
- exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, columns, data = [], totalRow = 0, idKey = 'id', extraFilter = null, footerFilter = null, dataMode = 'client', initialLoadData = true, onFetchData, onDataStateChange, enableRowSelection = false, enableMultiRowSelection = true, selectMode = 'page', isRowSelectable, onSelectionChange, enableBulkActions = false, bulkActions, enableColumnResizing = false, columnResizeMode = 'onChange', enableColumnDragging = false, onColumnDragEnd, enableColumnPinning = false, onColumnPinningChange, enableExpanding = false, getRowCanExpand, renderSubComponent, enablePagination = true, paginationMode = 'client', enableGlobalFilter = true, enableColumnFilter = false, filterMode = 'client', enableSorting = true, sortingMode = 'client', onSortingChange, exportFilename = 'export', onExportProgress, onExportComplete, onExportError, onServerExport, onExportCancel, enableHover = true, enableStripes = false, tableContainerProps = {}, tableProps = {}, fitToScreen = true, tableSize: initialTableSize = 'medium', enableStickyHeaderOrFooter = false, maxHeight = '400px', enableVirtualization = false, estimateRowHeight = 52, enableColumnVisibility = true, enableTableSizeControl = true, enableExport = true, enableReset = true, loading = false, emptyMessage = 'No data available', skeletonRows = 5, onColumnFiltersChange, onPaginationChange, onGlobalFilterChange, slots = {}, slotProps = {}, }, ref) {
43
+ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, columns, data = [], totalRow = 0, idKey = 'id', extraFilter = null, footerFilter = null, dataMode = 'client', initialLoadData = true, onFetchData, onDataStateChange, enableRowSelection = false, enableMultiRowSelection = true, selectMode = 'page', isRowSelectable, onSelectionChange, enableBulkActions = false, bulkActions, enableColumnResizing = false, columnResizeMode = 'onChange', enableColumnDragging = false, onColumnDragEnd, enableColumnPinning = false, onColumnPinningChange, enableExpanding = false, getRowCanExpand, renderSubComponent, enablePagination = true, paginationMode = 'client', enableGlobalFilter = true, enableColumnFilter = false, filterMode = 'client', enableSorting = true, sortingMode = 'client', onSortingChange, exportFilename = 'export', onExportProgress, onExportComplete, onExportError, onServerExport, onExportCancel, enableHover = true, enableStripes = false, tableContainerProps = {}, tableProps = {}, fitToScreen = true, tableSize: initialTableSize = 'medium', enableStickyHeaderOrFooter = false, maxHeight = '400px', enableVirtualization = false, estimateRowHeight = 52, enableColumnVisibility = true, enableTableSizeControl = true, enableExport = true, enableReset = true, loading = false, emptyMessage = 'No data available', skeletonRows = 5, onColumnFiltersChange, onPaginationChange, onGlobalFilterChange, slots = {}, slotProps = {}, logging, }, ref) {
44
44
  var _a;
45
45
  const isServerMode = dataMode === 'server';
46
46
  const isServerPagination = paginationMode === 'server' || isServerMode;
47
47
  const isServerFiltering = filterMode === 'server' || isServerMode;
48
48
  const isServerSorting = sortingMode === 'server' || isServerMode;
49
+ const logger = (0, react_1.useMemo)(() => (0, utils_1.createLogger)('DataTable', logging), [logging]);
50
+ const fetchLogger = (0, react_1.useMemo)(() => logger.child('fetch'), [logger]);
51
+ const paginationLogger = (0, react_1.useMemo)(() => logger.child('pagination'), [logger]);
52
+ const stateLogger = (0, react_1.useMemo)(() => logger.child('state'), [logger]);
53
+ (0, react_1.useEffect)(() => {
54
+ if (logger.isLevelEnabled('info')) {
55
+ logger.info('mounted', {
56
+ dataMode,
57
+ paginationMode,
58
+ filterMode,
59
+ sortingMode,
60
+ });
61
+ }
62
+ return () => {
63
+ if (logger.isLevelEnabled('info')) {
64
+ logger.info('unmounted');
65
+ }
66
+ };
67
+ }, [logger, dataMode, paginationMode, filterMode, sortingMode]);
49
68
  const initialStateConfig = (0, react_1.useMemo)(() => {
50
69
  return Object.assign(Object.assign({}, DEFAULT_INITIAL_STATE), initialState);
51
70
  }, [initialState]);
@@ -124,16 +143,41 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
124
143
  minWidth: '100%',
125
144
  }), [tableWidth]);
126
145
  const fetchData = (0, react_1.useCallback)((...args_1) => tslib_1.__awaiter(this, [...args_1], void 0, function* (overrides = {}) {
127
- if (!onFetchData)
146
+ var _a, _b;
147
+ console.info('fetchData', (0, lodash_1.cloneDeep)(overrides), (0, lodash_1.cloneDeep)(columnFilter), (0, lodash_1.cloneDeep)(sorting), (0, lodash_1.cloneDeep)(pagination));
148
+ if (!onFetchData) {
149
+ if (fetchLogger.isLevelEnabled('debug')) {
150
+ fetchLogger.debug('onFetchData not provided, skipping fetch', { overrides });
151
+ }
128
152
  return;
153
+ }
129
154
  const filters = Object.assign({ globalFilter,
130
155
  pagination,
131
156
  columnFilter,
132
157
  sorting }, overrides);
133
- const result = yield debouncedFetch(filters);
134
- if ((result === null || result === void 0 ? void 0 : result.data) && (result === null || result === void 0 ? void 0 : result.total) !== undefined) {
135
- setServerData(result.data);
136
- setServerTotal(result.total);
158
+ if (fetchLogger.isLevelEnabled('debug')) {
159
+ fetchLogger.debug('Requesting data', { filters });
160
+ }
161
+ try {
162
+ const result = yield debouncedFetch(filters);
163
+ if (fetchLogger.isLevelEnabled('debug')) {
164
+ fetchLogger.debug('Fetch resolved', {
165
+ rows: (_b = (_a = result === null || result === void 0 ? void 0 : result.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0,
166
+ total: result === null || result === void 0 ? void 0 : result.total,
167
+ });
168
+ }
169
+ if ((result === null || result === void 0 ? void 0 : result.data) && (result === null || result === void 0 ? void 0 : result.total) !== undefined) {
170
+ setServerData(result.data);
171
+ setServerTotal(result.total);
172
+ }
173
+ else if (fetchLogger.isLevelEnabled('warn')) {
174
+ fetchLogger.warn('Fetch handler returned unexpected shape', result);
175
+ }
176
+ return result;
177
+ }
178
+ catch (error) {
179
+ fetchLogger.error('Fetch failed', error);
180
+ throw error;
137
181
  }
138
182
  }), [
139
183
  onFetchData,
@@ -142,6 +186,7 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
142
186
  columnFilter,
143
187
  sorting,
144
188
  debouncedFetch,
189
+ fetchLogger,
145
190
  ]);
146
191
  const handleSelectionStateChange = (0, react_1.useCallback)((updaterOrValue) => {
147
192
  setSelectionState((prevState) => {
@@ -162,15 +207,22 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
162
207
  }
163
208
  }, [onColumnFiltersChange]);
164
209
  const tableStateChange = (0, react_1.useCallback)((overrides = {}) => {
165
- if (onDataStateChange) {
166
- const currentState = Object.assign({ globalFilter,
167
- columnFilter,
168
- sorting,
169
- pagination,
170
- columnOrder,
171
- columnPinning }, overrides);
172
- onDataStateChange(currentState);
210
+ if (!onDataStateChange) {
211
+ if (stateLogger.isLevelEnabled('debug')) {
212
+ stateLogger.debug('No onDataStateChange handler registered; skipping state update notification', { overrides });
213
+ }
214
+ return;
173
215
  }
216
+ const currentState = Object.assign({ globalFilter,
217
+ columnFilter,
218
+ sorting,
219
+ pagination,
220
+ columnOrder,
221
+ columnPinning }, overrides);
222
+ if (stateLogger.isLevelEnabled('debug')) {
223
+ stateLogger.debug('Emitting tableStateChange', currentState);
224
+ }
225
+ onDataStateChange(currentState);
174
226
  }, [
175
227
  onDataStateChange,
176
228
  globalFilter,
@@ -179,6 +231,7 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
179
231
  pagination,
180
232
  columnOrder,
181
233
  columnPinning,
234
+ stateLogger,
182
235
  ]);
183
236
  const handleSortingChange = (0, react_1.useCallback)((updaterOrValue) => {
184
237
  let newSorting = typeof updaterOrValue === 'function'
@@ -187,8 +240,18 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
187
240
  newSorting = newSorting.filter((sort) => sort.id);
188
241
  setSorting(newSorting);
189
242
  onSortingChange === null || onSortingChange === void 0 ? void 0 : onSortingChange(newSorting);
243
+ if (stateLogger.isLevelEnabled('debug')) {
244
+ stateLogger.debug('Sorting change applied', {
245
+ sorting: newSorting,
246
+ serverMode: isServerMode,
247
+ serverSorting: isServerSorting,
248
+ });
249
+ }
190
250
  if (isServerMode || isServerSorting) {
191
251
  const pagination = resetPageToFirst();
252
+ if (stateLogger.isLevelEnabled('debug')) {
253
+ stateLogger.debug('Sorting change triggered server fetch', { pagination, sorting: newSorting });
254
+ }
192
255
  tableStateChange({ sorting: newSorting, pagination });
193
256
  fetchData({
194
257
  sorting: newSorting,
@@ -198,6 +261,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
198
261
  else if (onDataStateChange) {
199
262
  const pagination = resetPageToFirst();
200
263
  setTimeout(() => {
264
+ if (stateLogger.isLevelEnabled('debug')) {
265
+ stateLogger.debug('Sorting change notified client state change', { pagination, sorting: newSorting });
266
+ }
201
267
  tableStateChange({ sorting: newSorting, pagination });
202
268
  }, 0);
203
269
  }
@@ -209,6 +275,7 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
209
275
  isServerSorting,
210
276
  onDataStateChange,
211
277
  tableStateChange,
278
+ stateLogger,
212
279
  ]);
213
280
  const handleColumnOrderChange = (0, react_1.useCallback)((updatedColumnOrder) => {
214
281
  const newColumnOrder = typeof updatedColumnOrder === 'function'
@@ -229,30 +296,67 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
229
296
  }
230
297
  }, [onColumnPinningChange, columnPinning]);
231
298
  const handlePaginationChange = (0, react_1.useCallback)((updater) => {
232
- setPagination(updater);
233
299
  const newPagination = typeof updater === 'function' ? updater(pagination) : updater;
300
+ if (paginationLogger.isLevelEnabled('debug')) {
301
+ paginationLogger.debug('Pagination change requested', {
302
+ previous: pagination,
303
+ next: newPagination,
304
+ serverSide: isServerMode || isServerPagination,
305
+ });
306
+ }
307
+ setPagination(newPagination);
308
+ onPaginationChange === null || onPaginationChange === void 0 ? void 0 : onPaginationChange(newPagination);
309
+ if (paginationLogger.isLevelEnabled('debug')) {
310
+ paginationLogger.debug('Pagination state updated', newPagination);
311
+ }
234
312
  if (isServerMode || isServerPagination) {
235
313
  setTimeout(() => {
314
+ if (paginationLogger.isLevelEnabled('debug')) {
315
+ paginationLogger.debug('Notifying server-side pagination change', newPagination);
316
+ }
236
317
  tableStateChange({ pagination: newPagination });
237
318
  fetchData({ pagination: newPagination });
238
319
  }, 0);
239
320
  }
240
321
  else if (onDataStateChange) {
241
322
  setTimeout(() => {
323
+ if (paginationLogger.isLevelEnabled('debug')) {
324
+ paginationLogger.debug('Notifying client-side pagination change', newPagination);
325
+ }
242
326
  tableStateChange({ pagination: newPagination });
243
327
  }, 0);
244
328
  }
245
- setPagination(newPagination);
246
- onPaginationChange === null || onPaginationChange === void 0 ? void 0 : onPaginationChange(newPagination);
247
- }, [pagination, isServerMode, isServerPagination, onDataStateChange, fetchData, tableStateChange]);
329
+ }, [
330
+ pagination,
331
+ isServerMode,
332
+ isServerPagination,
333
+ onDataStateChange,
334
+ fetchData,
335
+ tableStateChange,
336
+ paginationLogger,
337
+ onPaginationChange,
338
+ ]);
248
339
  const handleGlobalFilterChange = (0, react_1.useCallback)((updaterOrValue) => {
249
340
  const newFilter = typeof updaterOrValue === 'function'
250
341
  ? updaterOrValue(globalFilter)
251
342
  : updaterOrValue;
252
343
  setGlobalFilter(newFilter);
344
+ if (stateLogger.isLevelEnabled('debug')) {
345
+ stateLogger.debug('Global filter change applied', {
346
+ value: newFilter,
347
+ serverMode: isServerMode,
348
+ serverFiltering: isServerFiltering,
349
+ });
350
+ }
253
351
  if (isServerMode || isServerFiltering) {
254
352
  const pagination = resetPageToFirst();
255
353
  setTimeout(() => {
354
+ if (stateLogger.isLevelEnabled('debug')) {
355
+ stateLogger.debug('Global filter change triggering server fetch', {
356
+ pagination,
357
+ value: newFilter,
358
+ });
359
+ }
256
360
  tableStateChange({ globalFilter: newFilter, pagination });
257
361
  fetchData({ globalFilter: newFilter, pagination });
258
362
  }, 0);
@@ -260,11 +364,17 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
260
364
  else if (onDataStateChange) {
261
365
  const pagination = resetPageToFirst();
262
366
  setTimeout(() => {
367
+ if (stateLogger.isLevelEnabled('debug')) {
368
+ stateLogger.debug('Global filter change notifying client listeners', {
369
+ pagination,
370
+ value: newFilter,
371
+ });
372
+ }
263
373
  tableStateChange({ globalFilter: newFilter, pagination });
264
374
  }, 0);
265
375
  }
266
376
  onGlobalFilterChange === null || onGlobalFilterChange === void 0 ? void 0 : onGlobalFilterChange(newFilter);
267
- }, [globalFilter, isServerMode, isServerFiltering, onDataStateChange, fetchData, tableStateChange]);
377
+ }, [globalFilter, isServerMode, isServerFiltering, onDataStateChange, fetchData, tableStateChange, stateLogger]);
268
378
  const onColumnFilterChangeHandler = (0, react_1.useCallback)((updater) => {
269
379
  const currentState = columnFilter;
270
380
  const newState = typeof updater === 'function'
@@ -312,6 +422,12 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
312
422
  enabled: enableVirtualization && !enablePagination && rows.length > 0,
313
423
  });
314
424
  const resetPageToFirst = () => {
425
+ if (paginationLogger.isLevelEnabled('info')) {
426
+ paginationLogger.info('Resetting to first page due to state change', {
427
+ previousPageIndex: pagination.pageIndex,
428
+ pageSize: pagination.pageSize,
429
+ });
430
+ }
315
431
  const newPagination = { pageIndex: 0, pageSize: pagination.pageSize };
316
432
  setPagination(newPagination);
317
433
  onPaginationChange === null || onPaginationChange === void 0 ? void 0 : onPaginationChange(newPagination);
@@ -355,29 +471,6 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
355
471
  setColumnOrder(initialOrder);
356
472
  }
357
473
  }, [enableColumnDragging, enhancedColumns, columnOrder.length]);
358
- (0, use_data_table_api_1.useDataTableApi)({
359
- table,
360
- idKey,
361
- enhancedColumns,
362
- enablePagination,
363
- enableColumnPinning,
364
- initialStateConfig: Object.assign(Object.assign({}, DEFAULT_INITIAL_STATE), initialState),
365
- selectMode,
366
- onSelectionChange: handleSelectionStateChange,
367
- handleColumnFilterStateChange,
368
- onDataStateChange,
369
- onFetchData: fetchData,
370
- exportFilename,
371
- onExportProgress,
372
- onExportComplete,
373
- onExportError,
374
- onServerExport,
375
- exportController,
376
- setExportController,
377
- isExporting,
378
- onDataChange: setServerData,
379
- dataMode,
380
- }, internalApiRef);
381
474
  (0, react_1.useImperativeHandle)(ref, () => internalApiRef.current, []);
382
475
  (0, react_1.useImperativeHandle)(ref, () => ({
383
476
  table: {
@@ -505,6 +598,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
505
598
  pendingFilters: columnFilter.pendingFilters || [],
506
599
  pendingLogic: columnFilter.pendingLogic || 'AND',
507
600
  });
601
+ if (stateLogger.isLevelEnabled('debug')) {
602
+ stateLogger.debug(`Adding column filter ${columnId} ${operator} ${value}`, newFilters);
603
+ }
508
604
  },
509
605
  removeColumnFilter: (filterId) => {
510
606
  const columnFilter = table.getState().columnFilter;
@@ -516,6 +612,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
516
612
  pendingFilters: columnFilter.pendingFilters || [],
517
613
  pendingLogic: columnFilter.pendingLogic || 'AND',
518
614
  });
615
+ if (stateLogger.isLevelEnabled('debug')) {
616
+ stateLogger.debug(`Removing column filter ${filterId}`, newFilters);
617
+ }
519
618
  },
520
619
  clearAllFilters: () => {
521
620
  table.setGlobalFilter('');
@@ -534,11 +633,17 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
534
633
  pendingFilters: [],
535
634
  pendingLogic: 'AND',
536
635
  });
636
+ if (stateLogger.isLevelEnabled('debug')) {
637
+ stateLogger.debug('Resetting filters');
638
+ }
537
639
  },
538
640
  },
539
641
  sorting: {
540
642
  setSorting: (sortingState) => {
541
643
  table.setSorting(sortingState);
644
+ if (stateLogger.isLevelEnabled('debug')) {
645
+ stateLogger.debug(`Setting sorting`, sortingState);
646
+ }
542
647
  },
543
648
  sortColumn: (columnId, direction) => {
544
649
  const column = table.getColumn(columnId);
@@ -561,23 +666,41 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
561
666
  pagination: {
562
667
  goToPage: (pageIndex) => {
563
668
  table.setPageIndex(pageIndex);
669
+ if (paginationLogger.isLevelEnabled('debug')) {
670
+ paginationLogger.debug(`Going to page ${pageIndex}`);
671
+ }
564
672
  },
565
673
  nextPage: () => {
566
674
  table.nextPage();
675
+ if (paginationLogger.isLevelEnabled('debug')) {
676
+ paginationLogger.debug('Next page');
677
+ }
567
678
  },
568
679
  previousPage: () => {
569
680
  table.previousPage();
681
+ if (paginationLogger.isLevelEnabled('debug')) {
682
+ paginationLogger.debug('Previous page');
683
+ }
570
684
  },
571
685
  setPageSize: (pageSize) => {
572
686
  table.setPageSize(pageSize);
687
+ if (paginationLogger.isLevelEnabled('debug')) {
688
+ paginationLogger.debug(`Setting page size to ${pageSize}`);
689
+ }
573
690
  },
574
691
  goToFirstPage: () => {
575
692
  table.setPageIndex(0);
693
+ if (paginationLogger.isLevelEnabled('debug')) {
694
+ paginationLogger.debug('Going to first page');
695
+ }
576
696
  },
577
697
  goToLastPage: () => {
578
698
  const pageCount = table.getPageCount();
579
699
  if (pageCount > 0) {
580
700
  table.setPageIndex(pageCount - 1);
701
+ if (paginationLogger.isLevelEnabled('debug')) {
702
+ paginationLogger.debug(`Going to last page ${pageCount - 1}`);
703
+ }
581
704
  }
582
705
  },
583
706
  },
@@ -597,19 +720,28 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
597
720
  refresh: () => {
598
721
  var _a, _b;
599
722
  const filters = table.getState();
723
+ console.info('filters', (0, lodash_1.cloneDeep)(filters));
600
724
  const pagination = {
601
725
  pageIndex: 0,
602
726
  pageSize: ((_a = filters.pagination) === null || _a === void 0 ? void 0 : _a.pageSize) || ((_b = initialStateConfig.pagination) === null || _b === void 0 ? void 0 : _b.pageSize) || 10,
603
727
  };
728
+ console.info('pagination', (0, lodash_1.cloneDeep)(pagination));
604
729
  const allState = table.getState();
730
+ console.info('allState', (0, lodash_1.cloneDeep)(allState));
605
731
  setPagination(pagination);
606
732
  onDataStateChange === null || onDataStateChange === void 0 ? void 0 : onDataStateChange(allState);
607
733
  fetchData === null || fetchData === void 0 ? void 0 : fetchData({ pagination });
734
+ if (fetchLogger.isLevelEnabled('debug')) {
735
+ fetchLogger.debug('Refreshing data', { pagination, allState });
736
+ }
608
737
  },
609
738
  reload: () => {
610
739
  const allState = table.getState();
611
740
  onDataStateChange === null || onDataStateChange === void 0 ? void 0 : onDataStateChange(allState);
612
741
  onFetchData === null || onFetchData === void 0 ? void 0 : onFetchData({});
742
+ if (fetchLogger.isLevelEnabled('debug')) {
743
+ fetchLogger.debug('Reloading data', allState);
744
+ }
613
745
  },
614
746
  getAllData: () => {
615
747
  var _a;
@@ -628,6 +760,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
628
760
  const newData = (_a = table.getRowModel().rows) === null || _a === void 0 ? void 0 : _a.map(row => String(row.original[idKey]) === rowId
629
761
  ? Object.assign(Object.assign({}, row.original), updates) : row.original);
630
762
  setServerData === null || setServerData === void 0 ? void 0 : setServerData(newData || []);
763
+ if (fetchLogger.isLevelEnabled('debug')) {
764
+ fetchLogger.debug(`Updating row ${rowId}`, updates);
765
+ }
631
766
  },
632
767
  updateRowByIndex: (index, updates) => {
633
768
  var _a;
@@ -635,6 +770,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
635
770
  if (newData === null || newData === void 0 ? void 0 : newData[index]) {
636
771
  newData[index] = Object.assign(Object.assign({}, newData[index]), updates);
637
772
  setServerData(newData);
773
+ if (fetchLogger.isLevelEnabled('debug')) {
774
+ fetchLogger.debug(`Updating row by index ${index}`, updates);
775
+ }
638
776
  }
639
777
  },
640
778
  insertRow: (newRow, index) => {
@@ -647,17 +785,26 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
647
785
  newData.push(newRow);
648
786
  }
649
787
  setServerData(newData || []);
788
+ if (fetchLogger.isLevelEnabled('debug')) {
789
+ fetchLogger.debug(`Inserting row`, newRow);
790
+ }
650
791
  },
651
792
  deleteRow: (rowId) => {
652
793
  var _a;
653
794
  const newData = (_a = (table.getRowModel().rows || [])) === null || _a === void 0 ? void 0 : _a.filter(row => String(row.original[idKey]) !== rowId);
654
795
  setServerData === null || setServerData === void 0 ? void 0 : setServerData((newData === null || newData === void 0 ? void 0 : newData.map(row => row.original)) || []);
796
+ if (fetchLogger.isLevelEnabled('debug')) {
797
+ fetchLogger.debug(`Deleting row ${rowId}`);
798
+ }
655
799
  },
656
800
  deleteRowByIndex: (index) => {
657
801
  var _a;
658
802
  const newData = (_a = (table.getRowModel().rows || [])) === null || _a === void 0 ? void 0 : _a.map(row => row.original);
659
803
  newData.splice(index, 1);
660
804
  setServerData(newData);
805
+ if (fetchLogger.isLevelEnabled('debug')) {
806
+ fetchLogger.debug(`Deleting row by index ${index}`);
807
+ }
661
808
  },
662
809
  deleteSelectedRows: () => {
663
810
  var _a;
@@ -666,6 +813,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
666
813
  const newData = (_a = (table.getRowModel().rows || [])) === null || _a === void 0 ? void 0 : _a.filter(row => !selectedRowIds.includes(String(row.original[idKey])));
667
814
  setServerData((newData === null || newData === void 0 ? void 0 : newData.map(row => row.original)) || []);
668
815
  table.resetRowSelection();
816
+ if (fetchLogger.isLevelEnabled('debug')) {
817
+ fetchLogger.debug('Deleting selected rows');
818
+ }
669
819
  },
670
820
  replaceAllData: (newData) => {
671
821
  setServerData === null || setServerData === void 0 ? void 0 : setServerData(newData);
@@ -822,6 +972,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
822
972
  sorting: table.getState().sorting,
823
973
  pagination: table.getState().pagination,
824
974
  };
975
+ if (stateLogger.isLevelEnabled('debug')) {
976
+ stateLogger.debug('Server export CSV', { currentFilters });
977
+ }
825
978
  yield (0, utils_1.exportServerData)(table, {
826
979
  format: 'csv',
827
980
  filename,
@@ -841,6 +994,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
841
994
  onComplete: onExportComplete,
842
995
  onError: onExportError,
843
996
  });
997
+ if (stateLogger.isLevelEnabled('debug')) {
998
+ stateLogger.debug('Client export CSV', filename);
999
+ }
844
1000
  }
845
1001
  }
846
1002
  catch (error) {
@@ -866,6 +1022,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
866
1022
  sorting: table.getState().sorting,
867
1023
  pagination: table.getState().pagination,
868
1024
  };
1025
+ if (stateLogger.isLevelEnabled('debug')) {
1026
+ stateLogger.debug('Server export Excel', { currentFilters });
1027
+ }
869
1028
  yield (0, utils_1.exportServerData)(table, {
870
1029
  format: 'excel',
871
1030
  filename,
@@ -885,6 +1044,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
885
1044
  onComplete: onExportComplete,
886
1045
  onError: onExportError,
887
1046
  });
1047
+ if (stateLogger.isLevelEnabled('debug')) {
1048
+ stateLogger.debug('Client export Excel', filename);
1049
+ }
888
1050
  }
889
1051
  }
890
1052
  catch (error) {
@@ -892,6 +1054,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
892
1054
  message: error.message || 'Export failed',
893
1055
  code: 'EXPORT_ERROR',
894
1056
  });
1057
+ if (stateLogger.isLevelEnabled('debug')) {
1058
+ stateLogger.debug('Server export Excel failed', error);
1059
+ }
895
1060
  }
896
1061
  finally {
897
1062
  setExportController === null || setExportController === void 0 ? void 0 : setExportController(null);
@@ -905,6 +1070,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
905
1070
  message: 'No server export function provided',
906
1071
  code: 'NO_SERVER_EXPORT',
907
1072
  });
1073
+ if (stateLogger.isLevelEnabled('debug')) {
1074
+ stateLogger.debug('Server export data failed', 'No server export function provided');
1075
+ }
908
1076
  return;
909
1077
  }
910
1078
  try {
@@ -916,6 +1084,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
916
1084
  sorting: table.getState().sorting,
917
1085
  pagination: table.getState().pagination,
918
1086
  };
1087
+ if (stateLogger.isLevelEnabled('debug')) {
1088
+ stateLogger.debug('Server export data', { currentFilters });
1089
+ }
919
1090
  yield (0, utils_1.exportServerData)(table, {
920
1091
  format,
921
1092
  filename,
@@ -932,6 +1103,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
932
1103
  message: error.message || 'Export failed',
933
1104
  code: 'EXPORT_ERROR',
934
1105
  });
1106
+ if (stateLogger.isLevelEnabled('debug')) {
1107
+ stateLogger.debug('Server export data failed', error);
1108
+ }
935
1109
  }
936
1110
  finally {
937
1111
  setExportController === null || setExportController === void 0 ? void 0 : setExportController(null);
@@ -941,6 +1115,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
941
1115
  cancelExport: () => {
942
1116
  exportController === null || exportController === void 0 ? void 0 : exportController.abort();
943
1117
  setExportController === null || setExportController === void 0 ? void 0 : setExportController(null);
1118
+ if (stateLogger.isLevelEnabled('debug')) {
1119
+ stateLogger.debug('Export cancelled');
1120
+ }
944
1121
  },
945
1122
  },
946
1123
  }), [
@@ -1,17 +1,17 @@
1
- import { Row, SortingState, ColumnResizeMode, ColumnPinningState, RowData, PaginationState } from '@tanstack/react-table';
1
+ import { Row, SortingState, ColumnResizeMode, ColumnPinningState, RowData, PaginationState, ColumnDef } from '@tanstack/react-table';
2
2
  import { ReactNode } from 'react';
3
3
  import type { ColumnFilterState, TableFilters, TableState } from '../../types';
4
- import { DataTableColumn } from '../../types';
5
4
  import { DataTableSlots, PartialSlotProps } from '../../types/slots.types';
6
5
  import { DataTableSize } from '../../utils/table-helpers';
7
6
  import { SelectionState } from '../../features';
7
+ import { DataTableLoggingOptions } from '../../utils/logger';
8
8
  export type SelectMode = 'page' | 'all';
9
9
  declare module '@tanstack/table-core' {
10
10
  interface ColumnMeta<TData extends RowData, TValue> {
11
11
  }
12
12
  }
13
13
  export interface DataTableProps<T> {
14
- columns: DataTableColumn<T>[];
14
+ columns: ColumnDef<T, any>[];
15
15
  data?: T[];
16
16
  totalRow?: number;
17
17
  idKey?: keyof T;
@@ -95,4 +95,5 @@ export interface DataTableProps<T> {
95
95
  onColumnFilterChange?: (columnFilter: ColumnFilterState) => void;
96
96
  slots?: Partial<DataTableSlots<T>>;
97
97
  slotProps?: PartialSlotProps<T>;
98
+ logging?: boolean | DataTableLoggingOptions;
98
99
  }
@@ -6,6 +6,7 @@ const react_1 = require("react");
6
6
  const material_1 = require("@mui/material");
7
7
  const icons_material_1 = require("@mui/icons-material");
8
8
  const components_1 = require("../components");
9
+ const types_1 = require("../types");
9
10
  const generateEmployeeData = () => {
10
11
  const departments = [
11
12
  { id: 1, name: 'Engineering', color: '#2196F3' },
@@ -218,6 +219,10 @@ function AdvancedFeaturesExample() {
218
219
  pageIndex: 0,
219
220
  pageSize: 10,
220
221
  },
222
+ columnPinning: {
223
+ left: [types_1.DEFAULT_SELECTION_COLUMN_NAME],
224
+ right: ['actions'],
225
+ },
221
226
  columnOrder: ['name', 'department.name', 'salary', 'performance.rating', 'skills'],
222
227
  }, tableContainerProps: {
223
228
  sx: {
@@ -3,6 +3,7 @@ import { Ref } from 'react';
3
3
  import { ColumnFilterState, TableFilters, TableState } from '../types';
4
4
  import { DataTableApi } from '../types/data-table-api';
5
5
  import { SelectionState } from '../features';
6
+ import { DataTableLoggingOptions } from '../utils/logger';
6
7
  interface UseDataTableApiProps<T> {
7
8
  table: Table<T>;
8
9
  idKey: keyof T;
@@ -39,6 +40,7 @@ interface UseDataTableApiProps<T> {
39
40
  setExportController?: (controller: AbortController | null) => void;
40
41
  isExporting?: boolean;
41
42
  dataMode?: 'client' | 'server';
43
+ logging?: boolean | DataTableLoggingOptions;
42
44
  }
43
45
  export declare function useDataTableApi<T extends Record<string, any>>(props: UseDataTableApiProps<T>, ref: Ref<DataTableApi<T>>): void;
44
46
  export {};
@@ -4,8 +4,13 @@ exports.useDataTableApi = useDataTableApi;
4
4
  const tslib_1 = require("tslib");
5
5
  const react_1 = require("react");
6
6
  const export_utils_1 = require("../utils/export-utils");
7
+ const logger_1 = require("../utils/logger");
7
8
  function useDataTableApi(props, ref) {
8
- const { table, idKey, enhancedColumns, enablePagination, enableColumnPinning, initialStateConfig, selectMode = 'page', onSelectionChange, handleColumnFilterStateChange, onDataStateChange, onFetchData, onDataChange, exportFilename = 'export', onExportProgress, onExportComplete, onExportError, onServerExport, exportController, setExportController, isExporting, dataMode = 'client', } = props;
9
+ const { table, idKey, enhancedColumns, enablePagination, enableColumnPinning, initialStateConfig, selectMode = 'page', onSelectionChange, handleColumnFilterStateChange, onDataStateChange, onFetchData, onDataChange, exportFilename = 'export', onExportProgress, onExportComplete, onExportError, onServerExport, exportController, setExportController, isExporting, dataMode = 'client', logging, } = props;
10
+ const logger = (0, react_1.useMemo)(() => (0, logger_1.createLogger)('DataTableApi', logging), [logging]);
11
+ const fetchLogger = (0, react_1.useMemo)(() => logger.child('fetch'), [logger]);
12
+ const paginationLogger = (0, react_1.useMemo)(() => logger.child('pagination'), [logger]);
13
+ const stateLogger = (0, react_1.useMemo)(() => logger.child('state'), [logger]);
9
14
  const getTableFilters = (0, react_1.useCallback)((withAllState = false) => {
10
15
  const state = table.getState();
11
16
  return Object.assign({ sorting: state.sorting, globalFilter: state.globalFilter, columnFilter: state.columnFilter, pagination: state.pagination }, (withAllState ? {
@@ -55,6 +60,9 @@ function useDataTableApi(props, ref) {
55
60
  newOrder.splice(currentIndex, 1);
56
61
  newOrder.splice(toIndex, 0, columnId);
57
62
  table.setColumnOrder(newOrder);
63
+ if (stateLogger.isLevelEnabled('debug')) {
64
+ stateLogger.debug('Column order updated', `${columnId} from ${currentIndex} to ${toIndex}`);
65
+ }
58
66
  },
59
67
  resetColumnOrder: () => {
60
68
  const initialOrder = enhancedColumns.map((col, index) => {
@@ -67,6 +75,9 @@ function useDataTableApi(props, ref) {
67
75
  return `column_${index}`;
68
76
  });
69
77
  table.setColumnOrder(initialOrder);
78
+ if (stateLogger.isLevelEnabled('debug')) {
79
+ stateLogger.debug('Column order reset', initialOrder);
80
+ }
70
81
  },
71
82
  },
72
83
  columnPinning: {
@@ -76,6 +87,9 @@ function useDataTableApi(props, ref) {
76
87
  newPinning.right = (newPinning.right || []).filter(id => id !== columnId);
77
88
  newPinning.left = [...(newPinning.left || []).filter(id => id !== columnId), columnId];
78
89
  table.setColumnPinning(newPinning);
90
+ if (stateLogger.isLevelEnabled('debug')) {
91
+ stateLogger.debug('Column pinned left', `${columnId}`);
92
+ }
79
93
  },
80
94
  pinColumnRight: (columnId) => {
81
95
  const currentPinning = table.getState().columnPinning;
@@ -83,6 +97,9 @@ function useDataTableApi(props, ref) {
83
97
  newPinning.left = (newPinning.left || []).filter(id => id !== columnId);
84
98
  newPinning.right = [...(newPinning.right || []).filter(id => id !== columnId), columnId];
85
99
  table.setColumnPinning(newPinning);
100
+ if (stateLogger.isLevelEnabled('debug')) {
101
+ stateLogger.debug('Column pinned right', `${columnId}`);
102
+ }
86
103
  },
87
104
  unpinColumn: (columnId) => {
88
105
  const currentPinning = table.getState().columnPinning;
@@ -118,12 +135,21 @@ function useDataTableApi(props, ref) {
118
135
  filtering: {
119
136
  setGlobalFilter: (filter) => {
120
137
  table.setGlobalFilter(filter);
138
+ if (stateLogger.isLevelEnabled('debug')) {
139
+ stateLogger.debug('Global filter set', `${filter}`);
140
+ }
121
141
  },
122
142
  clearGlobalFilter: () => {
123
143
  table.setGlobalFilter('');
144
+ if (stateLogger.isLevelEnabled('debug')) {
145
+ stateLogger.debug('Global filter cleared');
146
+ }
124
147
  },
125
148
  setColumnFilters: (filters) => {
126
149
  handleColumnFilterStateChange(filters);
150
+ if (stateLogger.isLevelEnabled('debug')) {
151
+ stateLogger.debug('Column filters set', `${filters}`);
152
+ }
127
153
  },
128
154
  addColumnFilter: (columnId, operator, value) => {
129
155
  const newFilter = {
@@ -141,6 +167,9 @@ function useDataTableApi(props, ref) {
141
167
  pendingFilters: columnFilter.pendingFilters || [],
142
168
  pendingLogic: columnFilter.pendingLogic || 'AND',
143
169
  });
170
+ if (stateLogger.isLevelEnabled('debug')) {
171
+ stateLogger.debug(`Column filter added ${columnId} ${operator} ${value}`, newFilters);
172
+ }
144
173
  },
145
174
  removeColumnFilter: (filterId) => {
146
175
  const columnFilter = table.getState().columnFilter;
@@ -152,6 +181,9 @@ function useDataTableApi(props, ref) {
152
181
  pendingFilters: columnFilter.pendingFilters || [],
153
182
  pendingLogic: columnFilter.pendingLogic || 'AND',
154
183
  });
184
+ if (stateLogger.isLevelEnabled('debug')) {
185
+ stateLogger.debug(`Column filter removed ${filterId}`, newFilters);
186
+ }
155
187
  },
156
188
  clearAllFilters: () => {
157
189
  table.setGlobalFilter('');
@@ -161,6 +193,9 @@ function useDataTableApi(props, ref) {
161
193
  pendingFilters: [],
162
194
  pendingLogic: 'AND',
163
195
  });
196
+ if (stateLogger.isLevelEnabled('debug')) {
197
+ stateLogger.debug('Filters reset');
198
+ }
164
199
  },
165
200
  resetFilters: () => {
166
201
  table.resetGlobalFilter();
@@ -175,6 +210,9 @@ function useDataTableApi(props, ref) {
175
210
  sorting: {
176
211
  setSorting: (sortingState) => {
177
212
  table.setSorting(sortingState);
213
+ if (stateLogger.isLevelEnabled('debug')) {
214
+ stateLogger.debug('Sorting set', `${sortingState}`);
215
+ }
178
216
  },
179
217
  sortColumn: (columnId, direction) => {
180
218
  const column = table.getColumn(columnId);
@@ -197,24 +235,42 @@ function useDataTableApi(props, ref) {
197
235
  pagination: {
198
236
  goToPage: (pageIndex) => {
199
237
  table.setPageIndex(pageIndex);
238
+ if (paginationLogger.isLevelEnabled('debug')) {
239
+ paginationLogger.debug('Page index set', `${pageIndex}`);
240
+ }
200
241
  },
201
242
  nextPage: () => {
202
243
  table.nextPage();
244
+ if (paginationLogger.isLevelEnabled('debug')) {
245
+ paginationLogger.debug('Next page');
246
+ }
203
247
  },
204
248
  previousPage: () => {
205
249
  table.previousPage();
250
+ if (paginationLogger.isLevelEnabled('debug')) {
251
+ paginationLogger.debug('Previous page');
252
+ }
206
253
  },
207
254
  setPageSize: (pageSize) => {
208
255
  table.setPageSize(pageSize);
256
+ if (paginationLogger.isLevelEnabled('debug')) {
257
+ paginationLogger.debug('Page size set', `${pageSize}`);
258
+ }
209
259
  },
210
260
  goToFirstPage: () => {
211
261
  table.setPageIndex(0);
262
+ if (paginationLogger.isLevelEnabled('debug')) {
263
+ paginationLogger.debug('Page index set to 0');
264
+ }
212
265
  },
213
266
  goToLastPage: () => {
214
267
  const pageCount = table.getPageCount();
215
268
  if (pageCount > 0) {
216
269
  table.setPageIndex(pageCount - 1);
217
270
  }
271
+ if (paginationLogger.isLevelEnabled('debug')) {
272
+ paginationLogger.debug('Page index set to last page', `${pageCount - 1}`);
273
+ }
218
274
  },
219
275
  },
220
276
  selection: {
@@ -240,12 +296,18 @@ function useDataTableApi(props, ref) {
240
296
  const allState = getTableFilters(true);
241
297
  onDataStateChange === null || onDataStateChange === void 0 ? void 0 : onDataStateChange(allState);
242
298
  onFetchData === null || onFetchData === void 0 ? void 0 : onFetchData(filters);
299
+ if (fetchLogger.isLevelEnabled('debug')) {
300
+ fetchLogger.debug('Data refreshed', filters);
301
+ }
243
302
  },
244
303
  reload: () => {
245
304
  const filters = getTableFilters();
246
305
  const allState = getTableFilters(true);
247
306
  onDataStateChange === null || onDataStateChange === void 0 ? void 0 : onDataStateChange(allState);
248
307
  onFetchData === null || onFetchData === void 0 ? void 0 : onFetchData(filters);
308
+ if (fetchLogger.isLevelEnabled('debug')) {
309
+ fetchLogger.debug('Data reloaded', filters);
310
+ }
249
311
  },
250
312
  getAllData: () => {
251
313
  var _a;
@@ -264,6 +326,9 @@ function useDataTableApi(props, ref) {
264
326
  const newData = (_a = table.getRowModel().rows) === null || _a === void 0 ? void 0 : _a.map(row => String(row.original[idKey]) === rowId
265
327
  ? Object.assign(Object.assign({}, row.original), updates) : row.original);
266
328
  onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newData || []);
329
+ if (fetchLogger.isLevelEnabled('debug')) {
330
+ fetchLogger.debug('Row updated', `${rowId}`, updates);
331
+ }
267
332
  },
268
333
  updateRowByIndex: (index, updates) => {
269
334
  var _a;
@@ -283,11 +348,17 @@ function useDataTableApi(props, ref) {
283
348
  newData.push(newRow);
284
349
  }
285
350
  onDataChange(newData || []);
351
+ if (stateLogger.isLevelEnabled('debug')) {
352
+ stateLogger.debug('Row inserted', `${newRow}`, index);
353
+ }
286
354
  },
287
355
  deleteRow: (rowId) => {
288
356
  var _a;
289
357
  const newData = (_a = (table.getRowModel().rows || [])) === null || _a === void 0 ? void 0 : _a.filter(row => String(row.original[idKey]) !== rowId);
290
358
  onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange((newData === null || newData === void 0 ? void 0 : newData.map(row => row.original)) || []);
359
+ if (stateLogger.isLevelEnabled('debug')) {
360
+ stateLogger.debug('Row deleted', `${rowId}`);
361
+ }
291
362
  },
292
363
  deleteRowByIndex: (index) => {
293
364
  var _a;
@@ -302,6 +373,9 @@ function useDataTableApi(props, ref) {
302
373
  const newData = (_a = (table.getRowModel().rows || [])) === null || _a === void 0 ? void 0 : _a.filter(row => !selectedRowIds.includes(String(row.original[idKey])));
303
374
  onDataChange((newData === null || newData === void 0 ? void 0 : newData.map(row => row.original)) || []);
304
375
  table.resetRowSelection();
376
+ if (stateLogger.isLevelEnabled('debug')) {
377
+ stateLogger.debug('Selected rows deleted', selectedRowIds);
378
+ }
305
379
  },
306
380
  replaceAllData: (newData) => {
307
381
  onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newData);
@@ -315,6 +389,9 @@ function useDataTableApi(props, ref) {
315
389
  return updateData ? Object.assign(Object.assign({}, row.original), updateData) : row.original;
316
390
  });
317
391
  onDataChange(newData || []);
392
+ if (stateLogger.isLevelEnabled('debug')) {
393
+ stateLogger.debug('Multiple rows updated', updates);
394
+ }
318
395
  },
319
396
  insertMultipleRows: (newRows, startIndex) => {
320
397
  var _a;
@@ -326,12 +403,18 @@ function useDataTableApi(props, ref) {
326
403
  newData.push(...newRows);
327
404
  }
328
405
  onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newData);
406
+ if (stateLogger.isLevelEnabled('debug')) {
407
+ stateLogger.debug('Multiple rows inserted', newRows);
408
+ }
329
409
  },
330
410
  deleteMultipleRows: (rowIds) => {
331
411
  var _a, _b;
332
412
  const idsToDelete = new Set(rowIds);
333
413
  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);
334
414
  onDataChange(newData);
415
+ if (stateLogger.isLevelEnabled('debug')) {
416
+ stateLogger.debug('Multiple rows deleted', rowIds);
417
+ }
335
418
  },
336
419
  updateField: (rowId, fieldName, value) => {
337
420
  var _a;
@@ -458,6 +541,9 @@ function useDataTableApi(props, ref) {
458
541
  sorting: table.getState().sorting,
459
542
  pagination: table.getState().pagination,
460
543
  };
544
+ if (stateLogger.isLevelEnabled('debug')) {
545
+ stateLogger.debug('Server export CSV', { currentFilters });
546
+ }
461
547
  yield (0, export_utils_1.exportServerData)(table, {
462
548
  format: 'csv',
463
549
  filename,
@@ -5,3 +5,4 @@ export * from './export-utils';
5
5
  export * from './special-columns.utils';
6
6
  export * from './debounced-fetch.utils';
7
7
  export * from './slot-helpers';
8
+ export * from './logger';
@@ -8,3 +8,4 @@ tslib_1.__exportStar(require("./export-utils"), exports);
8
8
  tslib_1.__exportStar(require("./special-columns.utils"), exports);
9
9
  tslib_1.__exportStar(require("./debounced-fetch.utils"), exports);
10
10
  tslib_1.__exportStar(require("./slot-helpers"), exports);
11
+ tslib_1.__exportStar(require("./logger"), exports);
@@ -0,0 +1,34 @@
1
+ export type LogLevel = 'silent' | 'error' | 'warn' | 'info' | 'debug';
2
+ interface ConsoleLike {
3
+ debug?: (...args: unknown[]) => void;
4
+ info?: (...args: unknown[]) => void;
5
+ warn?: (...args: unknown[]) => void;
6
+ error?: (...args: unknown[]) => void;
7
+ log?: (...args: unknown[]) => void;
8
+ }
9
+ export interface DataTableLoggingOptions {
10
+ enabled?: boolean;
11
+ level?: LogLevel;
12
+ prefix?: string;
13
+ scope?: string;
14
+ includeTimestamp?: boolean;
15
+ logger?: ConsoleLike;
16
+ }
17
+ type LoggerInput = boolean | DataTableLoggingOptions;
18
+ type ResolvedLoggerConfig = Required<Omit<DataTableLoggingOptions, 'logger'>> & {
19
+ logger: ConsoleLike;
20
+ };
21
+ type LogMethodLevel = Exclude<LogLevel, 'silent'>;
22
+ export interface LoggerInstance {
23
+ debug: (...args: unknown[]) => void;
24
+ info: (...args: unknown[]) => void;
25
+ warn: (...args: unknown[]) => void;
26
+ error: (...args: unknown[]) => void;
27
+ child: (scope: string, overrides?: LoggerInput) => LoggerInstance;
28
+ isLevelEnabled: (level: LogMethodLevel) => boolean;
29
+ config: ResolvedLoggerConfig;
30
+ }
31
+ export declare const createLogger: (scope?: string, input?: LoggerInput, parentConfig?: ResolvedLoggerConfig) => LoggerInstance;
32
+ export declare const configureDataTableLogging: (options: DataTableLoggingOptions) => void;
33
+ export declare const getDataTableLoggingConfig: () => ResolvedLoggerConfig;
34
+ export {};
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getDataTableLoggingConfig = exports.configureDataTableLogging = exports.createLogger = void 0;
4
+ const LOG_LEVEL_ORDER = {
5
+ silent: 0,
6
+ error: 1,
7
+ warn: 2,
8
+ info: 3,
9
+ debug: 4,
10
+ };
11
+ const defaultConsole = typeof console !== 'undefined'
12
+ ? console
13
+ : {
14
+ log: () => undefined,
15
+ debug: () => undefined,
16
+ info: () => undefined,
17
+ warn: () => undefined,
18
+ error: () => undefined,
19
+ };
20
+ let globalConfig = {
21
+ enabled: false,
22
+ level: 'warn',
23
+ prefix: 'DataTable',
24
+ scope: '',
25
+ includeTimestamp: false,
26
+ logger: defaultConsole,
27
+ };
28
+ const isLevelEnabled = (level, config) => {
29
+ if (!config.enabled) {
30
+ return false;
31
+ }
32
+ return LOG_LEVEL_ORDER[level] <= LOG_LEVEL_ORDER[config.level];
33
+ };
34
+ const formatPrefix = (level, config) => {
35
+ const segments = [];
36
+ if (config.prefix) {
37
+ segments.push(config.prefix);
38
+ }
39
+ if (config.scope) {
40
+ segments.push(config.scope);
41
+ }
42
+ const prefix = segments.length > 0 ? `[${segments.join(':')}]` : '';
43
+ return config.includeTimestamp
44
+ ? `[${new Date().toISOString()}]${prefix ? ` ${prefix}` : ''} [${level.toUpperCase()}]`
45
+ : `${prefix ? `${prefix} ` : ''}[${level.toUpperCase()}]`;
46
+ };
47
+ const getConsoleMethod = (level, logger) => {
48
+ var _a, _b, _c;
49
+ const methodName = level === 'debug' ? 'debug' : level;
50
+ return (_c = (_b = (_a = logger[methodName]) !== null && _a !== void 0 ? _a : logger.log) !== null && _b !== void 0 ? _b : defaultConsole.log) !== null && _c !== void 0 ? _c : (() => undefined);
51
+ };
52
+ const normaliseInput = (input) => {
53
+ if (typeof input === 'boolean') {
54
+ return { enabled: input };
55
+ }
56
+ return input !== null && input !== void 0 ? input : {};
57
+ };
58
+ const resolveConfig = (scope, input, parent) => {
59
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
60
+ const overrides = normaliseInput(input);
61
+ const base = parent !== null && parent !== void 0 ? parent : globalConfig;
62
+ return {
63
+ enabled: (_a = overrides.enabled) !== null && _a !== void 0 ? _a : base.enabled,
64
+ level: (_b = overrides.level) !== null && _b !== void 0 ? _b : base.level,
65
+ prefix: (_c = overrides.prefix) !== null && _c !== void 0 ? _c : base.prefix,
66
+ scope: (_f = (_e = (_d = overrides.scope) !== null && _d !== void 0 ? _d : scope) !== null && _e !== void 0 ? _e : base.scope) !== null && _f !== void 0 ? _f : '',
67
+ includeTimestamp: (_g = overrides.includeTimestamp) !== null && _g !== void 0 ? _g : base.includeTimestamp,
68
+ logger: (_j = (_h = overrides.logger) !== null && _h !== void 0 ? _h : base.logger) !== null && _j !== void 0 ? _j : defaultConsole,
69
+ };
70
+ };
71
+ const createLoggerMethods = (config) => {
72
+ const logWithLevel = (level) => {
73
+ const consoleMethod = getConsoleMethod(level, config.logger);
74
+ return (...args) => {
75
+ if (!isLevelEnabled(level, config)) {
76
+ return;
77
+ }
78
+ const prefix = formatPrefix(level, config);
79
+ consoleMethod(prefix, ...args);
80
+ };
81
+ };
82
+ return {
83
+ debug: logWithLevel('debug'),
84
+ info: logWithLevel('info'),
85
+ warn: logWithLevel('warn'),
86
+ error: logWithLevel('error'),
87
+ };
88
+ };
89
+ const createLogger = (scope, input, parentConfig) => {
90
+ const resolvedConfig = resolveConfig(scope, input, parentConfig);
91
+ const methods = createLoggerMethods(resolvedConfig);
92
+ const child = (childScope, overrides) => {
93
+ const combinedScope = childScope
94
+ ? (resolvedConfig.scope ? `${resolvedConfig.scope}.${childScope}` : childScope)
95
+ : resolvedConfig.scope;
96
+ return (0, exports.createLogger)(combinedScope, overrides, resolvedConfig);
97
+ };
98
+ return Object.assign(Object.assign({}, methods), { child, isLevelEnabled: (level) => isLevelEnabled(level, resolvedConfig), config: resolvedConfig });
99
+ };
100
+ exports.createLogger = createLogger;
101
+ const configureDataTableLogging = (options) => {
102
+ globalConfig = resolveConfig(options.scope, options, globalConfig);
103
+ };
104
+ exports.configureDataTableLogging = configureDataTableLogging;
105
+ const getDataTableLoggingConfig = () => (Object.assign({}, globalConfig));
106
+ exports.getDataTableLoggingConfig = getDataTableLoggingConfig;