@etsoo/materialui 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc.json +38 -0
  3. package/.gitattributes +2 -0
  4. package/.github/workflows/main.yml +48 -0
  5. package/.prettierignore +5 -0
  6. package/.prettierrc +6 -0
  7. package/LICENSE +21 -0
  8. package/README.md +16 -0
  9. package/__tests__/ComboBox.tsx +30 -0
  10. package/__tests__/MUGlobalTests.tsx +58 -0
  11. package/__tests__/NotifierMUTests.tsx +217 -0
  12. package/__tests__/SelectEx.tsx +26 -0
  13. package/__tests__/tsconfig.json +19 -0
  14. package/babel.config.json +11 -0
  15. package/lib/AuditDisplay.d.ts +33 -0
  16. package/lib/AuditDisplay.js +52 -0
  17. package/lib/AutocompleteExtendedProps.d.ts +64 -0
  18. package/lib/AutocompleteExtendedProps.js +1 -0
  19. package/lib/BackButton.d.ts +13 -0
  20. package/lib/BackButton.js +33 -0
  21. package/lib/BridgeCloseButton.d.ts +23 -0
  22. package/lib/BridgeCloseButton.js +32 -0
  23. package/lib/ButtonLink.d.ts +17 -0
  24. package/lib/ButtonLink.js +19 -0
  25. package/lib/ComboBox.d.ts +38 -0
  26. package/lib/ComboBox.js +108 -0
  27. package/lib/CountdownButton.d.ts +23 -0
  28. package/lib/CountdownButton.js +81 -0
  29. package/lib/CustomFabProps.d.ts +27 -0
  30. package/lib/CustomFabProps.js +1 -0
  31. package/lib/DataGridEx.d.ts +94 -0
  32. package/lib/DataGridEx.js +329 -0
  33. package/lib/DataGridRenderers.d.ts +22 -0
  34. package/lib/DataGridRenderers.js +99 -0
  35. package/lib/DialogButton.d.ts +54 -0
  36. package/lib/DialogButton.js +45 -0
  37. package/lib/DnDList.d.ts +87 -0
  38. package/lib/DnDList.js +153 -0
  39. package/lib/DraggablePaperComponent.d.ts +8 -0
  40. package/lib/DraggablePaperComponent.js +12 -0
  41. package/lib/EmailInput.d.ts +11 -0
  42. package/lib/EmailInput.js +15 -0
  43. package/lib/FabBox.d.ts +21 -0
  44. package/lib/FabBox.js +31 -0
  45. package/lib/FlexBox.d.ts +14 -0
  46. package/lib/FlexBox.js +18 -0
  47. package/lib/GridDataFormat.d.ts +10 -0
  48. package/lib/GridDataFormat.js +43 -0
  49. package/lib/IconButtonLink.d.ts +17 -0
  50. package/lib/IconButtonLink.js +16 -0
  51. package/lib/InputField.d.ts +21 -0
  52. package/lib/InputField.js +39 -0
  53. package/lib/ItemList.d.ts +56 -0
  54. package/lib/ItemList.js +69 -0
  55. package/lib/ListItemRightIcon.d.ts +4 -0
  56. package/lib/ListItemRightIcon.js +8 -0
  57. package/lib/ListMoreDisplay.d.ts +35 -0
  58. package/lib/ListMoreDisplay.js +99 -0
  59. package/lib/LoadingButton.d.ts +16 -0
  60. package/lib/LoadingButton.js +41 -0
  61. package/lib/MUGlobal.d.ts +102 -0
  62. package/lib/MUGlobal.js +184 -0
  63. package/lib/MaskInput.d.ts +34 -0
  64. package/lib/MaskInput.js +43 -0
  65. package/lib/MobileListItemRenderer.d.ts +17 -0
  66. package/lib/MobileListItemRenderer.js +35 -0
  67. package/lib/MoreFab.d.ts +45 -0
  68. package/lib/MoreFab.js +95 -0
  69. package/lib/NotifierMU.d.ts +47 -0
  70. package/lib/NotifierMU.js +387 -0
  71. package/lib/NotifierPromptProps.d.ts +22 -0
  72. package/lib/NotifierPromptProps.js +1 -0
  73. package/lib/OptionGroup.d.ts +58 -0
  74. package/lib/OptionGroup.js +81 -0
  75. package/lib/PList.d.ts +15 -0
  76. package/lib/PList.js +12 -0
  77. package/lib/ProgressCount.d.ts +44 -0
  78. package/lib/ProgressCount.js +79 -0
  79. package/lib/PullToRefreshUI.d.ts +9 -0
  80. package/lib/PullToRefreshUI.js +18 -0
  81. package/lib/RLink.d.ts +14 -0
  82. package/lib/RLink.js +37 -0
  83. package/lib/ResponsibleContainer.d.ts +87 -0
  84. package/lib/ResponsibleContainer.js +156 -0
  85. package/lib/ScrollTopFab.d.ts +7 -0
  86. package/lib/ScrollTopFab.js +25 -0
  87. package/lib/ScrollerListEx.d.ts +81 -0
  88. package/lib/ScrollerListEx.js +167 -0
  89. package/lib/SearchBar.d.ts +29 -0
  90. package/lib/SearchBar.js +260 -0
  91. package/lib/SearchField.d.ts +21 -0
  92. package/lib/SearchField.js +39 -0
  93. package/lib/SearchOptionGroup.d.ts +9 -0
  94. package/lib/SearchOptionGroup.js +14 -0
  95. package/lib/SelectBool.d.ts +13 -0
  96. package/lib/SelectBool.js +22 -0
  97. package/lib/SelectEx.d.ts +50 -0
  98. package/lib/SelectEx.js +156 -0
  99. package/lib/ShowDataComparison.d.ts +20 -0
  100. package/lib/ShowDataComparison.js +58 -0
  101. package/lib/Switch.d.ts +29 -0
  102. package/lib/Switch.js +34 -0
  103. package/lib/SwitchAnt.d.ts +25 -0
  104. package/lib/SwitchAnt.js +40 -0
  105. package/lib/TabBox.d.ts +54 -0
  106. package/lib/TabBox.js +31 -0
  107. package/lib/TableEx.d.ts +65 -0
  108. package/lib/TableEx.js +270 -0
  109. package/lib/TextFieldEx.d.ts +101 -0
  110. package/lib/TextFieldEx.js +126 -0
  111. package/lib/Tiplist.d.ts +18 -0
  112. package/lib/Tiplist.js +157 -0
  113. package/lib/TooltipClick.d.ts +15 -0
  114. package/lib/TooltipClick.js +40 -0
  115. package/lib/UserAvatar.d.ts +24 -0
  116. package/lib/UserAvatar.js +25 -0
  117. package/lib/UserAvatarEditor.d.ts +53 -0
  118. package/lib/UserAvatarEditor.js +129 -0
  119. package/lib/app/CommonApp.d.ts +38 -0
  120. package/lib/app/CommonApp.js +149 -0
  121. package/lib/app/IServiceAppSettings.d.ts +11 -0
  122. package/lib/app/IServiceAppSettings.js +1 -0
  123. package/lib/app/IServicePage.d.ts +6 -0
  124. package/lib/app/IServicePage.js +1 -0
  125. package/lib/app/IServiceUser.d.ts +14 -0
  126. package/lib/app/IServiceUser.js +1 -0
  127. package/lib/app/ISmartERPUser.d.ts +14 -0
  128. package/lib/app/ISmartERPUser.js +1 -0
  129. package/lib/app/Labels.d.ts +65 -0
  130. package/lib/app/Labels.js +62 -0
  131. package/lib/app/ReactApp.d.ts +195 -0
  132. package/lib/app/ReactApp.js +296 -0
  133. package/lib/app/ServiceApp.d.ts +78 -0
  134. package/lib/app/ServiceApp.js +244 -0
  135. package/lib/index.d.ts +74 -0
  136. package/lib/index.js +74 -0
  137. package/lib/pages/CommonPage.d.ts +11 -0
  138. package/lib/pages/CommonPage.js +60 -0
  139. package/lib/pages/CommonPageProps.d.ts +59 -0
  140. package/lib/pages/CommonPageProps.js +1 -0
  141. package/lib/pages/DataGridPage.d.ts +9 -0
  142. package/lib/pages/DataGridPage.js +79 -0
  143. package/lib/pages/DataGridPageProps.d.ts +17 -0
  144. package/lib/pages/DataGridPageProps.js +1 -0
  145. package/lib/pages/EditPage.d.ts +33 -0
  146. package/lib/pages/EditPage.js +29 -0
  147. package/lib/pages/FixedListPage.d.ts +15 -0
  148. package/lib/pages/FixedListPage.js +70 -0
  149. package/lib/pages/ListPage.d.ts +9 -0
  150. package/lib/pages/ListPage.js +50 -0
  151. package/lib/pages/ListPageProps.d.ts +7 -0
  152. package/lib/pages/ListPageProps.js +1 -0
  153. package/lib/pages/ResponsivePage.d.ts +9 -0
  154. package/lib/pages/ResponsivePage.js +45 -0
  155. package/lib/pages/ResponsivePageProps.d.ts +39 -0
  156. package/lib/pages/ResponsivePageProps.js +1 -0
  157. package/lib/pages/SearchPageProps.d.ts +30 -0
  158. package/lib/pages/SearchPageProps.js +1 -0
  159. package/lib/pages/TablePage.d.ts +9 -0
  160. package/lib/pages/TablePage.js +69 -0
  161. package/lib/pages/TablePageProps.d.ts +7 -0
  162. package/lib/pages/TablePageProps.js +1 -0
  163. package/lib/pages/ViewPage.d.ts +66 -0
  164. package/lib/pages/ViewPage.js +105 -0
  165. package/lib/texts/DateText.d.ts +34 -0
  166. package/lib/texts/DateText.js +25 -0
  167. package/lib/texts/MoneyText.d.ts +21 -0
  168. package/lib/texts/MoneyText.js +14 -0
  169. package/lib/texts/NumberText.d.ts +25 -0
  170. package/lib/texts/NumberText.js +14 -0
  171. package/package.json +97 -0
  172. package/src/AuditDisplay.tsx +114 -0
  173. package/src/AutocompleteExtendedProps.ts +83 -0
  174. package/src/BackButton.tsx +55 -0
  175. package/src/BridgeCloseButton.tsx +69 -0
  176. package/src/ButtonLink.tsx +32 -0
  177. package/src/ComboBox.tsx +251 -0
  178. package/src/CountdownButton.tsx +119 -0
  179. package/src/CustomFabProps.ts +32 -0
  180. package/src/DataGridEx.tsx +713 -0
  181. package/src/DataGridRenderers.tsx +140 -0
  182. package/src/DialogButton.tsx +163 -0
  183. package/src/DnDList.tsx +344 -0
  184. package/src/DraggablePaperComponent.tsx +19 -0
  185. package/src/EmailInput.tsx +24 -0
  186. package/src/FabBox.tsx +51 -0
  187. package/src/FlexBox.tsx +20 -0
  188. package/src/GridDataFormat.tsx +77 -0
  189. package/src/IconButtonLink.tsx +29 -0
  190. package/src/InputField.tsx +82 -0
  191. package/src/ItemList.tsx +204 -0
  192. package/src/ListItemRightIcon.tsx +9 -0
  193. package/src/ListMoreDisplay.tsx +205 -0
  194. package/src/LoadingButton.tsx +75 -0
  195. package/src/MUGlobal.ts +220 -0
  196. package/src/MaskInput.tsx +107 -0
  197. package/src/MobileListItemRenderer.tsx +79 -0
  198. package/src/MoreFab.tsx +211 -0
  199. package/src/NotifierMU.tsx +654 -0
  200. package/src/NotifierPromptProps.ts +24 -0
  201. package/src/OptionGroup.tsx +223 -0
  202. package/src/PList.tsx +27 -0
  203. package/src/ProgressCount.tsx +166 -0
  204. package/src/PullToRefreshUI.tsx +21 -0
  205. package/src/RLink.tsx +64 -0
  206. package/src/ResponsibleContainer.tsx +394 -0
  207. package/src/ScrollTopFab.tsx +34 -0
  208. package/src/ScrollerListEx.tsx +387 -0
  209. package/src/SearchBar.tsx +396 -0
  210. package/src/SearchField.tsx +82 -0
  211. package/src/SearchOptionGroup.tsx +31 -0
  212. package/src/SelectBool.tsx +33 -0
  213. package/src/SelectEx.tsx +290 -0
  214. package/src/ShowDataComparison.tsx +106 -0
  215. package/src/Switch.tsx +94 -0
  216. package/src/SwitchAnt.tsx +95 -0
  217. package/src/TabBox.tsx +118 -0
  218. package/src/TableEx.tsx +558 -0
  219. package/src/TextFieldEx.tsx +249 -0
  220. package/src/Tiplist.tsx +303 -0
  221. package/src/TooltipClick.tsx +84 -0
  222. package/src/UserAvatar.tsx +64 -0
  223. package/src/UserAvatarEditor.tsx +287 -0
  224. package/src/app/CommonApp.ts +223 -0
  225. package/src/app/IServiceAppSettings.ts +13 -0
  226. package/src/app/IServicePage.ts +6 -0
  227. package/src/app/IServiceUser.ts +17 -0
  228. package/src/app/ISmartERPUser.ts +16 -0
  229. package/src/app/Labels.ts +77 -0
  230. package/src/app/ReactApp.ts +504 -0
  231. package/src/app/ServiceApp.ts +352 -0
  232. package/src/index.ts +77 -0
  233. package/src/pages/CommonPage.tsx +128 -0
  234. package/src/pages/CommonPageProps.ts +70 -0
  235. package/src/pages/DataGridPage.tsx +140 -0
  236. package/src/pages/DataGridPageProps.ts +24 -0
  237. package/src/pages/EditPage.tsx +114 -0
  238. package/src/pages/FixedListPage.tsx +141 -0
  239. package/src/pages/ListPage.tsx +90 -0
  240. package/src/pages/ListPageProps.ts +12 -0
  241. package/src/pages/ResponsivePage.tsx +68 -0
  242. package/src/pages/ResponsivePageProps.ts +57 -0
  243. package/src/pages/SearchPageProps.ts +39 -0
  244. package/src/pages/TablePage.tsx +126 -0
  245. package/src/pages/TablePageProps.ts +12 -0
  246. package/src/pages/ViewPage.tsx +282 -0
  247. package/src/texts/DateText.tsx +74 -0
  248. package/src/texts/MoneyText.tsx +49 -0
  249. package/src/texts/NumberText.tsx +40 -0
  250. package/tsconfig.json +19 -0
@@ -0,0 +1,558 @@
1
+ import {
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
+ import {
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
+
30
+ /**
31
+ * Extended table min width for width-unset column
32
+ */
33
+ export const TableExMinWidth: number = 180;
34
+
35
+ /**
36
+ * Extended table methods ref
37
+ */
38
+ export interface TableExMethodRef<T> extends GridMethodRef<T> {
39
+ /**
40
+ * Refresh data
41
+ */
42
+ refresh(): void;
43
+ }
44
+
45
+ /**
46
+ * Extended table props
47
+ */
48
+ export type TableExProps<
49
+ T extends object,
50
+ D extends DataTypes.Keys<T>
51
+ > = TableProps &
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
+
99
+ /**
100
+ * Extended Table
101
+ * @param props Props
102
+ * @returns Component
103
+ */
104
+ export function TableEx<
105
+ T extends object,
106
+ D extends DataTypes.Keys<T> = IdDefaultType<T>
107
+ >(props: TableExProps<T, D>) {
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
138
+ rowsPerPageLocal = Math.floor(
139
+ (maxHeight - otherHeight) / rowHeight
140
+ );
141
+ } else if (typeof loadBatchSize === 'number') {
142
+ rowsPerPageLocal = loadBatchSize;
143
+ } else {
144
+ rowsPerPageLocal = 10;
145
+ }
146
+
147
+ // Rows
148
+ const [rows, updateRows] = React.useState<T[]>([]);
149
+ const setRows = (rows: T[]) => {
150
+ state.loadedItems = rows.length;
151
+ updateRows(rows);
152
+ };
153
+
154
+ // States
155
+ const stateRefs = React.useRef<GridLoaderStates<T>>({
156
+ autoLoad,
157
+ currentPage: 0,
158
+ loadedItems: 0,
159
+ hasNextPage: true,
160
+ isNextPageLoading: false,
161
+ orderBy: defaultOrderBy,
162
+ orderByAsc: defaultOrderBy
163
+ ? columns.find((column) => column.field === defaultOrderBy)?.sortAsc
164
+ : undefined,
165
+ batchSize: rowsPerPageLocal,
166
+ selectedItems: []
167
+ });
168
+ const state = stateRefs.current;
169
+
170
+ // Reset the state and load again
171
+ const reset = (add?: Partial<GridLoaderStates<T>>) => {
172
+ const resetState: Partial<GridLoaderStates<T>> = {
173
+ autoLoad: true,
174
+ currentPage: 0,
175
+ loadedItems: 0,
176
+ hasNextPage: true,
177
+ isNextPageLoading: false,
178
+ lastLoadedItems: undefined,
179
+ ...add
180
+ };
181
+ Object.assign(state, resetState);
182
+ };
183
+
184
+ React.useImperativeHandle(
185
+ mRef,
186
+ () => ({
187
+ /**
188
+ * Refresh data
189
+ */
190
+ refresh(): void {
191
+ loadDataLocal();
192
+ },
193
+
194
+ /**
195
+ * Reset
196
+ */
197
+ reset
198
+ }),
199
+ []
200
+ );
201
+
202
+ // Load data
203
+ const loadDataLocal = () => {
204
+ // Prevent multiple loadings
205
+ if (!state.hasNextPage || state.isNextPageLoading) return;
206
+
207
+ // Update state
208
+ state.isNextPageLoading = true;
209
+
210
+ // Parameters
211
+ const { currentPage, batchSize, orderBy, orderByAsc, data, isMounted } =
212
+ state;
213
+
214
+ const loadProps: GridLoadDataProps = {
215
+ currentPage,
216
+ batchSize,
217
+ orderBy,
218
+ orderByAsc,
219
+ data
220
+ };
221
+
222
+ loadData(loadProps).then((result) => {
223
+ state.isMounted = true;
224
+ if (result == null || isMounted === false) {
225
+ return;
226
+ }
227
+
228
+ const newItems = result.length;
229
+ state.lastLoadedItems = newItems;
230
+ state.hasNextPage = newItems >= batchSize;
231
+ state.isNextPageLoading = false;
232
+
233
+ // Update rows
234
+ setRows(result);
235
+ });
236
+ };
237
+
238
+ const handleChangePage = (_event: unknown, newPage: number) => {
239
+ state.hasNextPage = true;
240
+ state.currentPage = newPage;
241
+ loadDataLocal();
242
+ };
243
+
244
+ const handleChangeRowsPerPage = (
245
+ event: React.ChangeEvent<HTMLInputElement>
246
+ ) => {
247
+ const batchSize = parseInt(event.target.value);
248
+ reset({ batchSize });
249
+ };
250
+
251
+ const handleSelect = (item: T, checked: Boolean) => {
252
+ const selectedItems = state.selectedItems;
253
+
254
+ const index = selectedItems.findIndex(
255
+ (selectedItem) => selectedItem[idField] === item[idField]
256
+ );
257
+ if (checked) {
258
+ if (index === -1) selectedItems.push(item);
259
+ } else {
260
+ if (index !== -1) selectedItems.splice(index, 1);
261
+ }
262
+
263
+ if (onSelectChange != null) {
264
+ onSelectChange(selectedItems);
265
+ }
266
+ };
267
+
268
+ const handleSelectAll = (checked: boolean) => {
269
+ const selectedItems = state.selectedItems;
270
+
271
+ rows.forEach((row) => {
272
+ const index = selectedItems.findIndex(
273
+ (selectedItem) => selectedItem[idField] === row[idField]
274
+ );
275
+
276
+ if (checked) {
277
+ if (index === -1) selectedItems.push(row);
278
+ } else if (index !== -1) {
279
+ selectedItems.splice(index, 1);
280
+ }
281
+ });
282
+
283
+ if (onSelectChange != null) {
284
+ onSelectChange(selectedItems);
285
+ }
286
+ };
287
+
288
+ // New sort
289
+ const handleSort = (field: string, asc?: boolean) => {
290
+ reset({ orderBy: field, orderByAsc: asc });
291
+ };
292
+
293
+ // Destruct states
294
+ const {
295
+ autoLoad: stateAutoLoad,
296
+ currentPage,
297
+ hasNextPage,
298
+ lastLoadedItems,
299
+ orderBy,
300
+ batchSize,
301
+ selectedItems
302
+ } = state;
303
+
304
+ // Current page selected items
305
+ const pageSelectedItems = selectable
306
+ ? rows.reduce((previousValue, currentItem) => {
307
+ if (
308
+ selectedItems.some(
309
+ (item) => item[idField] === currentItem[idField]
310
+ )
311
+ )
312
+ return previousValue + 1;
313
+
314
+ return previousValue;
315
+ }, 0)
316
+ : 0;
317
+
318
+ // Total rows
319
+ const totalRows = hasNextPage
320
+ ? -1
321
+ : currentPage * batchSize + (lastLoadedItems ?? 0);
322
+
323
+ // Auto load data when current page is 0
324
+ if (currentPage === 0 && stateAutoLoad && lastLoadedItems == null)
325
+ loadDataLocal();
326
+
327
+ React.useEffect(() => {
328
+ return () => {
329
+ state.isMounted = false;
330
+ };
331
+ }, []);
332
+
333
+ // Layout
334
+ return (
335
+ <Paper>
336
+ <TableContainer sx={{ maxHeight }}>
337
+ <Table {...rest}>
338
+ <TableHead>
339
+ <TableRow
340
+ sx={{
341
+ '& th': {
342
+ backgroundColor: headerColors[0],
343
+ color: headerColors[1]
344
+ }
345
+ }}
346
+ >
347
+ {selectable && (
348
+ <TableCell padding="checkbox">
349
+ <Checkbox
350
+ color="primary"
351
+ indeterminate={
352
+ pageSelectedItems > 0 &&
353
+ pageSelectedItems < rows.length
354
+ }
355
+ checked={pageSelectedItems > 0}
356
+ onChange={(_event, checked) =>
357
+ handleSelectAll(checked)
358
+ }
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)
389
+ column.sortAsc = !sortAsc;
390
+
391
+ handleSort(
392
+ field,
393
+ column.sortAsc
394
+ );
395
+ }}
396
+ >
397
+ {headerText}
398
+ </TableSortLabel>
399
+ );
400
+ } else {
401
+ sortLabel = headerText;
402
+ }
403
+
404
+ return (
405
+ <TableCell
406
+ align={GridAlignGet(align, type)}
407
+ key={field ?? index.toString()}
408
+ width={width}
409
+ sx={{
410
+ minWidth:
411
+ minWidth == null
412
+ ? width == null
413
+ ? TableExMinWidth
414
+ : undefined
415
+ : minWidth
416
+ }}
417
+ >
418
+ {sortLabel}
419
+ </TableCell>
420
+ );
421
+ })}
422
+ </TableRow>
423
+ </TableHead>
424
+ <TableBody
425
+ sx={{
426
+ '& tr:nth-of-type(odd):not(.Mui-selected)': {
427
+ backgroundColor: alternatingColors[0]
428
+ },
429
+ '& tr:nth-of-type(even):not(.Mui-selected)': {
430
+ backgroundColor: alternatingColors[1]
431
+ }
432
+ }}
433
+ >
434
+ {[...Array(batchSize)].map((_item, rowIndex) => {
435
+ // Row
436
+ const row =
437
+ rowIndex < rows.length
438
+ ? rows[rowIndex]
439
+ : undefined;
440
+
441
+ // Row id field value
442
+ const rowId =
443
+ DataTypes.getValue(row, idField) ?? rowIndex;
444
+
445
+ // Selected or not
446
+ const isItemSelected = selectable
447
+ ? selectedItems.some(
448
+ (item) => item[idField] === rowId
449
+ )
450
+ : false;
451
+
452
+ return (
453
+ <TableRow
454
+ key={rowId as unknown as React.Key}
455
+ selected={isItemSelected}
456
+ >
457
+ {selectable && (
458
+ <TableCell padding="checkbox">
459
+ {row && (
460
+ <Checkbox
461
+ color="primary"
462
+ checked={isItemSelected}
463
+ onChange={(
464
+ _event,
465
+ checked
466
+ ) =>
467
+ handleSelect(
468
+ row,
469
+ checked
470
+ )
471
+ }
472
+ />
473
+ )}
474
+ </TableCell>
475
+ )}
476
+ {columns.map(
477
+ (
478
+ {
479
+ align,
480
+ cellRenderer = DataGridRenderers.defaultCellRenderer,
481
+ field,
482
+ type,
483
+ valueFormatter
484
+ },
485
+ columnIndex
486
+ ) => {
487
+ const formatProps: GridCellFormatterProps<T> =
488
+ {
489
+ data: row,
490
+ field,
491
+ rowIndex,
492
+ columnIndex
493
+ };
494
+
495
+ const cellProps: TableCellProps = {
496
+ align: GridAlignGet(
497
+ align,
498
+ type
499
+ ),
500
+ valign: 'middle'
501
+ };
502
+
503
+ const child = row ? (
504
+ cellRenderer({
505
+ data: row,
506
+ field,
507
+ formattedValue:
508
+ valueFormatter
509
+ ? valueFormatter(
510
+ formatProps
511
+ )
512
+ : undefined,
513
+ selected: isItemSelected,
514
+ type,
515
+ rowIndex,
516
+ columnIndex,
517
+ cellProps
518
+ })
519
+ ) : (
520
+ <React.Fragment>
521
+ &nbsp;
522
+ </React.Fragment>
523
+ );
524
+
525
+ return (
526
+ <TableCell
527
+ key={`${rowId}${columnIndex}`}
528
+ {...cellProps}
529
+ >
530
+ {child}
531
+ </TableCell>
532
+ );
533
+ }
534
+ )}
535
+ </TableRow>
536
+ );
537
+ })}
538
+ </TableBody>
539
+ </Table>
540
+ </TableContainer>
541
+ <TablePagination
542
+ component="div"
543
+ showFirstButton
544
+ count={totalRows}
545
+ rowsPerPage={batchSize}
546
+ page={currentPage}
547
+ onPageChange={handleChangePage}
548
+ onRowsPerPageChange={handleChangeRowsPerPage}
549
+ rowsPerPageOptions={[
550
+ batchSize,
551
+ 2 * batchSize,
552
+ 5 * batchSize,
553
+ 10 * batchSize
554
+ ]}
555
+ />
556
+ </Paper>
557
+ );
558
+ }