@etsoo/materialui 1.1.91 → 1.1.93
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/lib/DataGridEx.js +3 -2
- package/lib/TableEx.d.ts +5 -5
- package/lib/TableEx.js +23 -18
- package/package.json +5 -5
- package/src/DataGridEx.tsx +4 -2
- package/src/TableEx.tsx +494 -519
package/lib/DataGridEx.js
CHANGED
|
@@ -218,7 +218,7 @@ export function DataGridEx(props) {
|
|
|
218
218
|
/**
|
|
219
219
|
* Item renderer
|
|
220
220
|
*/
|
|
221
|
-
const itemRenderer = ({ columnIndex, rowIndex, style, data, selectedItems }) => {
|
|
221
|
+
const itemRenderer = ({ columnIndex, rowIndex, style, data, selectedItems, setItems }) => {
|
|
222
222
|
// Column
|
|
223
223
|
const { align, cellRenderer = DataGridRenderers.defaultCellRenderer, cellBoxStyle, field, type, valueFormatter, renderProps } = columns[columnIndex];
|
|
224
224
|
// Props
|
|
@@ -261,7 +261,8 @@ export function DataGridEx(props) {
|
|
|
261
261
|
rowIndex,
|
|
262
262
|
columnIndex,
|
|
263
263
|
cellProps,
|
|
264
|
-
renderProps
|
|
264
|
+
renderProps,
|
|
265
|
+
setItems
|
|
265
266
|
});
|
|
266
267
|
return (React.createElement("div", { className: rowClass, style: style, "data-row": rowIndex, "data-column": columnIndex, onMouseDown: selectable && !checkable ? handleMouseDown : undefined, onMouseOver: selectable ? handleMouseOver : undefined, onMouseOut: selectable ? handleMouseOut : undefined, onClick: (event) => onClick && data != null && onClick(event, data), onDoubleClick: (event) => onDoubleClick && data != null && onDoubleClick(event, data) },
|
|
267
268
|
React.createElement(Box, { ...cellProps, onMouseEnter: handleMouseEnter }, child)));
|
package/lib/TableEx.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { GridColumn, GridLoader } from
|
|
2
|
-
import { GridMethodRef } from
|
|
3
|
-
import { DataTypes, IdDefaultType } from
|
|
4
|
-
import { TableProps } from
|
|
5
|
-
import React from
|
|
1
|
+
import { GridColumn, GridLoader } from "@etsoo/react";
|
|
2
|
+
import { GridMethodRef } from "@etsoo/react/lib/components/GridMethodRef";
|
|
3
|
+
import { DataTypes, IdDefaultType } from "@etsoo/shared";
|
|
4
|
+
import { TableProps } from "@mui/material";
|
|
5
|
+
import React from "react";
|
|
6
6
|
/**
|
|
7
7
|
* Extended table min width for width-unset column
|
|
8
8
|
*/
|
package/lib/TableEx.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { GridAlignGet, GridSizeGet } from
|
|
2
|
-
import { DataTypes } from
|
|
3
|
-
import { Checkbox, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TablePagination, TableRow, TableSortLabel, useTheme } from
|
|
4
|
-
import React from
|
|
5
|
-
import { DataGridRenderers } from
|
|
1
|
+
import { GridAlignGet, GridSizeGet } from "@etsoo/react";
|
|
2
|
+
import { DataTypes } from "@etsoo/shared";
|
|
3
|
+
import { Checkbox, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TablePagination, TableRow, TableSortLabel, useTheme } from "@mui/material";
|
|
4
|
+
import React from "react";
|
|
5
|
+
import { DataGridRenderers } from "./DataGridRenderers";
|
|
6
6
|
/**
|
|
7
7
|
* Extended table min width for width-unset column
|
|
8
8
|
*/
|
|
@@ -17,7 +17,7 @@ export function TableEx(props) {
|
|
|
17
17
|
// Theme
|
|
18
18
|
const theme = useTheme();
|
|
19
19
|
// Destruct
|
|
20
|
-
const { alternatingColors = [theme.palette.action.hover, undefined], autoLoad = true, columns, defaultOrderBy, headerColors = [undefined, undefined], idField =
|
|
20
|
+
const { alternatingColors = [theme.palette.action.hover, undefined], autoLoad = true, columns, defaultOrderBy, headerColors = [undefined, undefined], idField = "id", loadBatchSize, loadData, maxHeight, mRef, onSelectChange, rowHeight = 53, otherHeight = 110, threshold, ...rest } = props;
|
|
21
21
|
const selectable = onSelectChange != null;
|
|
22
22
|
// Rows per page
|
|
23
23
|
let rowsPerPageLocal;
|
|
@@ -27,7 +27,7 @@ export function TableEx(props) {
|
|
|
27
27
|
else
|
|
28
28
|
rowsPerPageLocal = Math.floor((maxHeight - otherHeight) / rowHeight);
|
|
29
29
|
}
|
|
30
|
-
else if (typeof loadBatchSize ===
|
|
30
|
+
else if (typeof loadBatchSize === "number") {
|
|
31
31
|
rowsPerPageLocal = loadBatchSize;
|
|
32
32
|
}
|
|
33
33
|
else {
|
|
@@ -153,6 +153,13 @@ export function TableEx(props) {
|
|
|
153
153
|
const handleSort = (field, asc) => {
|
|
154
154
|
reset({ orderBy: field, orderByAsc: asc });
|
|
155
155
|
};
|
|
156
|
+
// Set items for rerenderer
|
|
157
|
+
const setItems = (callback) => {
|
|
158
|
+
const result = callback(rows);
|
|
159
|
+
if (result == null)
|
|
160
|
+
return;
|
|
161
|
+
setRows(result);
|
|
162
|
+
};
|
|
156
163
|
// Destruct states
|
|
157
164
|
const { autoLoad: stateAutoLoad, currentPage, hasNextPage, lastLoadedItems, orderBy, batchSize, selectedItems } = state;
|
|
158
165
|
// Current page selected items
|
|
@@ -181,14 +188,13 @@ export function TableEx(props) {
|
|
|
181
188
|
React.createElement(Table, { ...rest },
|
|
182
189
|
React.createElement(TableHead, null,
|
|
183
190
|
React.createElement(TableRow, { sx: {
|
|
184
|
-
|
|
191
|
+
"& th": {
|
|
185
192
|
backgroundColor: headerColors[0],
|
|
186
193
|
color: headerColors[1]
|
|
187
194
|
}
|
|
188
195
|
} },
|
|
189
196
|
selectable && (React.createElement(TableCell, { padding: "checkbox" },
|
|
190
|
-
React.createElement(Checkbox, { color: "primary", indeterminate: pageSelectedItems > 0 &&
|
|
191
|
-
pageSelectedItems < rows.length, checked: pageSelectedItems > 0, onChange: (_event, checked) => handleSelectAll(checked) }))),
|
|
197
|
+
React.createElement(Checkbox, { color: "primary", indeterminate: pageSelectedItems > 0 && pageSelectedItems < rows.length, checked: pageSelectedItems > 0, onChange: (_event, checked) => handleSelectAll(checked) }))),
|
|
192
198
|
columns.map((column, index) => {
|
|
193
199
|
// Destruct
|
|
194
200
|
const { align, field, header, minWidth, sortable, sortAsc = true, type, width } = column;
|
|
@@ -198,7 +204,7 @@ export function TableEx(props) {
|
|
|
198
204
|
let sortLabel;
|
|
199
205
|
if (sortable && field != null) {
|
|
200
206
|
const active = orderBy === field;
|
|
201
|
-
sortLabel = (React.createElement(TableSortLabel, { active: active, direction: sortAsc ?
|
|
207
|
+
sortLabel = (React.createElement(TableSortLabel, { active: active, direction: sortAsc ? "asc" : "desc", onClick: (_event) => {
|
|
202
208
|
if (active)
|
|
203
209
|
column.sortAsc = !sortAsc;
|
|
204
210
|
handleSort(field, column.sortAsc);
|
|
@@ -216,18 +222,16 @@ export function TableEx(props) {
|
|
|
216
222
|
} }, sortLabel));
|
|
217
223
|
}))),
|
|
218
224
|
React.createElement(TableBody, { sx: {
|
|
219
|
-
|
|
225
|
+
"& tr:nth-of-type(odd):not(.Mui-selected)": {
|
|
220
226
|
backgroundColor: alternatingColors[0]
|
|
221
227
|
},
|
|
222
|
-
|
|
228
|
+
"& tr:nth-of-type(even):not(.Mui-selected)": {
|
|
223
229
|
backgroundColor: alternatingColors[1]
|
|
224
230
|
}
|
|
225
231
|
} }, [...Array(batchSize)].map((_item, rowIndex) => {
|
|
226
232
|
var _a;
|
|
227
233
|
// Row
|
|
228
|
-
const row = rowIndex < rows.length
|
|
229
|
-
? rows[rowIndex]
|
|
230
|
-
: undefined;
|
|
234
|
+
const row = rowIndex < rows.length ? rows[rowIndex] : undefined;
|
|
231
235
|
// Row id field value
|
|
232
236
|
const rowId = (_a = DataTypes.getValue(row, idField)) !== null && _a !== void 0 ? _a : rowIndex;
|
|
233
237
|
// Selected or not
|
|
@@ -245,7 +249,7 @@ export function TableEx(props) {
|
|
|
245
249
|
};
|
|
246
250
|
const cellProps = {
|
|
247
251
|
align: GridAlignGet(align, type),
|
|
248
|
-
valign:
|
|
252
|
+
valign: "middle"
|
|
249
253
|
};
|
|
250
254
|
const child = row ? (cellRenderer({
|
|
251
255
|
data: row,
|
|
@@ -257,7 +261,8 @@ export function TableEx(props) {
|
|
|
257
261
|
type,
|
|
258
262
|
rowIndex,
|
|
259
263
|
columnIndex,
|
|
260
|
-
cellProps
|
|
264
|
+
cellProps,
|
|
265
|
+
setItems
|
|
261
266
|
})) : (React.createElement(React.Fragment, null, "\u00A0"));
|
|
262
267
|
return (React.createElement(TableCell, { key: `${rowId}${columnIndex}`, ...cellProps }, child));
|
|
263
268
|
})));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/materialui",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.93",
|
|
4
4
|
"description": "TypeScript Material-UI Implementation",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -50,10 +50,10 @@
|
|
|
50
50
|
"@emotion/css": "^11.10.6",
|
|
51
51
|
"@emotion/react": "^11.10.6",
|
|
52
52
|
"@emotion/styled": "^11.10.6",
|
|
53
|
-
"@etsoo/appscript": "^1.3.
|
|
53
|
+
"@etsoo/appscript": "^1.3.89",
|
|
54
54
|
"@etsoo/notificationbase": "^1.1.24",
|
|
55
|
-
"@etsoo/react": "^1.6.
|
|
56
|
-
"@etsoo/shared": "^1.1.
|
|
55
|
+
"@etsoo/react": "^1.6.61",
|
|
56
|
+
"@etsoo/shared": "^1.1.99",
|
|
57
57
|
"@mui/icons-material": "^5.11.16",
|
|
58
58
|
"@mui/material": "^5.11.16",
|
|
59
59
|
"@mui/x-data-grid": "^6.0.4",
|
|
@@ -89,6 +89,6 @@
|
|
|
89
89
|
"@typescript-eslint/parser": "^5.57.1",
|
|
90
90
|
"jest": "^29.5.0",
|
|
91
91
|
"jest-environment-jsdom": "^29.5.0",
|
|
92
|
-
"typescript": "^5.0.
|
|
92
|
+
"typescript": "^5.0.4"
|
|
93
93
|
}
|
|
94
94
|
}
|
package/src/DataGridEx.tsx
CHANGED
|
@@ -498,7 +498,8 @@ export function DataGridEx<
|
|
|
498
498
|
rowIndex,
|
|
499
499
|
style,
|
|
500
500
|
data,
|
|
501
|
-
selectedItems
|
|
501
|
+
selectedItems,
|
|
502
|
+
setItems
|
|
502
503
|
}: ScrollerGridItemRendererProps<T>) => {
|
|
503
504
|
// Column
|
|
504
505
|
const {
|
|
@@ -564,7 +565,8 @@ export function DataGridEx<
|
|
|
564
565
|
rowIndex,
|
|
565
566
|
columnIndex,
|
|
566
567
|
cellProps,
|
|
567
|
-
renderProps
|
|
568
|
+
renderProps,
|
|
569
|
+
setItems
|
|
568
570
|
});
|
|
569
571
|
|
|
570
572
|
return (
|
package/src/TableEx.tsx
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
} from
|
|
10
|
-
import { GridMethodRef } from
|
|
11
|
-
import { DataTypes, IdDefaultType } from
|
|
2
|
+
GridAlignGet,
|
|
3
|
+
GridCellFormatterProps,
|
|
4
|
+
GridColumn,
|
|
5
|
+
GridLoadDataProps,
|
|
6
|
+
GridLoader,
|
|
7
|
+
GridLoaderStates,
|
|
8
|
+
GridSizeGet
|
|
9
|
+
} from "@etsoo/react";
|
|
10
|
+
import { GridMethodRef } from "@etsoo/react/lib/components/GridMethodRef";
|
|
11
|
+
import { DataTypes, IdDefaultType } from "@etsoo/shared";
|
|
12
12
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
} from
|
|
27
|
-
import React from
|
|
28
|
-
import { DataGridRenderers } from
|
|
13
|
+
Checkbox,
|
|
14
|
+
Paper,
|
|
15
|
+
Table,
|
|
16
|
+
TableBody,
|
|
17
|
+
TableCell,
|
|
18
|
+
TableCellProps,
|
|
19
|
+
TableContainer,
|
|
20
|
+
TableHead,
|
|
21
|
+
TablePagination,
|
|
22
|
+
TableProps,
|
|
23
|
+
TableRow,
|
|
24
|
+
TableSortLabel,
|
|
25
|
+
useTheme
|
|
26
|
+
} from "@mui/material";
|
|
27
|
+
import React from "react";
|
|
28
|
+
import { DataGridRenderers } from "./DataGridRenderers";
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Extended table min width for width-unset column
|
|
@@ -36,65 +36,65 @@ export const TableExMinWidth: number = 180;
|
|
|
36
36
|
* Extended table methods ref
|
|
37
37
|
*/
|
|
38
38
|
export interface TableExMethodRef<T> extends GridMethodRef<T> {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Refresh data
|
|
41
|
+
*/
|
|
42
|
+
refresh(): void;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
46
|
* Extended table props
|
|
47
47
|
*/
|
|
48
48
|
export type TableExProps<
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
T extends object,
|
|
50
|
+
D extends DataTypes.Keys<T>
|
|
51
51
|
> = TableProps &
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
52
|
+
GridLoader<T> & {
|
|
53
|
+
/**
|
|
54
|
+
* Alternating colors for odd/even rows
|
|
55
|
+
*/
|
|
56
|
+
alternatingColors?: [string?, string?];
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Columns
|
|
60
|
+
*/
|
|
61
|
+
columns: GridColumn<T>[];
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Header cells background color and font color
|
|
65
|
+
*/
|
|
66
|
+
headerColors?: [string?, string?];
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Id field
|
|
70
|
+
*/
|
|
71
|
+
idField?: D;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Max height
|
|
75
|
+
*/
|
|
76
|
+
maxHeight?: number;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Methods
|
|
80
|
+
*/
|
|
81
|
+
mRef?: React.Ref<TableExMethodRef<T>>;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* On items select change
|
|
85
|
+
*/
|
|
86
|
+
onSelectChange?: (selectedItems: T[]) => void;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Row height
|
|
90
|
+
*/
|
|
91
|
+
rowHeight?: number;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Header and bottom height
|
|
95
|
+
*/
|
|
96
|
+
otherHeight?: number;
|
|
97
|
+
};
|
|
98
98
|
|
|
99
99
|
/**
|
|
100
100
|
* Extended Table
|
|
@@ -102,458 +102,433 @@ export type TableExProps<
|
|
|
102
102
|
* @returns Component
|
|
103
103
|
*/
|
|
104
104
|
export function TableEx<
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
T extends object,
|
|
106
|
+
D extends DataTypes.Keys<T> = IdDefaultType<T>
|
|
107
107
|
>(props: TableExProps<T, D>) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
isNextPageLoading: false,
|
|
179
|
-
lastLoadedItems: undefined,
|
|
180
|
-
...add
|
|
181
|
-
};
|
|
182
|
-
Object.assign(state, resetState);
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
React.useImperativeHandle(
|
|
186
|
-
mRef,
|
|
187
|
-
() => ({
|
|
188
|
-
/**
|
|
189
|
-
* Refresh data
|
|
190
|
-
*/
|
|
191
|
-
refresh(): void {
|
|
192
|
-
loadDataLocal();
|
|
193
|
-
},
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Reset
|
|
197
|
-
*/
|
|
198
|
-
reset
|
|
199
|
-
}),
|
|
200
|
-
[]
|
|
201
|
-
);
|
|
202
|
-
|
|
203
|
-
// Load data
|
|
204
|
-
const loadDataLocal = () => {
|
|
205
|
-
// Prevent multiple loadings
|
|
206
|
-
if (!state.hasNextPage || state.isNextPageLoading) return;
|
|
207
|
-
|
|
208
|
-
// Update state
|
|
209
|
-
state.isNextPageLoading = true;
|
|
210
|
-
|
|
211
|
-
// Parameters
|
|
212
|
-
const { currentPage, batchSize, orderBy, orderByAsc, data, isMounted } =
|
|
213
|
-
state;
|
|
214
|
-
|
|
215
|
-
const loadProps: GridLoadDataProps = {
|
|
216
|
-
currentPage,
|
|
217
|
-
batchSize,
|
|
218
|
-
orderBy,
|
|
219
|
-
orderByAsc,
|
|
220
|
-
data
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
loadData(loadProps).then((result) => {
|
|
224
|
-
state.isMounted = true;
|
|
225
|
-
if (result == null || isMounted === false) {
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const newItems = result.length;
|
|
230
|
-
state.lastLoadedItems = newItems;
|
|
231
|
-
state.hasNextPage = newItems >= batchSize;
|
|
232
|
-
state.isNextPageLoading = false;
|
|
233
|
-
|
|
234
|
-
// Update rows
|
|
235
|
-
setRows(result);
|
|
236
|
-
});
|
|
108
|
+
// Theme
|
|
109
|
+
const theme = useTheme();
|
|
110
|
+
|
|
111
|
+
// Destruct
|
|
112
|
+
const {
|
|
113
|
+
alternatingColors = [theme.palette.action.hover, undefined],
|
|
114
|
+
autoLoad = true,
|
|
115
|
+
columns,
|
|
116
|
+
defaultOrderBy,
|
|
117
|
+
headerColors = [undefined, undefined],
|
|
118
|
+
idField = "id" as D,
|
|
119
|
+
loadBatchSize,
|
|
120
|
+
loadData,
|
|
121
|
+
maxHeight,
|
|
122
|
+
mRef,
|
|
123
|
+
onSelectChange,
|
|
124
|
+
rowHeight = 53,
|
|
125
|
+
otherHeight = 110,
|
|
126
|
+
threshold,
|
|
127
|
+
...rest
|
|
128
|
+
} = props;
|
|
129
|
+
|
|
130
|
+
const selectable: boolean = onSelectChange != null;
|
|
131
|
+
|
|
132
|
+
// Rows per page
|
|
133
|
+
let rowsPerPageLocal: number;
|
|
134
|
+
if (maxHeight != null) {
|
|
135
|
+
if (loadBatchSize != null)
|
|
136
|
+
rowsPerPageLocal = GridSizeGet(loadBatchSize, maxHeight);
|
|
137
|
+
else rowsPerPageLocal = Math.floor((maxHeight - otherHeight) / rowHeight);
|
|
138
|
+
} else if (typeof loadBatchSize === "number") {
|
|
139
|
+
rowsPerPageLocal = loadBatchSize;
|
|
140
|
+
} else {
|
|
141
|
+
rowsPerPageLocal = 10;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Rows
|
|
145
|
+
const [rows, updateRows] = React.useState<T[]>([]);
|
|
146
|
+
const setRows = (rows: T[]) => {
|
|
147
|
+
state.loadedItems = rows.length;
|
|
148
|
+
updateRows(rows);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// States
|
|
152
|
+
const stateRefs = React.useRef<GridLoaderStates<T>>({
|
|
153
|
+
autoLoad,
|
|
154
|
+
currentPage: 0,
|
|
155
|
+
loadedItems: 0,
|
|
156
|
+
hasNextPage: true,
|
|
157
|
+
isNextPageLoading: false,
|
|
158
|
+
orderBy: defaultOrderBy,
|
|
159
|
+
orderByAsc: defaultOrderBy
|
|
160
|
+
? columns.find((column) => column.field === defaultOrderBy)?.sortAsc
|
|
161
|
+
: undefined,
|
|
162
|
+
batchSize: rowsPerPageLocal,
|
|
163
|
+
selectedItems: [],
|
|
164
|
+
idCache: {}
|
|
165
|
+
});
|
|
166
|
+
const state = stateRefs.current;
|
|
167
|
+
|
|
168
|
+
// Reset the state and load again
|
|
169
|
+
const reset = (add?: Partial<GridLoaderStates<T>>) => {
|
|
170
|
+
const resetState: Partial<GridLoaderStates<T>> = {
|
|
171
|
+
autoLoad: true,
|
|
172
|
+
currentPage: 0,
|
|
173
|
+
loadedItems: 0,
|
|
174
|
+
hasNextPage: true,
|
|
175
|
+
isNextPageLoading: false,
|
|
176
|
+
lastLoadedItems: undefined,
|
|
177
|
+
...add
|
|
237
178
|
};
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
179
|
+
Object.assign(state, resetState);
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
React.useImperativeHandle(
|
|
183
|
+
mRef,
|
|
184
|
+
() => ({
|
|
185
|
+
/**
|
|
186
|
+
* Refresh data
|
|
187
|
+
*/
|
|
188
|
+
refresh(): void {
|
|
242
189
|
loadDataLocal();
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Reset
|
|
194
|
+
*/
|
|
195
|
+
reset
|
|
196
|
+
}),
|
|
197
|
+
[]
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
// Load data
|
|
201
|
+
const loadDataLocal = () => {
|
|
202
|
+
// Prevent multiple loadings
|
|
203
|
+
if (!state.hasNextPage || state.isNextPageLoading) return;
|
|
204
|
+
|
|
205
|
+
// Update state
|
|
206
|
+
state.isNextPageLoading = true;
|
|
207
|
+
|
|
208
|
+
// Parameters
|
|
209
|
+
const { currentPage, batchSize, orderBy, orderByAsc, data, isMounted } =
|
|
210
|
+
state;
|
|
211
|
+
|
|
212
|
+
const loadProps: GridLoadDataProps = {
|
|
213
|
+
currentPage,
|
|
214
|
+
batchSize,
|
|
215
|
+
orderBy,
|
|
216
|
+
orderByAsc,
|
|
217
|
+
data
|
|
243
218
|
};
|
|
244
219
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
const handleSelect = (item: T, checked: Boolean) => {
|
|
253
|
-
const selectedItems = state.selectedItems;
|
|
254
|
-
|
|
255
|
-
const index = selectedItems.findIndex(
|
|
256
|
-
(selectedItem) => selectedItem[idField] === item[idField]
|
|
257
|
-
);
|
|
258
|
-
if (checked) {
|
|
259
|
-
if (index === -1) selectedItems.push(item);
|
|
260
|
-
} else {
|
|
261
|
-
if (index !== -1) selectedItems.splice(index, 1);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
if (onSelectChange != null) {
|
|
265
|
-
onSelectChange(selectedItems);
|
|
266
|
-
}
|
|
267
|
-
};
|
|
220
|
+
loadData(loadProps).then((result) => {
|
|
221
|
+
state.isMounted = true;
|
|
222
|
+
if (result == null || isMounted === false) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
268
225
|
|
|
269
|
-
|
|
270
|
-
|
|
226
|
+
const newItems = result.length;
|
|
227
|
+
state.lastLoadedItems = newItems;
|
|
228
|
+
state.hasNextPage = newItems >= batchSize;
|
|
229
|
+
state.isNextPageLoading = false;
|
|
271
230
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
231
|
+
// Update rows
|
|
232
|
+
setRows(result);
|
|
233
|
+
});
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const handleChangePage = (_event: unknown, newPage: number) => {
|
|
237
|
+
state.hasNextPage = true;
|
|
238
|
+
state.currentPage = newPage;
|
|
239
|
+
loadDataLocal();
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const handleChangeRowsPerPage = (
|
|
243
|
+
event: React.ChangeEvent<HTMLInputElement>
|
|
244
|
+
) => {
|
|
245
|
+
const batchSize = parseInt(event.target.value);
|
|
246
|
+
reset({ batchSize });
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const handleSelect = (item: T, checked: Boolean) => {
|
|
250
|
+
const selectedItems = state.selectedItems;
|
|
251
|
+
|
|
252
|
+
const index = selectedItems.findIndex(
|
|
253
|
+
(selectedItem) => selectedItem[idField] === item[idField]
|
|
254
|
+
);
|
|
255
|
+
if (checked) {
|
|
256
|
+
if (index === -1) selectedItems.push(item);
|
|
257
|
+
} else {
|
|
258
|
+
if (index !== -1) selectedItems.splice(index, 1);
|
|
259
|
+
}
|
|
276
260
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
282
|
-
});
|
|
261
|
+
if (onSelectChange != null) {
|
|
262
|
+
onSelectChange(selectedItems);
|
|
263
|
+
}
|
|
264
|
+
};
|
|
283
265
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
}
|
|
287
|
-
};
|
|
266
|
+
const handleSelectAll = (checked: boolean) => {
|
|
267
|
+
const selectedItems = state.selectedItems;
|
|
288
268
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
269
|
+
rows.forEach((row) => {
|
|
270
|
+
const index = selectedItems.findIndex(
|
|
271
|
+
(selectedItem) => selectedItem[idField] === row[idField]
|
|
272
|
+
);
|
|
293
273
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
orderBy,
|
|
301
|
-
batchSize,
|
|
302
|
-
selectedItems
|
|
303
|
-
} = state;
|
|
304
|
-
|
|
305
|
-
// Current page selected items
|
|
306
|
-
const pageSelectedItems = selectable
|
|
307
|
-
? rows.reduce((previousValue, currentItem) => {
|
|
308
|
-
if (
|
|
309
|
-
selectedItems.some(
|
|
310
|
-
(item) => item[idField] === currentItem[idField]
|
|
311
|
-
)
|
|
312
|
-
)
|
|
313
|
-
return previousValue + 1;
|
|
314
|
-
|
|
315
|
-
return previousValue;
|
|
316
|
-
}, 0)
|
|
317
|
-
: 0;
|
|
318
|
-
|
|
319
|
-
// Total rows
|
|
320
|
-
const totalRows = hasNextPage
|
|
321
|
-
? -1
|
|
322
|
-
: currentPage * batchSize + (lastLoadedItems ?? 0);
|
|
323
|
-
|
|
324
|
-
// Auto load data when current page is 0
|
|
325
|
-
if (currentPage === 0 && stateAutoLoad && lastLoadedItems == null)
|
|
326
|
-
loadDataLocal();
|
|
274
|
+
if (checked) {
|
|
275
|
+
if (index === -1) selectedItems.push(row);
|
|
276
|
+
} else if (index !== -1) {
|
|
277
|
+
selectedItems.splice(index, 1);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
327
280
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
281
|
+
if (onSelectChange != null) {
|
|
282
|
+
onSelectChange(selectedItems);
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
// New sort
|
|
287
|
+
const handleSort = (field: string, asc?: boolean) => {
|
|
288
|
+
reset({ orderBy: field, orderByAsc: asc });
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
// Set items for rerenderer
|
|
292
|
+
const setItems = (callback: (items: T[]) => T[] | undefined) => {
|
|
293
|
+
const result = callback(rows);
|
|
294
|
+
if (result == null) return;
|
|
295
|
+
setRows(result);
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
// Destruct states
|
|
299
|
+
const {
|
|
300
|
+
autoLoad: stateAutoLoad,
|
|
301
|
+
currentPage,
|
|
302
|
+
hasNextPage,
|
|
303
|
+
lastLoadedItems,
|
|
304
|
+
orderBy,
|
|
305
|
+
batchSize,
|
|
306
|
+
selectedItems
|
|
307
|
+
} = state;
|
|
308
|
+
|
|
309
|
+
// Current page selected items
|
|
310
|
+
const pageSelectedItems = selectable
|
|
311
|
+
? rows.reduce((previousValue, currentItem) => {
|
|
312
|
+
if (
|
|
313
|
+
selectedItems.some((item) => item[idField] === currentItem[idField])
|
|
314
|
+
)
|
|
315
|
+
return previousValue + 1;
|
|
316
|
+
|
|
317
|
+
return previousValue;
|
|
318
|
+
}, 0)
|
|
319
|
+
: 0;
|
|
320
|
+
|
|
321
|
+
// Total rows
|
|
322
|
+
const totalRows = hasNextPage
|
|
323
|
+
? -1
|
|
324
|
+
: currentPage * batchSize + (lastLoadedItems ?? 0);
|
|
325
|
+
|
|
326
|
+
// Auto load data when current page is 0
|
|
327
|
+
if (currentPage === 0 && stateAutoLoad && lastLoadedItems == null)
|
|
328
|
+
loadDataLocal();
|
|
329
|
+
|
|
330
|
+
React.useEffect(() => {
|
|
331
|
+
return () => {
|
|
332
|
+
state.isMounted = false;
|
|
333
|
+
};
|
|
334
|
+
}, []);
|
|
335
|
+
|
|
336
|
+
// Layout
|
|
337
|
+
return (
|
|
338
|
+
<Paper>
|
|
339
|
+
<TableContainer sx={{ maxHeight }}>
|
|
340
|
+
<Table {...rest}>
|
|
341
|
+
<TableHead>
|
|
342
|
+
<TableRow
|
|
343
|
+
sx={{
|
|
344
|
+
"& th": {
|
|
345
|
+
backgroundColor: headerColors[0],
|
|
346
|
+
color: headerColors[1]
|
|
347
|
+
}
|
|
348
|
+
}}
|
|
349
|
+
>
|
|
350
|
+
{selectable && (
|
|
351
|
+
<TableCell padding="checkbox">
|
|
352
|
+
<Checkbox
|
|
353
|
+
color="primary"
|
|
354
|
+
indeterminate={
|
|
355
|
+
pageSelectedItems > 0 && pageSelectedItems < rows.length
|
|
356
|
+
}
|
|
357
|
+
checked={pageSelectedItems > 0}
|
|
358
|
+
onChange={(_event, checked) => handleSelectAll(checked)}
|
|
359
|
+
/>
|
|
360
|
+
</TableCell>
|
|
361
|
+
)}
|
|
362
|
+
{columns.map((column, index) => {
|
|
363
|
+
// Destruct
|
|
364
|
+
const {
|
|
365
|
+
align,
|
|
366
|
+
field,
|
|
367
|
+
header,
|
|
368
|
+
minWidth,
|
|
369
|
+
sortable,
|
|
370
|
+
sortAsc = true,
|
|
371
|
+
type,
|
|
372
|
+
width
|
|
373
|
+
} = column;
|
|
374
|
+
|
|
375
|
+
// Header text
|
|
376
|
+
const headerText = header ?? field;
|
|
377
|
+
|
|
378
|
+
// Sortable
|
|
379
|
+
let sortLabel: React.ReactNode;
|
|
380
|
+
if (sortable && field != null) {
|
|
381
|
+
const active = orderBy === field;
|
|
382
|
+
|
|
383
|
+
sortLabel = (
|
|
384
|
+
<TableSortLabel
|
|
385
|
+
active={active}
|
|
386
|
+
direction={sortAsc ? "asc" : "desc"}
|
|
387
|
+
onClick={(_event) => {
|
|
388
|
+
if (active) column.sortAsc = !sortAsc;
|
|
389
|
+
|
|
390
|
+
handleSort(field, column.sortAsc);
|
|
391
|
+
}}
|
|
434
392
|
>
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
})
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
</
|
|
558
|
-
|
|
393
|
+
{headerText}
|
|
394
|
+
</TableSortLabel>
|
|
395
|
+
);
|
|
396
|
+
} else {
|
|
397
|
+
sortLabel = headerText;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
return (
|
|
401
|
+
<TableCell
|
|
402
|
+
align={GridAlignGet(align, type)}
|
|
403
|
+
key={field ?? index.toString()}
|
|
404
|
+
width={width}
|
|
405
|
+
sx={{
|
|
406
|
+
minWidth:
|
|
407
|
+
minWidth == null
|
|
408
|
+
? width == null
|
|
409
|
+
? TableExMinWidth
|
|
410
|
+
: undefined
|
|
411
|
+
: minWidth
|
|
412
|
+
}}
|
|
413
|
+
>
|
|
414
|
+
{sortLabel}
|
|
415
|
+
</TableCell>
|
|
416
|
+
);
|
|
417
|
+
})}
|
|
418
|
+
</TableRow>
|
|
419
|
+
</TableHead>
|
|
420
|
+
<TableBody
|
|
421
|
+
sx={{
|
|
422
|
+
"& tr:nth-of-type(odd):not(.Mui-selected)": {
|
|
423
|
+
backgroundColor: alternatingColors[0]
|
|
424
|
+
},
|
|
425
|
+
"& tr:nth-of-type(even):not(.Mui-selected)": {
|
|
426
|
+
backgroundColor: alternatingColors[1]
|
|
427
|
+
}
|
|
428
|
+
}}
|
|
429
|
+
>
|
|
430
|
+
{[...Array(batchSize)].map((_item, rowIndex) => {
|
|
431
|
+
// Row
|
|
432
|
+
const row = rowIndex < rows.length ? rows[rowIndex] : undefined;
|
|
433
|
+
|
|
434
|
+
// Row id field value
|
|
435
|
+
const rowId = DataTypes.getValue(row, idField) ?? rowIndex;
|
|
436
|
+
|
|
437
|
+
// Selected or not
|
|
438
|
+
const isItemSelected = selectable
|
|
439
|
+
? selectedItems.some((item) => item[idField] === rowId)
|
|
440
|
+
: false;
|
|
441
|
+
|
|
442
|
+
return (
|
|
443
|
+
<TableRow
|
|
444
|
+
key={rowId as unknown as React.Key}
|
|
445
|
+
selected={isItemSelected}
|
|
446
|
+
>
|
|
447
|
+
{selectable && (
|
|
448
|
+
<TableCell padding="checkbox">
|
|
449
|
+
{row && (
|
|
450
|
+
<Checkbox
|
|
451
|
+
color="primary"
|
|
452
|
+
checked={isItemSelected}
|
|
453
|
+
onChange={(_event, checked) =>
|
|
454
|
+
handleSelect(row, checked)
|
|
455
|
+
}
|
|
456
|
+
/>
|
|
457
|
+
)}
|
|
458
|
+
</TableCell>
|
|
459
|
+
)}
|
|
460
|
+
{columns.map(
|
|
461
|
+
(
|
|
462
|
+
{
|
|
463
|
+
align,
|
|
464
|
+
cellRenderer = DataGridRenderers.defaultCellRenderer,
|
|
465
|
+
field,
|
|
466
|
+
type,
|
|
467
|
+
valueFormatter
|
|
468
|
+
},
|
|
469
|
+
columnIndex
|
|
470
|
+
) => {
|
|
471
|
+
const formatProps: GridCellFormatterProps<T> = {
|
|
472
|
+
data: row,
|
|
473
|
+
field,
|
|
474
|
+
rowIndex,
|
|
475
|
+
columnIndex
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
const cellProps: TableCellProps = {
|
|
479
|
+
align: GridAlignGet(align, type),
|
|
480
|
+
valign: "middle"
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
const child = row ? (
|
|
484
|
+
cellRenderer({
|
|
485
|
+
data: row,
|
|
486
|
+
field,
|
|
487
|
+
formattedValue: valueFormatter
|
|
488
|
+
? valueFormatter(formatProps)
|
|
489
|
+
: undefined,
|
|
490
|
+
selected: isItemSelected,
|
|
491
|
+
type,
|
|
492
|
+
rowIndex,
|
|
493
|
+
columnIndex,
|
|
494
|
+
cellProps,
|
|
495
|
+
setItems
|
|
496
|
+
})
|
|
497
|
+
) : (
|
|
498
|
+
<React.Fragment> </React.Fragment>
|
|
499
|
+
);
|
|
500
|
+
|
|
501
|
+
return (
|
|
502
|
+
<TableCell
|
|
503
|
+
key={`${rowId}${columnIndex}`}
|
|
504
|
+
{...cellProps}
|
|
505
|
+
>
|
|
506
|
+
{child}
|
|
507
|
+
</TableCell>
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
)}
|
|
511
|
+
</TableRow>
|
|
512
|
+
);
|
|
513
|
+
})}
|
|
514
|
+
</TableBody>
|
|
515
|
+
</Table>
|
|
516
|
+
</TableContainer>
|
|
517
|
+
<TablePagination
|
|
518
|
+
component="div"
|
|
519
|
+
showFirstButton
|
|
520
|
+
count={totalRows}
|
|
521
|
+
rowsPerPage={batchSize}
|
|
522
|
+
page={currentPage}
|
|
523
|
+
onPageChange={handleChangePage}
|
|
524
|
+
onRowsPerPageChange={handleChangeRowsPerPage}
|
|
525
|
+
rowsPerPageOptions={[
|
|
526
|
+
batchSize,
|
|
527
|
+
2 * batchSize,
|
|
528
|
+
5 * batchSize,
|
|
529
|
+
10 * batchSize
|
|
530
|
+
]}
|
|
531
|
+
/>
|
|
532
|
+
</Paper>
|
|
533
|
+
);
|
|
559
534
|
}
|