@ackplus/react-tanstack-data-table 1.0.19-beta-0.9 → 1.0.19-beta-0.10

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
@@ -573,10 +573,10 @@ If you find this package helpful and want to support its development, consider m
573
573
 
574
574
  <div align="center">
575
575
 
576
- [![PayPal](https://img.shields.io/badge/PayPal-00457C?style=for-the-badge&logo=paypal&logoColor=white)](https://www.paypal.com/paypalme/my/profile)
576
+ [![PayPal](https://img.shields.io/badge/PayPal-00457C?style=for-the-badge&logo=paypal&logoColor=white)](https://www.paypal.com/paypalme/ckhandla94)
577
577
  [![Razorpay](https://img.shields.io/badge/Razorpay-02042B?style=for-the-badge&logo=razorpay&logoColor=white)](https://razorpay.me/@ackplus)
578
578
 
579
- **[💳 PayPal](https://www.paypal.com/paypalme/my/profile)** • **[💳 Razorpay](https://razorpay.me/@ackplus)**
579
+ **[💳 PayPal](https://www.paypal.com/paypalme/ckhandla94)** • **[💳 Razorpay](https://razorpay.me/@ackplus)**
580
580
 
581
581
  </div>
582
582
 
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.19-beta-0.9",
4
+ "version": "1.0.19-beta-0.10",
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
@@ -14,6 +14,7 @@ export * from './lib/hooks';
14
14
  export * from './lib/types';
15
15
  export type { Column, ColumnDef, Row, Table, Header, Cell, SortingState, ColumnFiltersState, VisibilityState, ColumnOrderState, ColumnPinningState, PaginationState, } from '@tanstack/react-table';
16
16
  export * from './lib/features';
17
+ export { ServerSideTest } from './lib/examples/server-side-test';
17
18
  export { CustomColumnFilterExample } from './lib/examples/custom-column-filter-example';
18
19
  export { SimpleLocalExample } from './lib/examples/simple-local-example';
19
20
  export { AdvancedFeaturesExample } from './lib/examples/advanced-features-example';
package/src/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AdvancedFeaturesExample = exports.SimpleLocalExample = exports.CustomColumnFilterExample = exports.DataTableToolbar = exports.BulkActionsToolbar = exports.TableSizeControl = exports.TableExportControl = exports.ColumnResetControl = exports.ColumnPinningControl = exports.ColumnVisibilityControl = exports.DataTable = void 0;
3
+ exports.AdvancedFeaturesExample = exports.SimpleLocalExample = exports.CustomColumnFilterExample = exports.ServerSideTest = exports.DataTableToolbar = exports.BulkActionsToolbar = exports.TableSizeControl = exports.TableExportControl = exports.ColumnResetControl = exports.ColumnPinningControl = exports.ColumnVisibilityControl = exports.DataTable = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  var table_1 = require("./lib/components/table");
6
6
  Object.defineProperty(exports, "DataTable", { enumerable: true, get: function () { return table_1.DataTable; } });
@@ -23,6 +23,8 @@ tslib_1.__exportStar(require("./lib/utils/table-helpers"), exports);
23
23
  tslib_1.__exportStar(require("./lib/hooks"), exports);
24
24
  tslib_1.__exportStar(require("./lib/types"), exports);
25
25
  tslib_1.__exportStar(require("./lib/features"), exports);
26
+ var server_side_test_1 = require("./lib/examples/server-side-test");
27
+ Object.defineProperty(exports, "ServerSideTest", { enumerable: true, get: function () { return server_side_test_1.ServerSideTest; } });
26
28
  var custom_column_filter_example_1 = require("./lib/examples/custom-column-filter-example");
27
29
  Object.defineProperty(exports, "CustomColumnFilterExample", { enumerable: true, get: function () { return custom_column_filter_example_1.CustomColumnFilterExample; } });
28
30
  var simple_local_example_1 = require("./lib/examples/simple-local-example");
@@ -181,17 +181,23 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
181
181
  onDataStateChange,
182
182
  ]);
183
183
  const handleColumnOrderChange = (0, react_1.useCallback)((updatedColumnOrder) => {
184
- setColumnOrder(updatedColumnOrder);
184
+ const newColumnOrder = typeof updatedColumnOrder === 'function'
185
+ ? updatedColumnOrder(columnOrder)
186
+ : updatedColumnOrder;
187
+ setColumnOrder(newColumnOrder);
185
188
  if (onColumnDragEnd) {
186
- onColumnDragEnd(updatedColumnOrder);
189
+ onColumnDragEnd(newColumnOrder);
187
190
  }
188
- }, [onColumnDragEnd]);
191
+ }, [onColumnDragEnd, columnOrder]);
189
192
  const handleColumnPinningChange = (0, react_1.useCallback)((updatedColumnPinning) => {
190
- setColumnPinning(updatedColumnPinning);
193
+ const newColumnPinning = typeof updatedColumnPinning === 'function'
194
+ ? updatedColumnPinning(columnPinning)
195
+ : updatedColumnPinning;
196
+ setColumnPinning(newColumnPinning);
191
197
  if (onColumnPinningChange) {
192
- onColumnPinningChange(updatedColumnPinning);
198
+ onColumnPinningChange(newColumnPinning);
193
199
  }
194
- }, [onColumnPinningChange]);
200
+ }, [onColumnPinningChange, columnPinning]);
195
201
  const handlePaginationChange = (0, react_1.useCallback)((updater) => {
196
202
  setPagination(updater);
197
203
  const newPagination = typeof updater === 'function' ? updater(pagination) : updater;
@@ -472,7 +478,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
472
478
  const BodySlot = (0, slot_helpers_1.getSlotComponent)(slots, 'body', material_1.TableBody);
473
479
  const FooterSlot = (0, slot_helpers_1.getSlotComponent)(slots, 'footer', material_1.Box);
474
480
  const PaginationSlot = (0, slot_helpers_1.getSlotComponent)(slots, 'pagination', pagination_1.DataTablePagination);
475
- return ((0, jsx_runtime_1.jsx)(data_table_context_1.DataTableProvider, { table: table, children: (0, jsx_runtime_1.jsxs)(RootSlot, Object.assign({}, slotProps === null || slotProps === void 0 ? void 0 : slotProps.root, { children: [(enableGlobalFilter || extraFilter) ? ((0, jsx_runtime_1.jsx)(ToolbarSlot, Object.assign({ extraFilter: extraFilter, enableGlobalFilter: enableGlobalFilter, enableColumnVisibility: enableColumnVisibility, enableColumnFilter: enableColumnFilter, enableExport: enableExport, enableReset: enableReset, enableTableSizeControl: enableTableSizeControl, enableColumnPinning: enableColumnPinning }, slotProps === null || slotProps === void 0 ? void 0 : slotProps.toolbar))) : null, enableBulkActions && enableRowSelection && isSomeRowsSelected ? ((0, jsx_runtime_1.jsx)(BulkActionsSlot, Object.assign({ selectionState: selectionState, selectedRowCount: selectedRowCount, bulkActions: bulkActions, sx: {
481
+ return ((0, jsx_runtime_1.jsx)(data_table_context_1.DataTableProvider, { table: table, apiRef: internalApiRef, dataMode: dataMode, tableSize: tableSize, onTableSizeChange: (size) => {
482
+ setTableSize(size);
483
+ }, customColumnsFilter: customColumnsFilter, onChangeCustomColumnsFilter: 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)(RootSlot, Object.assign({}, slotProps === null || slotProps === void 0 ? void 0 : slotProps.root, { children: [(enableGlobalFilter || extraFilter) ? ((0, jsx_runtime_1.jsx)(ToolbarSlot, Object.assign({ extraFilter: extraFilter, enableGlobalFilter: enableGlobalFilter, enableColumnVisibility: enableColumnVisibility, enableColumnFilter: enableColumnFilter, enableExport: enableExport, enableReset: enableReset, enableTableSizeControl: enableTableSizeControl, enableColumnPinning: enableColumnPinning }, slotProps === null || slotProps === void 0 ? void 0 : slotProps.toolbar))) : null, enableBulkActions && enableRowSelection && isSomeRowsSelected ? ((0, jsx_runtime_1.jsx)(BulkActionsSlot, Object.assign({ selectionState: selectionState, selectedRowCount: selectedRowCount, bulkActions: bulkActions, sx: {
476
484
  position: 'relative',
477
485
  zIndex: 2,
478
486
  } }, slotProps === null || slotProps === void 0 ? void 0 : slotProps.bulkActionsToolbar))) : null, (0, jsx_runtime_1.jsx)(TableContainerSlot, Object.assign({ component: material_1.Paper, ref: tableContainerRef, sx: Object.assign(Object.assign(Object.assign({ width: '100%', overflowX: 'auto' }, (enableStickyHeaderOrFooter && {
@@ -23,6 +23,7 @@ function TableExportControl({ exportFilename: propsExportFilename, onServerExpor
23
23
  const handleExport = (format) => tslib_1.__awaiter(this, void 0, void 0, function* () {
24
24
  var _a, _b;
25
25
  try {
26
+ console.log('handleExport', dataMode, onServerExport);
26
27
  if (dataMode === 'server' && onServerExport) {
27
28
  const currentState = table.getState();
28
29
  const currentFilters = {
@@ -60,12 +61,23 @@ function TableExportControl({ exportFilename: propsExportFilename, onServerExpor
60
61
  });
61
62
  }
62
63
  });
63
- const selectedRowCount = Object.keys(table.getState().rowSelection).filter(key => table.getState().rowSelection[key]).length;
64
+ const selectedRowCount = table.getSelectedCount ? table.getSelectedCount() : 0;
65
+ const hasSelection = table.getIsSomeRowsSelected ? table.getIsSomeRowsSelected() : false;
66
+ const visibleColumns = table.getVisibleLeafColumns().filter(col => col.getIsVisible());
67
+ const exportableColumns = visibleColumns.filter(col => {
68
+ const columnDef = col.columnDef;
69
+ return columnDef.hideInExport !== true;
70
+ });
71
+ const hiddenFromExportColumns = visibleColumns.filter(col => {
72
+ const columnDef = col.columnDef;
73
+ return columnDef.hideInExport === true;
74
+ });
64
75
  const summary = {
65
76
  filteredRows: table.getFilteredRowModel().rows.length,
66
- totalColumns: table.getVisibleLeafColumns().filter(col => col.getIsVisible()).length,
77
+ totalColumns: exportableColumns.length,
78
+ hiddenColumns: hiddenFromExportColumns.length,
67
79
  selectedRows: selectedRowCount,
68
- hasSelection: selectedRowCount > 0,
80
+ hasSelection: hasSelection,
69
81
  };
70
82
  return ((0, jsx_runtime_1.jsx)(menu_dropdown_1.MenuDropdown, { anchor: ((0, jsx_runtime_1.jsx)(material_1.Tooltip, { title: "Export data", children: (0, jsx_runtime_1.jsx)(material_1.IconButton, { size: "small", disabled: isExporting, sx: {
71
83
  flexShrink: 0,
@@ -78,9 +90,9 @@ function TableExportControl({ exportFilename: propsExportFilename, onServerExpor
78
90
  p: 1,
79
91
  bgcolor: 'grey.50',
80
92
  borderRadius: 1,
81
- }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "subtitle2", gutterBottom: true, children: "Export Summary" }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body2", color: "text.secondary", children: summary.hasSelection
82
- ? `${summary.selectedRows} selected • ${summary.totalColumns} visible columns`
83
- : `${summary.filteredRows} filtered • ${summary.totalColumns} visible columns` }), summary.hasSelection ? ((0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "caption", color: "primary.main", sx: { fontWeight: 'medium' }, children: "Will export selected rows only" })) : null] }), isExporting ? ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, { onClick: () => {
93
+ }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "subtitle2", gutterBottom: true, children: "Export Summary" }), (0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "body2", color: "text.secondary", children: [summary.hasSelection
94
+ ? `${summary.selectedRows} selected • ${summary.totalColumns} exportable columns`
95
+ : `${summary.filteredRows} filtered • ${summary.totalColumns} exportable columns`, summary.hiddenColumns > 0 && ((0, jsx_runtime_1.jsxs)("span", { style: { color: 'orange' }, children: [' ', "\u2022 ", summary.hiddenColumns, " hidden from export"] }))] }), summary.hasSelection ? ((0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "caption", color: "primary.main", sx: { fontWeight: 'medium' }, children: "Will export selected rows only" })) : null] }), isExporting ? ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, { onClick: () => {
84
96
  onCancelExport === null || onCancelExport === void 0 ? void 0 : onCancelExport();
85
97
  handleClose();
86
98
  }, children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: (0, jsx_runtime_1.jsx)(ExportIconSlot, Object.assign({ fontSize: "small", color: "warning" }, slotProps === null || slotProps === void 0 ? void 0 : slotProps.exportIcon)) }), (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: "Cancel Export", secondary: "Stop current export" })] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(material_1.MenuItem, { onClick: () => tslib_1.__awaiter(this, void 0, void 0, function* () {
@@ -3,3 +3,4 @@ export { SelectionTestExample } from './selection-test-example';
3
3
  export { AdvancedFeaturesExample } from './advanced-features-example';
4
4
  export { SimpleLocalExample } from './simple-local-example';
5
5
  export { BulkActionsTest } from './bulk-actions-test';
6
+ export { ServerSideFetchingExample } from './server-side-fetching-example';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BulkActionsTest = exports.SimpleLocalExample = exports.AdvancedFeaturesExample = exports.SelectionTestExample = exports.CustomColumnFilterExample = void 0;
3
+ exports.ServerSideFetchingExample = exports.BulkActionsTest = exports.SimpleLocalExample = exports.AdvancedFeaturesExample = exports.SelectionTestExample = exports.CustomColumnFilterExample = void 0;
4
4
  var custom_column_filter_example_1 = require("./custom-column-filter-example");
5
5
  Object.defineProperty(exports, "CustomColumnFilterExample", { enumerable: true, get: function () { return custom_column_filter_example_1.CustomColumnFilterExample; } });
6
6
  var selection_test_example_1 = require("./selection-test-example");
@@ -11,3 +11,5 @@ var simple_local_example_1 = require("./simple-local-example");
11
11
  Object.defineProperty(exports, "SimpleLocalExample", { enumerable: true, get: function () { return simple_local_example_1.SimpleLocalExample; } });
12
12
  var bulk_actions_test_1 = require("./bulk-actions-test");
13
13
  Object.defineProperty(exports, "BulkActionsTest", { enumerable: true, get: function () { return bulk_actions_test_1.BulkActionsTest; } });
14
+ var server_side_fetching_example_1 = require("./server-side-fetching-example");
15
+ Object.defineProperty(exports, "ServerSideFetchingExample", { enumerable: true, get: function () { return server_side_fetching_example_1.ServerSideFetchingExample; } });
@@ -0,0 +1 @@
1
+ export declare function ServerSideFetchingExample(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,241 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ServerSideFetchingExample = ServerSideFetchingExample;
4
+ const tslib_1 = require("tslib");
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ const material_1 = require("@mui/material");
8
+ const data_table_1 = require("../components/table/data-table");
9
+ const MOCK_EMPLOYEES = Array.from({ length: 1000 }, (_, index) => {
10
+ const departments = ['Engineering', 'Marketing', 'Sales', 'HR', 'Finance', 'Operations'];
11
+ const roles = ['Manager', 'Senior', 'Junior', 'Lead', 'Director', 'Specialist'];
12
+ const firstNames = ['John', 'Jane', 'Bob', 'Alice', 'Charlie', 'Diana', 'Eve', 'Frank', 'Grace', 'Henry'];
13
+ const lastNames = ['Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Garcia', 'Miller', 'Davis', 'Rodriguez', 'Martinez'];
14
+ const firstName = firstNames[Math.floor(Math.random() * firstNames.length)];
15
+ const lastName = lastNames[Math.floor(Math.random() * lastNames.length)];
16
+ return {
17
+ id: index + 1,
18
+ name: `${firstName} ${lastName}`,
19
+ email: `${firstName.toLowerCase()}.${lastName.toLowerCase()}@company.com`,
20
+ department: departments[Math.floor(Math.random() * departments.length)],
21
+ role: roles[Math.floor(Math.random() * roles.length)],
22
+ salary: Math.floor(Math.random() * 80000) + 40000,
23
+ isActive: Math.random() > 0.15,
24
+ joinDate: new Date(2020 + Math.floor(Math.random() * 4), Math.floor(Math.random() * 12), Math.floor(Math.random() * 28) + 1).toISOString().split('T')[0],
25
+ };
26
+ });
27
+ function ServerSideFetchingExample() {
28
+ const [loading, setLoading] = (0, react_1.useState)(false);
29
+ const [error, setError] = (0, react_1.useState)(null);
30
+ const [selectionInfo, setSelectionInfo] = (0, react_1.useState)(null);
31
+ const [lastFetchParams, setLastFetchParams] = (0, react_1.useState)(null);
32
+ const [fetchCount, setFetchCount] = (0, react_1.useState)(0);
33
+ const apiRef = (0, react_1.useRef)(null);
34
+ const handleFetchData = (0, react_1.useCallback)((filters) => tslib_1.__awaiter(this, void 0, void 0, function* () {
35
+ var _a, _b, _c;
36
+ console.log('🔄 Fetching data with filters:', filters);
37
+ setLoading(true);
38
+ setError(null);
39
+ setLastFetchParams(filters);
40
+ setFetchCount(prev => prev + 1);
41
+ try {
42
+ yield new Promise(resolve => setTimeout(resolve, 300 + Math.random() * 500));
43
+ let filteredData = [...MOCK_EMPLOYEES];
44
+ if (filters.globalFilter) {
45
+ const searchTerm = filters.globalFilter.toLowerCase();
46
+ filteredData = filteredData.filter(employee => employee.name.toLowerCase().includes(searchTerm) ||
47
+ employee.email.toLowerCase().includes(searchTerm) ||
48
+ employee.department.toLowerCase().includes(searchTerm) ||
49
+ employee.role.toLowerCase().includes(searchTerm));
50
+ }
51
+ if ((_b = (_a = filters.customColumnsFilter) === null || _a === void 0 ? void 0 : _a.filters) === null || _b === void 0 ? void 0 : _b.length) {
52
+ filteredData = filteredData.filter(employee => {
53
+ return filters.customColumnsFilter.filters.every((filter) => {
54
+ const value = employee[filter.columnId];
55
+ const filterValue = filter.value;
56
+ switch (filter.operator) {
57
+ case 'equals':
58
+ return value === filterValue;
59
+ case 'contains':
60
+ return String(value).toLowerCase().includes(String(filterValue).toLowerCase());
61
+ case 'startsWith':
62
+ return String(value).toLowerCase().startsWith(String(filterValue).toLowerCase());
63
+ case 'endsWith':
64
+ return String(value).toLowerCase().endsWith(String(filterValue).toLowerCase());
65
+ case 'greaterThan':
66
+ return Number(value) > Number(filterValue);
67
+ case 'lessThan':
68
+ return Number(value) < Number(filterValue);
69
+ default:
70
+ return true;
71
+ }
72
+ });
73
+ });
74
+ }
75
+ if ((_c = filters.sorting) === null || _c === void 0 ? void 0 : _c.length) {
76
+ filteredData.sort((a, b) => {
77
+ for (const sort of filters.sorting) {
78
+ const aValue = a[sort.id];
79
+ const bValue = b[sort.id];
80
+ let comparison = 0;
81
+ if (aValue < bValue)
82
+ comparison = -1;
83
+ else if (aValue > bValue)
84
+ comparison = 1;
85
+ if (comparison !== 0) {
86
+ return sort.desc ? -comparison : comparison;
87
+ }
88
+ }
89
+ return 0;
90
+ });
91
+ }
92
+ const total = filteredData.length;
93
+ let pageData = filteredData;
94
+ if (filters.pagination) {
95
+ const { pageIndex = 0, pageSize = 10 } = filters.pagination;
96
+ const start = pageIndex * pageSize;
97
+ const end = start + pageSize;
98
+ pageData = filteredData.slice(start, end);
99
+ }
100
+ console.log('✅ Data fetched successfully:', {
101
+ total,
102
+ pageSize: pageData.length,
103
+ filters: filters.pagination
104
+ });
105
+ return {
106
+ data: pageData,
107
+ total: total,
108
+ };
109
+ }
110
+ catch (err) {
111
+ console.error('❌ Error fetching data:', err);
112
+ setError('Failed to fetch data. Please try again.');
113
+ throw err;
114
+ }
115
+ finally {
116
+ setLoading(false);
117
+ }
118
+ }), []);
119
+ const handleSelectionChange = (0, react_1.useCallback)((selection) => {
120
+ console.log('🔄 Selection changed:', selection);
121
+ setSelectionInfo(selection);
122
+ }, []);
123
+ const handleServerExport = (0, react_1.useCallback)((filters, selection) => tslib_1.__awaiter(this, void 0, void 0, function* () {
124
+ console.log('📤 Exporting data with filters:', filters);
125
+ console.log('📤 Export selection:', selection);
126
+ yield new Promise(resolve => setTimeout(resolve, 1000));
127
+ let exportData = [...MOCK_EMPLOYEES];
128
+ if (filters === null || filters === void 0 ? void 0 : filters.globalFilter) {
129
+ const searchTerm = filters.globalFilter.toLowerCase();
130
+ exportData = exportData.filter(employee => employee.name.toLowerCase().includes(searchTerm) ||
131
+ employee.email.toLowerCase().includes(searchTerm) ||
132
+ employee.department.toLowerCase().includes(searchTerm) ||
133
+ employee.role.toLowerCase().includes(searchTerm));
134
+ }
135
+ if (selection.type === 'include' && selection.ids.length > 0) {
136
+ exportData = exportData.filter(employee => selection.ids.includes(employee.id.toString()));
137
+ }
138
+ else if (selection.type === 'exclude' && selection.ids.length > 0) {
139
+ exportData = exportData.filter(employee => !selection.ids.includes(employee.id.toString()));
140
+ }
141
+ return {
142
+ data: exportData,
143
+ total: exportData.length,
144
+ };
145
+ }), []);
146
+ const columns = [
147
+ {
148
+ id: 'name',
149
+ accessorKey: 'name',
150
+ header: 'Name',
151
+ size: 200,
152
+ enableGlobalFilter: true,
153
+ },
154
+ {
155
+ id: 'email',
156
+ accessorKey: 'email',
157
+ header: 'Email',
158
+ size: 250,
159
+ enableGlobalFilter: true,
160
+ },
161
+ {
162
+ id: 'department',
163
+ accessorKey: 'department',
164
+ header: 'Department',
165
+ size: 150,
166
+ enableGlobalFilter: true,
167
+ },
168
+ {
169
+ id: 'role',
170
+ accessorKey: 'role',
171
+ header: 'Role',
172
+ size: 120,
173
+ enableGlobalFilter: true,
174
+ },
175
+ {
176
+ id: 'salary',
177
+ accessorKey: 'salary',
178
+ header: 'Salary',
179
+ size: 120,
180
+ accessorFn: (row) => `$${row.salary.toLocaleString()}`,
181
+ hideInExport: true,
182
+ },
183
+ {
184
+ id: 'isActive',
185
+ accessorKey: 'isActive',
186
+ header: 'Status',
187
+ size: 100,
188
+ accessorFn: (row) => row.isActive ? 'Active' : 'Inactive',
189
+ cell: ({ getValue }) => ((0, jsx_runtime_1.jsx)(material_1.Chip, { label: getValue() ? 'Active' : 'Inactive', color: getValue() ? 'success' : 'default', size: "small" })),
190
+ },
191
+ {
192
+ id: 'joinDate',
193
+ accessorKey: 'joinDate',
194
+ header: 'Join Date',
195
+ size: 120,
196
+ accessorFn: (row) => new Date(row.joinDate).toLocaleDateString(),
197
+ },
198
+ ];
199
+ return ((0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { p: 3 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h4", gutterBottom: true, children: "Server-Side Data Fetching Example" }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body1", color: "text.secondary", paragraph: true, children: "Demonstrates server-side data fetching with proper API ref state management and page-based selection. The Salary column has `hideInExport: true` so it will be excluded from exports." }), (0, jsx_runtime_1.jsxs)(material_1.Stack, { direction: "row", spacing: 2, sx: { mb: 3 }, children: [(0, jsx_runtime_1.jsx)(material_1.Card, { variant: "outlined", children: (0, jsx_runtime_1.jsxs)(material_1.CardContent, { sx: { pb: 2 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h6", color: "primary", children: fetchCount }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body2", color: "text.secondary", children: "API Calls Made" })] }) }), (0, jsx_runtime_1.jsx)(material_1.Card, { variant: "outlined", children: (0, jsx_runtime_1.jsxs)(material_1.CardContent, { sx: { pb: 2 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h6", color: "secondary", children: (selectionInfo === null || selectionInfo === void 0 ? void 0 : selectionInfo.ids.length) || 0 }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body2", color: "text.secondary", children: "Selected Items" })] }) }), (0, jsx_runtime_1.jsx)(material_1.Card, { variant: "outlined", children: (0, jsx_runtime_1.jsxs)(material_1.CardContent, { sx: { pb: 2 }, children: [(0, jsx_runtime_1.jsxs)(material_1.Stack, { direction: "row", alignItems: "center", spacing: 1, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h6", color: loading ? 'warning.main' : 'success.main', children: loading ? 'Loading...' : 'Ready' }), loading && (0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 16 })] }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body2", color: "text.secondary", children: "Server Status" })] }) })] }), error && ((0, jsx_runtime_1.jsx)(material_1.Alert, { severity: "error", sx: { mb: 3 }, children: error })), (0, jsx_runtime_1.jsx)(material_1.Card, { sx: { mb: 3 }, children: (0, jsx_runtime_1.jsxs)(material_1.CardContent, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h6", gutterBottom: true, children: "API Controls (via apiRef)" }), (0, jsx_runtime_1.jsxs)(material_1.Stack, { direction: "row", spacing: 2, flexWrap: "wrap", children: [(0, jsx_runtime_1.jsx)(material_1.Button, { variant: "outlined", size: "small", onClick: () => {
200
+ var _a;
201
+ const state = (_a = apiRef.current) === null || _a === void 0 ? void 0 : _a.selection.getSelectionState();
202
+ console.log('Current Selection State:', state);
203
+ alert(`Selection: ${JSON.stringify(state, null, 2)}`);
204
+ }, children: "Get Selection State" }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "outlined", size: "small", onClick: () => {
205
+ var _a;
206
+ const count = (_a = apiRef.current) === null || _a === void 0 ? void 0 : _a.selection.getSelectedCount();
207
+ console.log('Selected Count:', count);
208
+ alert(`Selected Count: ${count}`);
209
+ }, children: "Get Selected Count" }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "outlined", size: "small", onClick: () => {
210
+ var _a;
211
+ (_a = apiRef.current) === null || _a === void 0 ? void 0 : _a.selection.selectAll();
212
+ console.log('Selected all rows on current page');
213
+ }, children: "Select All (Page)" }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "outlined", size: "small", onClick: () => {
214
+ var _a;
215
+ (_a = apiRef.current) === null || _a === void 0 ? void 0 : _a.selection.deselectAll();
216
+ console.log('Deselected all rows');
217
+ }, children: "Deselect All" }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "outlined", size: "small", onClick: () => {
218
+ var _a;
219
+ (_a = apiRef.current) === null || _a === void 0 ? void 0 : _a.data.refresh();
220
+ console.log('Refreshed data');
221
+ }, children: "Refresh Data" })] })] }) }), selectionInfo && ((0, jsx_runtime_1.jsx)(material_1.Card, { sx: { mb: 3 }, children: (0, jsx_runtime_1.jsxs)(material_1.CardContent, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h6", gutterBottom: true, children: "Current Selection Info" }), (0, jsx_runtime_1.jsx)(material_1.Paper, { sx: { p: 2, bgcolor: 'grey.50' }, children: (0, jsx_runtime_1.jsxs)(material_1.Stack, { spacing: 1, children: [(0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "body2", children: [(0, jsx_runtime_1.jsx)("strong", { children: "Selection Type:" }), " ", selectionInfo.type] }), (0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "body2", children: [(0, jsx_runtime_1.jsx)("strong", { children: "Selected IDs:" }), " [", selectionInfo.ids.join(', '), "]"] }), (0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "body2", children: [(0, jsx_runtime_1.jsx)("strong", { children: "Count:" }), " ", selectionInfo.ids.length] })] }) })] }) })), (0, jsx_runtime_1.jsx)(material_1.Card, { sx: { mb: 3 }, children: (0, jsx_runtime_1.jsxs)(material_1.CardContent, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h6", gutterBottom: true, children: "Export & Column Configuration" }), (0, jsx_runtime_1.jsx)(material_1.Alert, { severity: "info", sx: { mb: 2 }, children: (0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "body2", children: [(0, jsx_runtime_1.jsx)("strong", { children: "hideInExport Demo:" }), " The Salary column has `hideInExport: true` so it will be excluded from CSV/Excel exports. Try exporting to see the difference!"] }) }), (0, jsx_runtime_1.jsxs)(material_1.Stack, { spacing: 1, children: [(0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "body2", children: [(0, jsx_runtime_1.jsx)("strong", { children: "Exportable columns:" }), " Name, Email, Department, Role, Status, Join Date"] }), (0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "body2", color: "warning.main", children: [(0, jsx_runtime_1.jsx)("strong", { children: "Hidden from export:" }), " Salary (contains sensitive data)"] })] })] }) }), lastFetchParams && ((0, jsx_runtime_1.jsx)(material_1.Card, { sx: { mb: 3 }, children: (0, jsx_runtime_1.jsxs)(material_1.CardContent, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h6", gutterBottom: true, children: "Last Fetch Parameters" }), (0, jsx_runtime_1.jsx)(material_1.Paper, { sx: { p: 2, bgcolor: 'grey.50' }, children: (0, jsx_runtime_1.jsx)("pre", { style: { fontSize: '12px', margin: 0, overflow: 'auto' }, children: JSON.stringify(lastFetchParams, null, 2) }) })] }) })), (0, jsx_runtime_1.jsx)(material_1.Divider, { sx: { mb: 3 } }), (0, jsx_runtime_1.jsx)(data_table_1.DataTable, { ref: apiRef, columns: columns, dataMode: "server", initialLoadData: true, onFetchData: handleFetchData, loading: loading, enableRowSelection: true, enableMultiRowSelection: true, selectMode: "page", onSelectionChange: handleSelectionChange, enableBulkActions: true, bulkActions: (selectionState) => ((0, jsx_runtime_1.jsxs)(material_1.Stack, { direction: "row", spacing: 1, children: [(0, jsx_runtime_1.jsxs)(material_1.Button, { variant: "contained", size: "small", color: "error", onClick: () => {
222
+ console.log('Bulk delete action triggered');
223
+ console.log('Selection state:', selectionState);
224
+ alert(`Would delete ${selectionState.ids.length} items`);
225
+ }, children: ["Delete Selected (", selectionState.ids.length, ")"] }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "outlined", size: "small", onClick: () => {
226
+ console.log('Bulk update action triggered');
227
+ console.log('Selection state:', selectionState);
228
+ alert(`Would update ${selectionState.ids.length} items`);
229
+ }, children: "Update Selected" })] })), enableGlobalFilter: true, enableColumnFilter: true, enableSorting: true, enablePagination: true, initialState: {
230
+ pagination: {
231
+ pageIndex: 0,
232
+ pageSize: 10,
233
+ },
234
+ }, enableExport: true, exportFilename: "employees", onServerExport: handleServerExport, onExportProgress: (progress) => {
235
+ console.log('Export progress:', progress);
236
+ }, onExportComplete: (result) => {
237
+ console.log('Export completed:', result);
238
+ }, onExportError: (error) => {
239
+ console.error('Export error:', error);
240
+ }, enableHover: true, enableStripes: true, tableSize: "medium", enableColumnVisibility: true, enableTableSizeControl: true, enableReset: true, emptyMessage: "No employees found matching your criteria", skeletonRows: 10 })] }));
241
+ }
@@ -0,0 +1 @@
1
+ export declare function ServerSideTest(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ServerSideTest = ServerSideTest;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const material_1 = require("@mui/material");
6
+ const server_side_fetching_example_1 = require("./server-side-fetching-example");
7
+ function ServerSideTest() {
8
+ return ((0, jsx_runtime_1.jsx)(material_1.Box, { sx: { p: 2 }, children: (0, jsx_runtime_1.jsxs)(material_1.Paper, { sx: { p: 3 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h5", gutterBottom: true, children: "Server-Side Data Fetching Test" }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body2", color: "text.secondary", paragraph: true, children: "This example demonstrates how to use the DataTable component with server-side data fetching. The onFetchData callback handles all server operations including filtering, sorting, and pagination." }), (0, jsx_runtime_1.jsx)(server_side_fetching_example_1.ServerSideFetchingExample, {})] }) }));
9
+ }
@@ -116,7 +116,7 @@ exports.CustomSelectionFeature = {
116
116
  const selectMode = table.options.selectMode || 'page';
117
117
  if (selectMode === 'all' && state.type === 'exclude') {
118
118
  const totalCount = table.getRowCount();
119
- return state.ids.length < totalCount;
119
+ return state.ids.length < totalCount && totalCount > 0;
120
120
  }
121
121
  else {
122
122
  return state.ids.length > 0;
@@ -134,7 +134,7 @@ exports.CustomSelectionFeature = {
134
134
  const selectMode = table.options.selectMode || 'page';
135
135
  if (selectMode === 'all' && state.type === 'exclude') {
136
136
  const totalCount = table.getRowCount();
137
- return totalCount - state.ids.length;
137
+ return Math.max(0, totalCount - state.ids.length);
138
138
  }
139
139
  else {
140
140
  return state.ids.length;
@@ -19,9 +19,11 @@ function exportClientData(table, options) {
19
19
  });
20
20
  const rowData = {};
21
21
  row.getVisibleCells().forEach(cell => {
22
- const header = typeof cell.column.columnDef.header === 'string'
23
- ? cell.column.columnDef.header
24
- : cell.column.id;
22
+ const columnDef = cell.column.columnDef;
23
+ if (columnDef.hideInExport === true) {
24
+ return;
25
+ }
26
+ const header = typeof columnDef.header === 'string' ? columnDef.header : cell.column.id;
25
27
  rowData[header] = cell.getValue() || '';
26
28
  });
27
29
  return rowData;
@@ -55,7 +57,10 @@ function exportServerData(table, options) {
55
57
  if (!data || !Array.isArray(data)) {
56
58
  throw new Error('Invalid data received from server');
57
59
  }
58
- const visibleColumns = table.getVisibleLeafColumns().filter(col => col.getIsVisible());
60
+ const visibleColumns = table.getVisibleLeafColumns().filter(col => {
61
+ const columnDef = col.columnDef;
62
+ return col.getIsVisible() && columnDef.hideInExport !== true;
63
+ });
59
64
  const exportData = data.map((rowData, index) => {
60
65
  onProgress === null || onProgress === void 0 ? void 0 : onProgress({
61
66
  processedRows: index + 1,
@@ -64,14 +69,15 @@ function exportServerData(table, options) {
64
69
  });
65
70
  const exportRow = {};
66
71
  visibleColumns.forEach(column => {
72
+ var _a;
67
73
  const columnId = column.id;
68
- const header = typeof column.columnDef.header === 'string'
69
- ? column.columnDef.header
74
+ const columnDef = column.columnDef;
75
+ const header = typeof columnDef.header === 'string'
76
+ ? columnDef.header
70
77
  : columnId;
71
78
  let value = rowData[columnId];
72
- const columnDef = column.columnDef;
73
- if (columnDef.accessorFn && typeof columnDef.accessorFn === 'function') {
74
- value = columnDef.accessorFn(rowData);
79
+ if (column.accessorFn && typeof column.accessorFn === 'function') {
80
+ value = ((_a = (column.accessorFn(rowData, index) || '')) === null || _a === void 0 ? void 0 : _a.toString()) || '';
75
81
  }
76
82
  if (value === null || value === undefined) {
77
83
  value = '';