@ackplus/react-tanstack-data-table 1.1.19 → 1.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/hooks/use-data-table-engine.d.ts.map +1 -1
- package/dist/lib/hooks/use-data-table-engine.js +54 -15
- package/dist/lib/types/data-table.types.d.ts +2 -1
- package/dist/lib/types/data-table.types.d.ts.map +1 -1
- package/package.json +3 -4
- package/src/index.ts +0 -75
- package/src/lib/components/data-table-view.tsx +0 -386
- package/src/lib/components/droupdown/menu-dropdown.tsx +0 -103
- package/src/lib/components/filters/filter-value-input.tsx +0 -225
- package/src/lib/components/filters/index.ts +0 -126
- package/src/lib/components/headers/draggable-header.tsx +0 -326
- package/src/lib/components/headers/index.ts +0 -6
- package/src/lib/components/headers/table-header.tsx +0 -175
- package/src/lib/components/index.ts +0 -21
- package/src/lib/components/pagination/data-table-pagination.tsx +0 -111
- package/src/lib/components/pagination/index.ts +0 -5
- package/src/lib/components/rows/data-table-row.tsx +0 -218
- package/src/lib/components/rows/empty-data-row.tsx +0 -69
- package/src/lib/components/rows/index.ts +0 -7
- package/src/lib/components/rows/loading-rows.tsx +0 -164
- package/src/lib/components/toolbar/bulk-actions-toolbar.tsx +0 -125
- package/src/lib/components/toolbar/column-filter-control.tsx +0 -432
- package/src/lib/components/toolbar/column-pinning-control.tsx +0 -275
- package/src/lib/components/toolbar/column-reset-control.tsx +0 -74
- package/src/lib/components/toolbar/column-visibility-control.tsx +0 -105
- package/src/lib/components/toolbar/data-table-toolbar.tsx +0 -257
- package/src/lib/components/toolbar/index.ts +0 -17
- package/src/lib/components/toolbar/table-export-control.tsx +0 -233
- package/src/lib/components/toolbar/table-refresh-control.tsx +0 -62
- package/src/lib/components/toolbar/table-search-control.tsx +0 -155
- package/src/lib/components/toolbar/table-size-control.tsx +0 -102
- package/src/lib/contexts/data-table-context.tsx +0 -126
- package/src/lib/data-table.tsx +0 -29
- package/src/lib/features/README.md +0 -161
- package/src/lib/features/column-filter.feature.ts +0 -493
- package/src/lib/features/index.ts +0 -23
- package/src/lib/features/selection.feature.ts +0 -322
- package/src/lib/hooks/index.ts +0 -2
- package/src/lib/hooks/use-data-table-engine.ts +0 -1516
- package/src/lib/icons/add-icon.tsx +0 -23
- package/src/lib/icons/csv-icon.tsx +0 -15
- package/src/lib/icons/delete-icon.tsx +0 -30
- package/src/lib/icons/excel-icon.tsx +0 -15
- package/src/lib/icons/index.ts +0 -7
- package/src/lib/icons/unpin-icon.tsx +0 -18
- package/src/lib/icons/view-comfortable-icon.tsx +0 -45
- package/src/lib/icons/view-compact-icon.tsx +0 -55
- package/src/lib/types/column.types.ts +0 -63
- package/src/lib/types/data-table-api.ts +0 -191
- package/src/lib/types/data-table.types.ts +0 -192
- package/src/lib/types/export.types.ts +0 -223
- package/src/lib/types/index.ts +0 -24
- package/src/lib/types/slots.types.ts +0 -342
- package/src/lib/types/table.types.ts +0 -88
- package/src/lib/utils/column-helpers.ts +0 -72
- package/src/lib/utils/debounced-fetch.utils.ts +0 -131
- package/src/lib/utils/export-utils.ts +0 -712
- package/src/lib/utils/index.ts +0 -27
- package/src/lib/utils/logger.ts +0 -203
- package/src/lib/utils/slot-helpers.tsx +0 -194
- package/src/lib/utils/special-columns.utils.ts +0 -101
- package/src/lib/utils/styling-helpers.ts +0 -126
- package/src/lib/utils/table-helpers.ts +0 -106
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Stack,
|
|
3
|
-
Toolbar,
|
|
4
|
-
Typography,
|
|
5
|
-
Box,
|
|
6
|
-
ToolbarProps,
|
|
7
|
-
SxProps,
|
|
8
|
-
} from '@mui/material';
|
|
9
|
-
import React, { ReactNode, ReactElement } from 'react';
|
|
10
|
-
|
|
11
|
-
import { ColumnFilterControl } from './column-filter-control';
|
|
12
|
-
import { ColumnPinningControl } from './column-pinning-control';
|
|
13
|
-
import { ColumnResetControl } from './column-reset-control';
|
|
14
|
-
import { ColumnVisibilityControl } from './column-visibility-control';
|
|
15
|
-
import { TableExportControl } from './table-export-control';
|
|
16
|
-
import { TableSearchControl } from './table-search-control';
|
|
17
|
-
import { TableSizeControl } from './table-size-control';
|
|
18
|
-
import { useDataTableContext } from '../../contexts/data-table-context';
|
|
19
|
-
import { TableRefreshControl } from './table-refresh-control';
|
|
20
|
-
import { getSlotComponent, mergeSlotProps, extractSlotProps } from '../../utils/slot-helpers';
|
|
21
|
-
|
|
22
|
-
export interface DataTableToolbarProps extends ToolbarProps {
|
|
23
|
-
extraFilter?: ReactNode;
|
|
24
|
-
enableGlobalFilter?: boolean;
|
|
25
|
-
title?: string;
|
|
26
|
-
subtitle?: string;
|
|
27
|
-
enableColumnVisibility?: boolean;
|
|
28
|
-
enableExport?: boolean;
|
|
29
|
-
enableReset?: boolean;
|
|
30
|
-
enableColumnFilter?: boolean;
|
|
31
|
-
enableTableSizeControl?: boolean;
|
|
32
|
-
enableColumnPinning?: boolean;
|
|
33
|
-
// Enhanced styling props
|
|
34
|
-
titleSx?: SxProps;
|
|
35
|
-
subtitleSx?: SxProps;
|
|
36
|
-
containerSx?: SxProps;
|
|
37
|
-
leftSectionSx?: SxProps;
|
|
38
|
-
rightSectionSx?: SxProps;
|
|
39
|
-
// Allow full customization of any prop
|
|
40
|
-
[key: string]: any;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export function DataTableToolbar(props: DataTableToolbarProps = {}): ReactElement {
|
|
44
|
-
const {
|
|
45
|
-
extraFilter = null,
|
|
46
|
-
enableGlobalFilter = true,
|
|
47
|
-
title,
|
|
48
|
-
subtitle,
|
|
49
|
-
enableColumnVisibility = true,
|
|
50
|
-
enableExport = true,
|
|
51
|
-
enableReset = true,
|
|
52
|
-
enableRefresh = false,
|
|
53
|
-
enableColumnFilter = true,
|
|
54
|
-
enableTableSizeControl = true,
|
|
55
|
-
enableColumnPinning = true,
|
|
56
|
-
titleSx,
|
|
57
|
-
subtitleSx,
|
|
58
|
-
containerSx,
|
|
59
|
-
leftSectionSx,
|
|
60
|
-
rightSectionSx,
|
|
61
|
-
...otherProps
|
|
62
|
-
} = props;
|
|
63
|
-
|
|
64
|
-
const { table, slots, slotProps = {} } = useDataTableContext();
|
|
65
|
-
|
|
66
|
-
// Extract slot-specific props with enhanced merging
|
|
67
|
-
const toolbarSlotProps = extractSlotProps(slotProps, 'toolbar');
|
|
68
|
-
const searchInputSlotProps = extractSlotProps(slotProps, 'searchInput');
|
|
69
|
-
const tableSizeControlSlotProps = extractSlotProps(slotProps, 'tableSizeControl');
|
|
70
|
-
const columnCustomFilterControlSlotProps = extractSlotProps(slotProps, 'columnCustomFilterControl');
|
|
71
|
-
const columnPinningControlSlotProps = extractSlotProps(slotProps, 'columnPinningControl');
|
|
72
|
-
const columnVisibilityControlSlotProps = extractSlotProps(slotProps, 'columnVisibilityControl');
|
|
73
|
-
const resetButtonSlotProps = extractSlotProps(slotProps, 'resetButton');
|
|
74
|
-
const exportButtonSlotProps = extractSlotProps(slotProps, 'exportButton');
|
|
75
|
-
const refreshButtonSlotProps = extractSlotProps(slotProps, 'refreshButton');
|
|
76
|
-
|
|
77
|
-
const ToolbarSlot = getSlotComponent(slots, 'toolbar', Toolbar);
|
|
78
|
-
const TableSearchControlSlot = getSlotComponent(slots, 'searchInput', TableSearchControl);
|
|
79
|
-
const TableSizeControlSlot = getSlotComponent(slots, 'tableSizeControl', TableSizeControl);
|
|
80
|
-
const ColumnCustomFilterControlSlot = getSlotComponent(slots, 'columnCustomFilterControl', ColumnFilterControl);
|
|
81
|
-
const ColumnPinningControlSlot = getSlotComponent(slots, 'columnPinningControl', ColumnPinningControl);
|
|
82
|
-
const ColumnVisibilityControlSlot = getSlotComponent(slots, 'columnVisibilityControl', ColumnVisibilityControl);
|
|
83
|
-
const ColumnResetControlSlot = getSlotComponent(slots, 'resetButton', ColumnResetControl);
|
|
84
|
-
const TableExportControlSlot = getSlotComponent(slots, 'exportButton', TableExportControl);
|
|
85
|
-
const TableRefreshControlSlot = getSlotComponent(slots, 'refreshButton', TableRefreshControl);
|
|
86
|
-
|
|
87
|
-
// Merge all props for maximum flexibility
|
|
88
|
-
const mergedToolbarProps = mergeSlotProps(
|
|
89
|
-
{
|
|
90
|
-
// Default toolbar props
|
|
91
|
-
table,
|
|
92
|
-
...otherProps,
|
|
93
|
-
},
|
|
94
|
-
toolbarSlotProps
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
// Omit child-slot props so they are not spread onto the Toolbar DOM element (React warning)
|
|
98
|
-
const TOOLBAR_CHILD_SLOT_KEYS = [
|
|
99
|
-
'refreshButtonProps',
|
|
100
|
-
'searchInputProps',
|
|
101
|
-
'tableSizeControlProps',
|
|
102
|
-
'columnFilterProps',
|
|
103
|
-
'columnPinningProps',
|
|
104
|
-
'columnVisibilityProps',
|
|
105
|
-
'resetButtonProps',
|
|
106
|
-
'exportButtonProps',
|
|
107
|
-
] as const;
|
|
108
|
-
const toolbarDomProps = { ...mergedToolbarProps };
|
|
109
|
-
TOOLBAR_CHILD_SLOT_KEYS.forEach((key) => delete toolbarDomProps[key]);
|
|
110
|
-
|
|
111
|
-
return (
|
|
112
|
-
<ToolbarSlot
|
|
113
|
-
{...toolbarDomProps}
|
|
114
|
-
>
|
|
115
|
-
<Box
|
|
116
|
-
sx={{
|
|
117
|
-
width: '100%',
|
|
118
|
-
...containerSx,
|
|
119
|
-
}}
|
|
120
|
-
>
|
|
121
|
-
{(title || subtitle) ? (
|
|
122
|
-
<Box sx={{ mb: 2 }}>
|
|
123
|
-
{title ? (
|
|
124
|
-
<Typography
|
|
125
|
-
variant="h6"
|
|
126
|
-
component="div"
|
|
127
|
-
sx={titleSx}
|
|
128
|
-
>
|
|
129
|
-
{title}
|
|
130
|
-
</Typography>
|
|
131
|
-
) : null}
|
|
132
|
-
{subtitle ? (
|
|
133
|
-
<Typography
|
|
134
|
-
variant="body2"
|
|
135
|
-
color="text.secondary"
|
|
136
|
-
sx={subtitleSx}
|
|
137
|
-
>
|
|
138
|
-
{subtitle}
|
|
139
|
-
</Typography>
|
|
140
|
-
) : null}
|
|
141
|
-
</Box>
|
|
142
|
-
) : null}
|
|
143
|
-
|
|
144
|
-
<Stack
|
|
145
|
-
direction="row"
|
|
146
|
-
spacing={2}
|
|
147
|
-
justifyContent="space-between"
|
|
148
|
-
alignItems="center"
|
|
149
|
-
>
|
|
150
|
-
{/* Left Section - Search, Filters, Actions, and Status */}
|
|
151
|
-
<Stack
|
|
152
|
-
direction="row"
|
|
153
|
-
spacing={0.5}
|
|
154
|
-
alignItems="center"
|
|
155
|
-
sx={{
|
|
156
|
-
flex: 1,
|
|
157
|
-
...leftSectionSx,
|
|
158
|
-
}}
|
|
159
|
-
>
|
|
160
|
-
{/* Table Actions and Filters */}
|
|
161
|
-
{enableTableSizeControl ? (
|
|
162
|
-
<TableSizeControlSlot
|
|
163
|
-
{...mergeSlotProps(
|
|
164
|
-
{},
|
|
165
|
-
tableSizeControlSlotProps,
|
|
166
|
-
props.tableSizeControlProps || {}
|
|
167
|
-
)}
|
|
168
|
-
/>
|
|
169
|
-
) : null}
|
|
170
|
-
|
|
171
|
-
{enableColumnFilter ? (
|
|
172
|
-
<ColumnCustomFilterControlSlot
|
|
173
|
-
{...mergeSlotProps(
|
|
174
|
-
{},
|
|
175
|
-
columnCustomFilterControlSlotProps,
|
|
176
|
-
props.columnFilterProps || {}
|
|
177
|
-
)}
|
|
178
|
-
/>
|
|
179
|
-
) : null}
|
|
180
|
-
|
|
181
|
-
{enableColumnPinning ? (
|
|
182
|
-
<ColumnPinningControlSlot
|
|
183
|
-
{...mergeSlotProps(
|
|
184
|
-
{},
|
|
185
|
-
columnPinningControlSlotProps,
|
|
186
|
-
props.columnPinningProps || {}
|
|
187
|
-
)}
|
|
188
|
-
/>
|
|
189
|
-
) : null}
|
|
190
|
-
|
|
191
|
-
{enableColumnVisibility ? (
|
|
192
|
-
<ColumnVisibilityControlSlot
|
|
193
|
-
{...mergeSlotProps(
|
|
194
|
-
{},
|
|
195
|
-
columnVisibilityControlSlotProps,
|
|
196
|
-
props.columnVisibilityProps || {}
|
|
197
|
-
)}
|
|
198
|
-
/>
|
|
199
|
-
) : null}
|
|
200
|
-
|
|
201
|
-
{enableReset ? (
|
|
202
|
-
<ColumnResetControlSlot
|
|
203
|
-
{...mergeSlotProps(
|
|
204
|
-
{},
|
|
205
|
-
resetButtonSlotProps,
|
|
206
|
-
props.resetButtonProps || {}
|
|
207
|
-
)}
|
|
208
|
-
/>
|
|
209
|
-
) : null}
|
|
210
|
-
|
|
211
|
-
{enableExport ? (
|
|
212
|
-
<TableExportControlSlot
|
|
213
|
-
{...mergeSlotProps(
|
|
214
|
-
{},
|
|
215
|
-
exportButtonSlotProps,
|
|
216
|
-
props.exportButtonProps || {}
|
|
217
|
-
)}
|
|
218
|
-
/>
|
|
219
|
-
) : null}
|
|
220
|
-
|
|
221
|
-
{/* Search */}
|
|
222
|
-
{enableGlobalFilter ? (
|
|
223
|
-
<TableSearchControlSlot
|
|
224
|
-
{...mergeSlotProps(
|
|
225
|
-
{},
|
|
226
|
-
searchInputSlotProps,
|
|
227
|
-
props.searchInputProps || {}
|
|
228
|
-
)}
|
|
229
|
-
/>
|
|
230
|
-
) : null}
|
|
231
|
-
|
|
232
|
-
{enableRefresh ? (
|
|
233
|
-
<TableRefreshControlSlot
|
|
234
|
-
{...mergeSlotProps(
|
|
235
|
-
{},
|
|
236
|
-
refreshButtonSlotProps,
|
|
237
|
-
props.refreshButtonProps || {}
|
|
238
|
-
)}
|
|
239
|
-
/>
|
|
240
|
-
) : null}
|
|
241
|
-
</Stack>
|
|
242
|
-
|
|
243
|
-
{/* Right Section - Extra Filter and More Menu */}
|
|
244
|
-
<Stack
|
|
245
|
-
direction="row"
|
|
246
|
-
spacing={1}
|
|
247
|
-
alignItems="center"
|
|
248
|
-
sx={rightSectionSx}
|
|
249
|
-
>
|
|
250
|
-
{/* Extra Filter */}
|
|
251
|
-
{extraFilter as any}
|
|
252
|
-
</Stack>
|
|
253
|
-
</Stack>
|
|
254
|
-
</Box>
|
|
255
|
-
</ToolbarSlot>
|
|
256
|
-
);
|
|
257
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Toolbar components for DataTable
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
// Main toolbar component
|
|
6
|
-
export { DataTableToolbar } from './data-table-toolbar';
|
|
7
|
-
|
|
8
|
-
// Individual toolbar building blocks - export for custom toolbars
|
|
9
|
-
export { ColumnVisibilityControl } from './column-visibility-control';
|
|
10
|
-
export { ColumnPinningControl } from './column-pinning-control';
|
|
11
|
-
export { ColumnResetControl } from './column-reset-control';
|
|
12
|
-
export { TableExportControl } from './table-export-control';
|
|
13
|
-
export { TableSizeControl } from './table-size-control';
|
|
14
|
-
export { ColumnFilterControl } from './column-filter-control';
|
|
15
|
-
// Bulk actions
|
|
16
|
-
export { BulkActionsToolbar } from './bulk-actions-toolbar';
|
|
17
|
-
export type { BulkActionsToolbarProps } from './bulk-actions-toolbar';
|
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
import { CloudDownloadOutlined } from '@mui/icons-material';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import {
|
|
4
|
-
IconButton,
|
|
5
|
-
Tooltip,
|
|
6
|
-
MenuItem,
|
|
7
|
-
ListItemIcon,
|
|
8
|
-
ListItemText,
|
|
9
|
-
Typography,
|
|
10
|
-
Box,
|
|
11
|
-
IconButtonProps,
|
|
12
|
-
SxProps,
|
|
13
|
-
Divider,
|
|
14
|
-
LinearProgress,
|
|
15
|
-
} from '@mui/material';
|
|
16
|
-
|
|
17
|
-
import { MenuDropdown } from '../droupdown/menu-dropdown';
|
|
18
|
-
import { useDataTableContext } from '../../contexts/data-table-context';
|
|
19
|
-
import { ExcelIcon, CsvIcon } from '../../icons';
|
|
20
|
-
import { getSlotComponent, mergeSlotProps, extractSlotProps } from '../../utils/slot-helpers';
|
|
21
|
-
|
|
22
|
-
interface TableExportControlProps {
|
|
23
|
-
// Optional props to override context defaults
|
|
24
|
-
exportFilename?: string;
|
|
25
|
-
// onServerExport?: (filters?: Partial<TableFilters>, selection?: SelectionState) => Promise<{ data: any[]; total: number }>;
|
|
26
|
-
// onExportProgress?: (progress: { processedRows?: number; totalRows?: number; percentage?: number }) => void;
|
|
27
|
-
// onExportComplete?: (result: { success: boolean; filename: string; totalRows: number }) => void;
|
|
28
|
-
// onExportError?: (error: { message: string; code: string }) => void;
|
|
29
|
-
// Enhanced customization props
|
|
30
|
-
iconButtonProps?: IconButtonProps;
|
|
31
|
-
tooltipProps?: any;
|
|
32
|
-
menuSx?: SxProps;
|
|
33
|
-
menuItemProps?: any;
|
|
34
|
-
[key: string]: any;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function TableExportControl(props: TableExportControlProps = {}) {
|
|
38
|
-
const {
|
|
39
|
-
exportFilename: propsExportFilename,
|
|
40
|
-
iconButtonProps,
|
|
41
|
-
tooltipProps,
|
|
42
|
-
menuSx,
|
|
43
|
-
menuItemProps,
|
|
44
|
-
} = props;
|
|
45
|
-
|
|
46
|
-
const {
|
|
47
|
-
apiRef,
|
|
48
|
-
slots,
|
|
49
|
-
slotProps,
|
|
50
|
-
isExporting,
|
|
51
|
-
exportPhase,
|
|
52
|
-
exportProgress,
|
|
53
|
-
onCancelExport,
|
|
54
|
-
// Export callbacks from context (DataTable props)
|
|
55
|
-
exportFilename: contextExportFilename,
|
|
56
|
-
} = useDataTableContext();
|
|
57
|
-
|
|
58
|
-
// Use props if provided, otherwise fall back to context values
|
|
59
|
-
const exportFilename = propsExportFilename || contextExportFilename || 'export';
|
|
60
|
-
|
|
61
|
-
// Extract slot-specific props with enhanced merging
|
|
62
|
-
const exportIconSlotProps = extractSlotProps(slotProps, 'exportIcon');
|
|
63
|
-
const csvIconSlotProps = extractSlotProps(slotProps, 'csvIcon');
|
|
64
|
-
const excelIconSlotProps = extractSlotProps(slotProps, 'excelIcon');
|
|
65
|
-
|
|
66
|
-
const ExportIconSlot = getSlotComponent(slots, 'exportIcon', CloudDownloadOutlined);
|
|
67
|
-
const CsvIconSlot = getSlotComponent(slots, 'csvIcon', CsvIcon);
|
|
68
|
-
const ExcelIconSlot = getSlotComponent(slots, 'excelIcon', ExcelIcon);
|
|
69
|
-
|
|
70
|
-
const handleExport = async (format: 'csv' | 'excel') => {
|
|
71
|
-
if (!apiRef?.current) return;
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
if (format === 'csv') {
|
|
75
|
-
await apiRef.current.export.exportCSV({
|
|
76
|
-
filename: exportFilename,
|
|
77
|
-
});
|
|
78
|
-
} else {
|
|
79
|
-
await apiRef.current.export.exportExcel({
|
|
80
|
-
filename: exportFilename,
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
} catch (error) {
|
|
84
|
-
console.error('Export failed:', error);
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
const handleCancelExport = () => {
|
|
89
|
-
if (onCancelExport) {
|
|
90
|
-
onCancelExport();
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
apiRef?.current?.export.cancelExport();
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
// Merge all props for maximum flexibility
|
|
97
|
-
const mergedIconButtonProps = mergeSlotProps(
|
|
98
|
-
{
|
|
99
|
-
size: 'small',
|
|
100
|
-
sx: { flexShrink: 0 },
|
|
101
|
-
},
|
|
102
|
-
exportIconSlotProps,
|
|
103
|
-
iconButtonProps || {}
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
const mergedMenuItemProps = mergeSlotProps(
|
|
107
|
-
{
|
|
108
|
-
sx: { minWidth: 150 },
|
|
109
|
-
},
|
|
110
|
-
menuItemProps || {}
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
const progressPercentage = typeof exportProgress?.percentage === 'number'
|
|
114
|
-
? Math.max(0, Math.min(100, exportProgress.percentage))
|
|
115
|
-
: undefined;
|
|
116
|
-
|
|
117
|
-
const getPhaseLabel = () => {
|
|
118
|
-
switch (exportPhase) {
|
|
119
|
-
case 'fetching':
|
|
120
|
-
return 'Fetching rows from server...';
|
|
121
|
-
case 'processing':
|
|
122
|
-
return 'Preparing export file...';
|
|
123
|
-
case 'downloading':
|
|
124
|
-
return 'Downloading file...';
|
|
125
|
-
case 'starting':
|
|
126
|
-
return 'Starting export...';
|
|
127
|
-
default:
|
|
128
|
-
return 'Export in progress...';
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
return (
|
|
133
|
-
<MenuDropdown
|
|
134
|
-
anchor={(
|
|
135
|
-
<Tooltip
|
|
136
|
-
title={isExporting ? 'Export in progress...' : 'Export data'}
|
|
137
|
-
{...tooltipProps}
|
|
138
|
-
>
|
|
139
|
-
<IconButton
|
|
140
|
-
{...mergedIconButtonProps}
|
|
141
|
-
>
|
|
142
|
-
<ExportIconSlot {...exportIconSlotProps} />
|
|
143
|
-
</IconButton>
|
|
144
|
-
</Tooltip>
|
|
145
|
-
)}
|
|
146
|
-
>
|
|
147
|
-
{({ handleClose }: { handleClose: () => void }) => (
|
|
148
|
-
<Box
|
|
149
|
-
sx={{
|
|
150
|
-
minWidth: 200,
|
|
151
|
-
...menuSx,
|
|
152
|
-
}}
|
|
153
|
-
>
|
|
154
|
-
<Typography
|
|
155
|
-
variant="subtitle2"
|
|
156
|
-
sx={{ p: 2, pb: 1 }}
|
|
157
|
-
>
|
|
158
|
-
Export Format
|
|
159
|
-
</Typography>
|
|
160
|
-
|
|
161
|
-
<MenuItem
|
|
162
|
-
onClick={() => {
|
|
163
|
-
handleExport('csv');
|
|
164
|
-
}}
|
|
165
|
-
disabled={isExporting}
|
|
166
|
-
{...mergedMenuItemProps}
|
|
167
|
-
>
|
|
168
|
-
<ListItemIcon>
|
|
169
|
-
<CsvIconSlot {...csvIconSlotProps} />
|
|
170
|
-
</ListItemIcon>
|
|
171
|
-
<ListItemText
|
|
172
|
-
primary="CSV"
|
|
173
|
-
secondary="Comma-separated values"
|
|
174
|
-
/>
|
|
175
|
-
</MenuItem>
|
|
176
|
-
|
|
177
|
-
<MenuItem
|
|
178
|
-
onClick={() => {
|
|
179
|
-
handleExport('excel');
|
|
180
|
-
}}
|
|
181
|
-
disabled={isExporting}
|
|
182
|
-
{...mergedMenuItemProps}
|
|
183
|
-
>
|
|
184
|
-
<ListItemIcon>
|
|
185
|
-
<ExcelIconSlot {...excelIconSlotProps} />
|
|
186
|
-
</ListItemIcon>
|
|
187
|
-
<ListItemText
|
|
188
|
-
primary="Excel"
|
|
189
|
-
secondary="Microsoft Excel format"
|
|
190
|
-
/>
|
|
191
|
-
</MenuItem>
|
|
192
|
-
|
|
193
|
-
{isExporting && (
|
|
194
|
-
<>
|
|
195
|
-
<Box sx={{ px: 2, pb: 1 }}>
|
|
196
|
-
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', mb: 0.75 }}>
|
|
197
|
-
{getPhaseLabel()}
|
|
198
|
-
</Typography>
|
|
199
|
-
<LinearProgress
|
|
200
|
-
variant={progressPercentage !== undefined ? 'determinate' : 'indeterminate'}
|
|
201
|
-
value={progressPercentage !== undefined ? progressPercentage : 0}
|
|
202
|
-
/>
|
|
203
|
-
{(exportProgress?.processedRows !== undefined || exportProgress?.totalRows !== undefined) && (
|
|
204
|
-
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', mt: 0.75 }}>
|
|
205
|
-
{`${exportProgress?.processedRows ?? 0}${exportProgress?.totalRows !== undefined ? ` / ${exportProgress.totalRows}` : ''}${progressPercentage !== undefined ? ` (${progressPercentage}%)` : ''}`}
|
|
206
|
-
</Typography>
|
|
207
|
-
)}
|
|
208
|
-
</Box>
|
|
209
|
-
<Divider sx={{ my: 1 }} />
|
|
210
|
-
<MenuItem
|
|
211
|
-
onClick={() => {
|
|
212
|
-
handleCancelExport();
|
|
213
|
-
handleClose();
|
|
214
|
-
}}
|
|
215
|
-
{...mergedMenuItemProps}
|
|
216
|
-
>
|
|
217
|
-
<ListItemText
|
|
218
|
-
primary="Cancel Export"
|
|
219
|
-
secondary="Stop current export job"
|
|
220
|
-
slotProps={{
|
|
221
|
-
primary: {
|
|
222
|
-
color: 'error.main',
|
|
223
|
-
},
|
|
224
|
-
}}
|
|
225
|
-
/>
|
|
226
|
-
</MenuItem>
|
|
227
|
-
</>
|
|
228
|
-
)}
|
|
229
|
-
</Box>
|
|
230
|
-
)}
|
|
231
|
-
</MenuDropdown>
|
|
232
|
-
);
|
|
233
|
-
}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import React, { ReactElement, useCallback } from 'react';
|
|
2
|
-
import { Refresh } from '@mui/icons-material';
|
|
3
|
-
import { IconButton, Tooltip, IconButtonProps, CircularProgress } from '@mui/material';
|
|
4
|
-
|
|
5
|
-
import { useDataTableContext } from '../../contexts/data-table-context';
|
|
6
|
-
import { extractSlotProps, getSlotComponent, mergeSlotProps } from '../../utils/slot-helpers';
|
|
7
|
-
|
|
8
|
-
export interface TableRefreshControlProps {
|
|
9
|
-
iconButtonProps?: IconButtonProps;
|
|
10
|
-
tooltipProps?: any;
|
|
11
|
-
|
|
12
|
-
/** optional override */
|
|
13
|
-
onRefresh?: () => void | Promise<void>;
|
|
14
|
-
|
|
15
|
-
/** disable + show spinner if true */
|
|
16
|
-
loading?: boolean;
|
|
17
|
-
|
|
18
|
-
/** use spinner instead of icon while loading */
|
|
19
|
-
showSpinnerWhileLoading?: boolean;
|
|
20
|
-
|
|
21
|
-
[key: string]: any;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function TableRefreshControl(props: TableRefreshControlProps = {}): ReactElement {
|
|
25
|
-
const { apiRef, slots, slotProps } = useDataTableContext();
|
|
26
|
-
|
|
27
|
-
const refreshIconSlotProps = extractSlotProps(slotProps, 'refreshIcon');
|
|
28
|
-
const RefreshIconSlot = getSlotComponent(slots, 'refreshIcon', Refresh);
|
|
29
|
-
|
|
30
|
-
const handleRefresh = useCallback(() => {
|
|
31
|
-
if (props.onRefresh) return props.onRefresh();
|
|
32
|
-
// Default: use internal api
|
|
33
|
-
apiRef?.current?.data?.reload?.();
|
|
34
|
-
}, [props, apiRef]);
|
|
35
|
-
|
|
36
|
-
const mergedIconButtonProps = mergeSlotProps(
|
|
37
|
-
{
|
|
38
|
-
size: 'small',
|
|
39
|
-
onClick: handleRefresh,
|
|
40
|
-
disabled: !!props.loading,
|
|
41
|
-
sx: { flexShrink: 0 },
|
|
42
|
-
},
|
|
43
|
-
refreshIconSlotProps,
|
|
44
|
-
props.iconButtonProps || {}
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
// Wrap in span so when IconButton is disabled (loading), the tooltip still
|
|
48
|
-
// receives pointer events and closes on mouse leave (disabled elements don't fire them).
|
|
49
|
-
return (
|
|
50
|
-
<Tooltip title="Refresh data" {...props.tooltipProps}>
|
|
51
|
-
<span style={{ display: 'inline-flex' }}>
|
|
52
|
-
<IconButton {...mergedIconButtonProps}>
|
|
53
|
-
{props.loading && props.showSpinnerWhileLoading ? (
|
|
54
|
-
<CircularProgress size={16} />
|
|
55
|
-
) : (
|
|
56
|
-
<RefreshIconSlot {...refreshIconSlotProps} />
|
|
57
|
-
)}
|
|
58
|
-
</IconButton>
|
|
59
|
-
</span>
|
|
60
|
-
</Tooltip>
|
|
61
|
-
);
|
|
62
|
-
}
|