mui-universal-table 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.
package/dist/index.js ADDED
@@ -0,0 +1,1139 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var React = require('react');
6
+ var PropTypes = require('prop-types');
7
+ var Paper = require('@mui/material/Paper');
8
+ var material = require('@mui/material');
9
+ var styles = require('@mui/material/styles');
10
+ var iconsMaterial = require('@mui/icons-material');
11
+ var RefreshIcon = require('@mui/icons-material/Refresh');
12
+
13
+ function _arrayLikeToArray(r, a) {
14
+ (null == a || a > r.length) && (a = r.length);
15
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
16
+ return n;
17
+ }
18
+ function _arrayWithHoles(r) {
19
+ if (Array.isArray(r)) return r;
20
+ }
21
+ function _arrayWithoutHoles(r) {
22
+ if (Array.isArray(r)) return _arrayLikeToArray(r);
23
+ }
24
+ function _defineProperty(e, r, t) {
25
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
26
+ value: t,
27
+ enumerable: true,
28
+ configurable: true,
29
+ writable: true
30
+ }) : e[r] = t, e;
31
+ }
32
+ function _extends() {
33
+ return _extends = Object.assign ? Object.assign.bind() : function (n) {
34
+ for (var e = 1; e < arguments.length; e++) {
35
+ var t = arguments[e];
36
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
37
+ }
38
+ return n;
39
+ }, _extends.apply(null, arguments);
40
+ }
41
+ function _iterableToArray(r) {
42
+ if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
43
+ }
44
+ function _iterableToArrayLimit(r, l) {
45
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
46
+ if (null != t) {
47
+ var e,
48
+ n,
49
+ i,
50
+ u,
51
+ a = [],
52
+ f = true,
53
+ o = false;
54
+ try {
55
+ if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
56
+ } catch (r) {
57
+ o = true, n = r;
58
+ } finally {
59
+ try {
60
+ if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
61
+ } finally {
62
+ if (o) throw n;
63
+ }
64
+ }
65
+ return a;
66
+ }
67
+ }
68
+ function _nonIterableRest() {
69
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
70
+ }
71
+ function _nonIterableSpread() {
72
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
73
+ }
74
+ function ownKeys(e, r) {
75
+ var t = Object.keys(e);
76
+ if (Object.getOwnPropertySymbols) {
77
+ var o = Object.getOwnPropertySymbols(e);
78
+ r && (o = o.filter(function (r) {
79
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
80
+ })), t.push.apply(t, o);
81
+ }
82
+ return t;
83
+ }
84
+ function _objectSpread2(e) {
85
+ for (var r = 1; r < arguments.length; r++) {
86
+ var t = null != arguments[r] ? arguments[r] : {};
87
+ r % 2 ? ownKeys(Object(t), true).forEach(function (r) {
88
+ _defineProperty(e, r, t[r]);
89
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
90
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
91
+ });
92
+ }
93
+ return e;
94
+ }
95
+ function _slicedToArray(r, e) {
96
+ return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
97
+ }
98
+ function _toConsumableArray(r) {
99
+ return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
100
+ }
101
+ function _toPrimitive(t, r) {
102
+ if ("object" != typeof t || !t) return t;
103
+ var e = t[Symbol.toPrimitive];
104
+ if (void 0 !== e) {
105
+ var i = e.call(t, r);
106
+ if ("object" != typeof i) return i;
107
+ throw new TypeError("@@toPrimitive must return a primitive value.");
108
+ }
109
+ return ("string" === r ? String : Number)(t);
110
+ }
111
+ function _toPropertyKey(t) {
112
+ var i = _toPrimitive(t, "string");
113
+ return "symbol" == typeof i ? i : i + "";
114
+ }
115
+ function _unsupportedIterableToArray(r, a) {
116
+ if (r) {
117
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
118
+ var t = {}.toString.call(r).slice(8, -1);
119
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
120
+ }
121
+ }
122
+
123
+ var LazyLoadingIndicator = function LazyLoadingIndicator(_ref) {
124
+ var show = _ref.show,
125
+ currentPage = _ref.currentPage,
126
+ totalPages = _ref.totalPages;
127
+ return /*#__PURE__*/React.createElement(material.Collapse, {
128
+ "in": show,
129
+ timeout: "auto",
130
+ unmountOnExit: true
131
+ }, /*#__PURE__*/React.createElement(material.Box, {
132
+ sx: {
133
+ width: "100%",
134
+ p: 2
135
+ }
136
+ }, /*#__PURE__*/React.createElement(material.Typography, {
137
+ variant: "body2",
138
+ color: "text.secondary",
139
+ sx: {
140
+ mb: 1
141
+ }
142
+ }, "Loading page ", currentPage, " of ", totalPages, "..."), /*#__PURE__*/React.createElement(material.LinearProgress, {
143
+ variant: "determinate",
144
+ value: currentPage / totalPages * 100
145
+ })));
146
+ };
147
+ LazyLoadingIndicator.propTypes = {
148
+ show: PropTypes.bool.isRequired,
149
+ currentPage: PropTypes.number,
150
+ totalPages: PropTypes.number
151
+ };
152
+
153
+ /**
154
+ * Standard visually-hidden style: content is accessible to screen readers
155
+ * but invisible on screen. Defined locally to avoid importing from
156
+ * @mui/utils which is not a declared peer dependency.
157
+ */
158
+ var visuallyHidden = {
159
+ border: 0,
160
+ clip: "rect(0 0 0 0)",
161
+ height: "1px",
162
+ margin: -1,
163
+ overflow: "hidden",
164
+ padding: 0,
165
+ position: "absolute",
166
+ whiteSpace: "nowrap",
167
+ width: "1px"
168
+ };
169
+ function getSelectableRowId(row, index, selectID) {
170
+ return selectID ? row[selectID] : index;
171
+ }
172
+ function getSearchableColumnIds(headers) {
173
+ return headers.filter(function (column) {
174
+ return column.searchable;
175
+ }).map(function (column) {
176
+ return column.id;
177
+ });
178
+ }
179
+ function filterRows(data, searchTerm, filterOptions) {
180
+ if (!searchTerm) {
181
+ return data;
182
+ }
183
+ var term = searchTerm.toLocaleLowerCase();
184
+ return data.filter(function (row) {
185
+ return filterOptions.some(function (filterOption) {
186
+ return String(row[filterOption]).toLocaleLowerCase().includes(term);
187
+ });
188
+ });
189
+ }
190
+ function getPageOptions(rowCount) {
191
+ if (rowCount <= 5) return [5];
192
+ if (rowCount <= 10) return [5, rowCount];
193
+ if (rowCount <= 25) return [5, 10, rowCount];
194
+ if (rowCount < 50) return [5, 10, 25, rowCount];
195
+ if (rowCount < 100) return [5, 10, 25, 50, rowCount];
196
+ return [5, 10, 25, 50, 100, rowCount];
197
+ }
198
+ function splitHeaders(headers) {
199
+ return headers.reduce(function (groups, header) {
200
+ if (header.subRow) {
201
+ groups.subTables.push(header);
202
+ } else {
203
+ groups.columns.push(header);
204
+ }
205
+ return groups;
206
+ }, {
207
+ subTables: [],
208
+ columns: []
209
+ });
210
+ }
211
+ function descendingComparator(a, b, orderBy) {
212
+ if (b[orderBy] < a[orderBy]) {
213
+ return -1;
214
+ }
215
+ if (b[orderBy] > a[orderBy]) {
216
+ return 1;
217
+ }
218
+ return 0;
219
+ }
220
+ function getComparator(order, orderBy) {
221
+ return order === "desc" ? function (a, b) {
222
+ return descendingComparator(a, b, orderBy);
223
+ } : function (a, b) {
224
+ return -descendingComparator(a, b, orderBy);
225
+ };
226
+ }
227
+
228
+ /**
229
+ * Format a cell value for display. Handles dates safely:
230
+ * returns the raw value for non-date headers, and a formatted
231
+ * date string for date headers (guards against invalid dates).
232
+ *
233
+ * Uses `new Date(raw)` directly rather than `Date.parse(raw)` to
234
+ * handle epoch-millisecond numbers, Date objects, and string
235
+ * formats that Date.parse may reject.
236
+ */
237
+ function formatCellValue(header, rowValues) {
238
+ var raw = rowValues[header.id];
239
+ if (!header.date) {
240
+ return raw;
241
+ }
242
+
243
+ // null and undefined produce a valid epoch-0 Date, not Invalid Date
244
+ if (raw === null || raw === undefined) {
245
+ return raw;
246
+ }
247
+ var d = new Date(raw);
248
+ if (Number.isNaN(d.getTime())) {
249
+ return raw;
250
+ }
251
+ return d.toDateString() + " " + d.toLocaleTimeString("en-US", {
252
+ hour: "numeric",
253
+ minute: "2-digit",
254
+ hour12: true
255
+ });
256
+ }
257
+ function stableSort(array, comparator, headers) {
258
+ var dateColumns = new Set(headers.filter(function (object) {
259
+ return object.date;
260
+ }).map(function (value) {
261
+ return value.id;
262
+ }));
263
+
264
+ // Build stable entries — compare pre-computed sort keys so we never
265
+ // mutate the original data or its shallow copies.
266
+ // Each entry is [originalRow, sortKey, index] so that the comparator
267
+ // works on numeric-converted date values while the original rows are
268
+ // returned unchanged (preserving the data seen by header.component).
269
+ var stabilizedThis = array.map(function (el, index) {
270
+ var sortKey = _objectSpread2({}, el);
271
+ for (var property in sortKey) {
272
+ if (dateColumns.has(property)) {
273
+ var parsed = Number(new Date(sortKey[property]));
274
+ // Preserve the original value for invalid dates so formatCellValue
275
+ // can display the fallback instead of passing NaN to React children.
276
+ if (!Number.isNaN(parsed)) {
277
+ sortKey[property] = parsed;
278
+ }
279
+ }
280
+ }
281
+ return [el, sortKey, index];
282
+ });
283
+ stabilizedThis.sort(function (a, b) {
284
+ var order = comparator(a[1], b[1]);
285
+ if (order !== 0) return order;
286
+ return a[2] - b[2];
287
+ });
288
+ return stabilizedThis.map(function (el) {
289
+ return el[0];
290
+ });
291
+ }
292
+
293
+ function useSearchableRows(data, headers) {
294
+ var _React$useState = React.useState(""),
295
+ _React$useState2 = _slicedToArray(_React$useState, 2),
296
+ searchTerm = _React$useState2[0],
297
+ setSearchTerm = _React$useState2[1];
298
+ var filterOptions = React.useMemo(function () {
299
+ return getSearchableColumnIds(headers);
300
+ }, [headers]);
301
+ var rows = React.useMemo(function () {
302
+ return filterRows(data, searchTerm, filterOptions);
303
+ }, [data, filterOptions, searchTerm]);
304
+ return {
305
+ rows: rows,
306
+ searchTerm: searchTerm,
307
+ setSearchTerm: setSearchTerm
308
+ };
309
+ }
310
+
311
+ function useSelectableRows(_ref) {
312
+ var rows = _ref.rows,
313
+ selectRows = _ref.selectRows,
314
+ selectID = _ref.selectID;
315
+ var _React$useState = React.useState([]),
316
+ _React$useState2 = _slicedToArray(_React$useState, 2),
317
+ selected = _React$useState2[0],
318
+ setSelected = _React$useState2[1];
319
+ var clearSelection = React.useCallback(function () {
320
+ setSelected([]);
321
+ }, []);
322
+ var handleSelectAllClick = React.useCallback(function (event) {
323
+ if (!event.target.checked) {
324
+ setSelected([]);
325
+ return;
326
+ }
327
+ var newSelected = rows.map(function (row, index) {
328
+ return getSelectableRowId(row, index, selectID);
329
+ });
330
+ setSelected(newSelected);
331
+ }, [rows, selectID]);
332
+ var handleClick = React.useCallback(function (event, id) {
333
+ if (!selectRows) {
334
+ return;
335
+ }
336
+ setSelected(function (previous) {
337
+ return previous.includes(id) ? previous.filter(function (selectedId) {
338
+ return selectedId !== id;
339
+ }) : [].concat(_toConsumableArray(previous), [id]);
340
+ });
341
+ }, [selectRows]);
342
+ return {
343
+ selected: selected,
344
+ clearSelection: clearSelection,
345
+ handleSelectAllClick: handleSelectAllClick,
346
+ handleClick: handleClick
347
+ };
348
+ }
349
+
350
+ function TableSelectionBanner(_ref) {
351
+ var selected = _ref.selected,
352
+ onSelection = _ref.onSelection,
353
+ selectIcon = _ref.selectIcon;
354
+ return /*#__PURE__*/React.createElement(material.Collapse, {
355
+ "in": selected.length > 0,
356
+ unmountOnExit: true
357
+ }, /*#__PURE__*/React.createElement(material.Box, {
358
+ sx: {
359
+ p: 2,
360
+ display: "flex",
361
+ justifyContent: "space-between",
362
+ bgcolor: function bgcolor(theme) {
363
+ return styles.alpha(theme.palette.primary.main, theme.palette.action.activatedOpacity);
364
+ },
365
+ borderRadius: 1,
366
+ borderBottomLeftRadius: 0,
367
+ borderBottomRightRadius: 0
368
+ }
369
+ }, /*#__PURE__*/React.createElement(material.Typography, {
370
+ variant: "h6",
371
+ id: "tableTitle",
372
+ component: "div"
373
+ }, selected.length, " selected"), /*#__PURE__*/React.createElement(material.IconButton, {
374
+ onClick: function onClick() {
375
+ return onSelection(selected);
376
+ }
377
+ }, selectIcon || /*#__PURE__*/React.createElement(iconsMaterial.Task, null))));
378
+ }
379
+ TableSelectionBanner.propTypes = {
380
+ selected: PropTypes.array.isRequired,
381
+ onSelection: PropTypes.func,
382
+ selectIcon: PropTypes.element
383
+ };
384
+
385
+ function TableTitle(_ref) {
386
+ var name = _ref.name,
387
+ subTable = _ref.subTable;
388
+ return /*#__PURE__*/React.createElement(material.Typography, {
389
+ variant: subTable ? "h6" : "h5",
390
+ color: subTable ? "secondary" : "primary",
391
+ sx: {
392
+ p: 2
393
+ }
394
+ }, name);
395
+ }
396
+ TableTitle.propTypes = {
397
+ name: PropTypes.string,
398
+ subTable: PropTypes.bool
399
+ };
400
+
401
+ function ReloadBtn(_ref) {
402
+ var setLoading = _ref.setLoading,
403
+ loading = _ref.loading,
404
+ onReload = _ref.onReload;
405
+ var canReload = typeof onReload === "function" || typeof setLoading === "function";
406
+ if (!canReload) {
407
+ return null;
408
+ }
409
+ var handleClick = function handleClick() {
410
+ if (typeof onReload === "function") {
411
+ onReload();
412
+ } else if (typeof setLoading === "function") {
413
+ setLoading(true);
414
+ }
415
+ };
416
+ return /*#__PURE__*/React.createElement(material.Tooltip, {
417
+ title: "Reload"
418
+ }, /*#__PURE__*/React.createElement(material.Button, {
419
+ variant: "contained",
420
+ color: "primary",
421
+ onClick: handleClick,
422
+ disabled: loading
423
+ }, /*#__PURE__*/React.createElement(RefreshIcon, null)));
424
+ }
425
+ ReloadBtn.propTypes = {
426
+ setLoading: PropTypes.func,
427
+ loading: PropTypes.bool,
428
+ /** Preferred callback — fires when the user clicks reload. */
429
+ onReload: PropTypes.func
430
+ };
431
+
432
+ function FancySearch(_ref) {
433
+ var value = _ref.value,
434
+ onSubmit = _ref.onSubmit;
435
+ var _React$useState = React.useState(value),
436
+ _React$useState2 = _slicedToArray(_React$useState, 2),
437
+ search = _React$useState2[0],
438
+ setSearch = _React$useState2[1];
439
+ var _React$useState3 = React.useState(Boolean(search)),
440
+ _React$useState4 = _slicedToArray(_React$useState3, 2),
441
+ hover = _React$useState4[0],
442
+ setHover = _React$useState4[1];
443
+ var expanded = hover || Boolean(search);
444
+ var handleSubmit = function handleSubmit(e) {
445
+ e.preventDefault();
446
+ onSubmit(search);
447
+ };
448
+ var handleEndHover = function handleEndHover() {
449
+ setHover(false);
450
+ };
451
+
452
+ // Sync internal state when the parent clears/changes the search term.
453
+ // A ref tracks whether this sync came from the user typing or from a parent
454
+ // update, so the debounce only fires for genuine user input.
455
+ var isUserType = React.useRef(false);
456
+ React.useEffect(function () {
457
+ if (isUserType.current) {
458
+ // User is typing — debounce as normal
459
+ isUserType.current = false;
460
+ var timer = setTimeout(function () {
461
+ onSubmit(search);
462
+ }, 700);
463
+ return function () {
464
+ return clearTimeout(timer);
465
+ };
466
+ }
467
+ // External value change (parent reset, clear from clearSelection, etc.)
468
+ // — sync state and do NOT fire a stale debounce.
469
+ setSearch(value);
470
+ return undefined;
471
+ }, [search, value, onSubmit]);
472
+ return /*#__PURE__*/React.createElement("form", {
473
+ onSubmit: handleSubmit
474
+ }, /*#__PURE__*/React.createElement(material.Paper, {
475
+ elevation: 0,
476
+ sx: {
477
+ borderRadius: expanded ? "24px" : "50px",
478
+ display: "flex",
479
+ alignItems: "center",
480
+ transition: "all 0.5s ease-in-out",
481
+ p: expanded ? 1 : 0.5,
482
+ width: "fit-content",
483
+ border: function border(theme) {
484
+ return "1px solid ".concat(theme.palette.divider);
485
+ },
486
+ mb: 1
487
+ },
488
+ onMouseEnter: function onMouseEnter() {
489
+ return setHover(true);
490
+ },
491
+ onMouseLeave: handleEndHover,
492
+ onKeyDown: function onKeyDown(e) {
493
+ return e.key === "Enter" && handleSubmit(e);
494
+ }
495
+ }, /*#__PURE__*/React.createElement(material.InputBase, {
496
+ placeholder: "Search",
497
+ value: search,
498
+ onChange: function onChange(e) {
499
+ isUserType.current = true;
500
+ setSearch(e.target.value);
501
+ },
502
+ sx: _objectSpread2({
503
+ ml: 1,
504
+ width: expanded ? "100%" : 0,
505
+ transition: "width 0.5s ease-in-out"
506
+ }, expanded ? {} : {
507
+ margin: 0
508
+ }),
509
+ onBlur: handleEndHover
510
+ }), /*#__PURE__*/React.createElement(material.Collapse, {
511
+ "in": Boolean(search),
512
+ orientation: "horizontal",
513
+ unmountOnExit: true
514
+ }, /*#__PURE__*/React.createElement(material.Stack, {
515
+ direction: "row",
516
+ alignItems: "center",
517
+ spacing: 0,
518
+ sx: {
519
+ mr: 3
520
+ }
521
+ }, /*#__PURE__*/React.createElement(material.IconButton, {
522
+ onClick: function onClick() {
523
+ isUserType.current = false;
524
+ setSearch("");
525
+ // Immediately clear instead of waiting for the debounce
526
+ onSubmit("");
527
+ }
528
+ }, /*#__PURE__*/React.createElement(iconsMaterial.Clear, null)), /*#__PURE__*/React.createElement(material.Divider, {
529
+ orientation: "vertical",
530
+ flexItem: true
531
+ }))), /*#__PURE__*/React.createElement(material.IconButton, {
532
+ onClick: handleSubmit,
533
+ type: "submit"
534
+ }, /*#__PURE__*/React.createElement(iconsMaterial.Search, null))));
535
+ }
536
+ FancySearch.propTypes = {
537
+ value: PropTypes.string,
538
+ onSubmit: PropTypes.func.isRequired
539
+ };
540
+
541
+ function SearchArea(props) {
542
+ var current = props.current,
543
+ setFinalVal = props.setFinalVal,
544
+ searchName = props.searchName,
545
+ persistSearch = props.persistSearch;
546
+ var searchVal = React.useMemo(function () {
547
+ if (current !== undefined && current !== null) return current;
548
+ if (persistSearch && searchName) {
549
+ var _sessionStorage$getIt;
550
+ return (_sessionStorage$getIt = sessionStorage.getItem("searchVal:".concat(searchName))) !== null && _sessionStorage$getIt !== void 0 ? _sessionStorage$getIt : "";
551
+ }
552
+ return "";
553
+ }, [current, persistSearch, searchName]);
554
+ return /*#__PURE__*/React.createElement("div", {
555
+ key: "SearchArea"
556
+ }, /*#__PURE__*/React.createElement(FancySearch, {
557
+ value: searchVal,
558
+ onSubmit: setFinalVal
559
+ }));
560
+ }
561
+ SearchArea.propTypes = {
562
+ current: PropTypes.string,
563
+ setFinalVal: PropTypes.func.isRequired,
564
+ searchName: PropTypes.string,
565
+ /** Persist search term to sessionStorage (requires searchName). Default: false */
566
+ persistSearch: PropTypes.bool
567
+ };
568
+
569
+ function TableToolbarContent(_ref) {
570
+ var setLoading = _ref.setLoading,
571
+ onReload = _ref.onReload,
572
+ reloadBtnLoading = _ref.reloadBtnLoading,
573
+ searchTerm = _ref.searchTerm,
574
+ onSearchChange = _ref.onSearchChange,
575
+ name = _ref.name,
576
+ persistSearch = _ref.persistSearch;
577
+ return /*#__PURE__*/React.createElement(material.Toolbar, {
578
+ sx: {
579
+ pl: {
580
+ sm: 2
581
+ },
582
+ pr: {
583
+ xs: 1,
584
+ sm: 1
585
+ },
586
+ pt: 2
587
+ }
588
+ }, /*#__PURE__*/React.createElement(material.Stack, {
589
+ spacing: 2,
590
+ direction: {
591
+ xs: "column",
592
+ md: "row"
593
+ },
594
+ sx: {
595
+ width: "100%",
596
+ alignItems: {
597
+ xs: "flex-start",
598
+ md: "center"
599
+ }
600
+ }
601
+ }, /*#__PURE__*/React.createElement(material.Box, {
602
+ sx: {
603
+ flex: "1 1 100%"
604
+ },
605
+ id: "tableTitle"
606
+ }, /*#__PURE__*/React.createElement(ReloadBtn, {
607
+ setLoading: setLoading,
608
+ onReload: onReload,
609
+ loading: reloadBtnLoading
610
+ })), /*#__PURE__*/React.createElement(SearchArea, {
611
+ current: searchTerm,
612
+ setFinalVal: onSearchChange,
613
+ searchName: name,
614
+ persistSearch: persistSearch
615
+ })));
616
+ }
617
+ TableToolbarContent.propTypes = {
618
+ setLoading: PropTypes.func,
619
+ onReload: PropTypes.func,
620
+ reloadBtnLoading: PropTypes.bool,
621
+ searchTerm: PropTypes.string,
622
+ onSearchChange: PropTypes.func.isRequired,
623
+ name: PropTypes.string,
624
+ persistSearch: PropTypes.bool
625
+ };
626
+
627
+ function useEnhancedTableState(_ref) {
628
+ var rows = _ref.rows,
629
+ subTable = _ref.subTable,
630
+ resetFlag = _ref.resetFlag;
631
+ var _React$useState = React.useState("asc"),
632
+ _React$useState2 = _slicedToArray(_React$useState, 2),
633
+ order = _React$useState2[0],
634
+ setOrder = _React$useState2[1];
635
+ var _React$useState3 = React.useState(""),
636
+ _React$useState4 = _slicedToArray(_React$useState3, 2),
637
+ orderBy = _React$useState4[0],
638
+ setOrderBy = _React$useState4[1];
639
+ var _React$useState5 = React.useState(function () {
640
+ return {
641
+ page: 0,
642
+ rowsPerPage: subTable ? rows.length : 5,
643
+ resetFlag: resetFlag
644
+ };
645
+ }),
646
+ _React$useState6 = _slicedToArray(_React$useState5, 2),
647
+ pagination = _React$useState6[0],
648
+ setPagination = _React$useState6[1];
649
+ React.useEffect(function () {
650
+ // eslint-disable-next-line react-hooks/set-state-in-effect
651
+ setPagination(function (previous) {
652
+ if (previous.resetFlag === resetFlag) {
653
+ return previous;
654
+ }
655
+ return _objectSpread2(_objectSpread2({}, previous), {}, {
656
+ page: 0,
657
+ resetFlag: resetFlag
658
+ });
659
+ });
660
+ }, [resetFlag]);
661
+ var page = pagination.page;
662
+ var rowsPerPage = subTable ? rows.length : pagination.rowsPerPage;
663
+ var handleRequestSort = React.useCallback(function (event, property) {
664
+ var isAsc = orderBy === property && order === "asc";
665
+ setOrder(isAsc ? "desc" : "asc");
666
+ setOrderBy(property);
667
+ }, [order, orderBy]);
668
+ var handleChangePage = React.useCallback(function (event, newPage) {
669
+ setPagination(function (previous) {
670
+ return _objectSpread2(_objectSpread2({}, previous), {}, {
671
+ page: newPage
672
+ });
673
+ });
674
+ }, []);
675
+ var handleChangeRowsPerPage = React.useCallback(function (event) {
676
+ setPagination(function (previous) {
677
+ return _objectSpread2(_objectSpread2({}, previous), {}, {
678
+ page: 0,
679
+ rowsPerPage: Number.parseInt(event.target.value, 10)
680
+ });
681
+ });
682
+ }, []);
683
+ return {
684
+ order: order,
685
+ orderBy: orderBy,
686
+ page: page,
687
+ rowsPerPage: rowsPerPage,
688
+ handleRequestSort: handleRequestSort,
689
+ handleChangePage: handleChangePage,
690
+ handleChangeRowsPerPage: handleChangeRowsPerPage
691
+ };
692
+ }
693
+
694
+ function EnhancedTableHead(props) {
695
+ var order = props.order,
696
+ orderBy = props.orderBy,
697
+ onRequestSort = props.onRequestSort,
698
+ selectRows = props.selectRows,
699
+ numSelected = props.numSelected,
700
+ rowCount = props.rowCount,
701
+ onSelectAllClick = props.onSelectAllClick;
702
+ var createSortHandler = function createSortHandler(property) {
703
+ return function (event) {
704
+ onRequestSort(event, property);
705
+ };
706
+ };
707
+ return /*#__PURE__*/React.createElement(material.TableHead, null, /*#__PURE__*/React.createElement(material.TableRow, null, selectRows && /*#__PURE__*/React.createElement(material.TableCell, {
708
+ padding: "checkbox"
709
+ }, /*#__PURE__*/React.createElement(material.Checkbox, {
710
+ color: "primary",
711
+ indeterminate: numSelected > 0 && numSelected < rowCount,
712
+ checked: rowCount > 0 && numSelected === rowCount,
713
+ onChange: onSelectAllClick
714
+ })), props.headings.map(function (headCell) {
715
+ return /*#__PURE__*/React.createElement(material.TableCell, {
716
+ key: headCell.id,
717
+ align: headCell.numeric ? "right" : "left",
718
+ padding: "normal",
719
+ sortDirection: orderBy === headCell.id ? order : false
720
+ }, /*#__PURE__*/React.createElement(material.TableSortLabel, {
721
+ active: orderBy === headCell.id,
722
+ direction: orderBy === headCell.id ? order : "asc",
723
+ onClick: createSortHandler(headCell.id)
724
+ }, headCell.label, orderBy === headCell.id ? /*#__PURE__*/React.createElement(material.Box, {
725
+ component: "span",
726
+ sx: visuallyHidden
727
+ }, order === "desc" ? "sorted descending" : "sorted ascending") : undefined));
728
+ })));
729
+ }
730
+ EnhancedTableHead.propTypes = {
731
+ onRequestSort: PropTypes.func.isRequired,
732
+ order: PropTypes.oneOf(["asc", "desc"]).isRequired,
733
+ orderBy: PropTypes.string.isRequired,
734
+ headings: PropTypes.array.isRequired,
735
+ selectRows: PropTypes.bool,
736
+ numSelected: PropTypes.number,
737
+ rowCount: PropTypes.number,
738
+ onSelectAllClick: PropTypes.func
739
+ };
740
+
741
+ /**
742
+ * Lazily import UniversalTable to statically break the circular dependency:
743
+ * UniversalTable → EnhancedTable → DataRow → SubTableRow → UniversalTable
744
+ * React.lazy resolves the import at render time, so the module graph stays acyclic.
745
+ */
746
+ var UniversalTable$2 = /*#__PURE__*/React.lazy(function () {
747
+ return Promise.resolve().then(function () { return UniversalTable$1; });
748
+ });
749
+
750
+ // ---------------------------------------------------------------------------
751
+ // SubRowToggleCell
752
+ // ---------------------------------------------------------------------------
753
+
754
+ function SubRowToggleCell(_ref) {
755
+ var header = _ref.header,
756
+ isOpen = _ref.isOpen,
757
+ onToggle = _ref.onToggle,
758
+ rowValues = _ref.rowValues,
759
+ hideBadge = _ref.hideBadge;
760
+ return /*#__PURE__*/React.createElement(material.TableCell, null, /*#__PURE__*/React.createElement(material.Tooltip, {
761
+ title: isOpen ? "Hide ".concat(header.id) : "Show ".concat(header.id)
762
+ }, /*#__PURE__*/React.createElement(material.Box, null, /*#__PURE__*/React.createElement(material.IconButton, {
763
+ onClick: function onClick(event) {
764
+ event.stopPropagation();
765
+ onToggle();
766
+ },
767
+ disabled: rowValues[header.id].length === 0,
768
+ color: header.iconColor || "secondary"
769
+ }, /*#__PURE__*/React.createElement(material.Badge, {
770
+ badgeContent: rowValues[header.id].length,
771
+ invisible: hideBadge,
772
+ anchorOrigin: {
773
+ vertical: "bottom",
774
+ horizontal: "right"
775
+ },
776
+ sx: {
777
+ "& .MuiBadge-badge": {
778
+ color: function color(theme) {
779
+ return theme.palette.text.primary;
780
+ }
781
+ }
782
+ }
783
+ }, isOpen ? (header === null || header === void 0 ? void 0 : header.closeIcon) || /*#__PURE__*/React.createElement(iconsMaterial.RemoveCircle, null) : (header === null || header === void 0 ? void 0 : header.openIcon) || /*#__PURE__*/React.createElement(iconsMaterial.AddCircle, null))))));
784
+ }
785
+ SubRowToggleCell.propTypes = {
786
+ header: PropTypes.object.isRequired,
787
+ isOpen: PropTypes.bool.isRequired,
788
+ onToggle: PropTypes.func.isRequired,
789
+ rowValues: PropTypes.object.isRequired,
790
+ hideBadge: PropTypes.bool
791
+ };
792
+
793
+ // ---------------------------------------------------------------------------
794
+ // SubTableRow
795
+ // ---------------------------------------------------------------------------
796
+
797
+ function SubTableRow(_ref2) {
798
+ var table = _ref2.table,
799
+ isOpen = _ref2.isOpen,
800
+ rowValues = _ref2.rowValues,
801
+ colSpan = _ref2.colSpan;
802
+ return /*#__PURE__*/React.createElement(material.TableRow, null, /*#__PURE__*/React.createElement(material.TableCell, {
803
+ colSpan: colSpan,
804
+ style: {
805
+ paddingBottom: 0,
806
+ paddingTop: 0
807
+ }
808
+ }, /*#__PURE__*/React.createElement(material.Collapse, {
809
+ "in": isOpen,
810
+ timeout: "auto",
811
+ unmountOnExit: true
812
+ }, /*#__PURE__*/React.createElement(React.Suspense, {
813
+ fallback: null
814
+ }, /*#__PURE__*/React.createElement(UniversalTable$2, {
815
+ loading: table.loading,
816
+ setLoading: table.setLoading,
817
+ onReload: table.onReload,
818
+ data: rowValues[table.id],
819
+ headers: table.headers,
820
+ name: table.subTitle,
821
+ subTable: true
822
+ })))));
823
+ }
824
+ SubTableRow.propTypes = {
825
+ table: PropTypes.object.isRequired,
826
+ isOpen: PropTypes.bool.isRequired,
827
+ rowValues: PropTypes.object.isRequired,
828
+ colSpan: PropTypes.number.isRequired
829
+ };
830
+
831
+ function renderDataCells(headers, rowValues) {
832
+ return headers.map(function (header, index) {
833
+ return /*#__PURE__*/React.createElement(material.TableCell, _extends({
834
+ key: header.id || index
835
+ }, header.cellProps), header.component ? header.component(rowValues) : formatCellValue(header, rowValues));
836
+ });
837
+ }
838
+ var DataRow = /*#__PURE__*/React.memo(function DataRow(props) {
839
+ var rowValues = props.rowValues,
840
+ headers = props.headers,
841
+ selectRows = props.selectRows,
842
+ isSelected = props.isSelected,
843
+ handleClick = props.handleClick;
844
+ var _React$useMemo = React.useMemo(function () {
845
+ return splitHeaders(headers);
846
+ }, [headers]),
847
+ subTables = _React$useMemo.subTables,
848
+ columns = _React$useMemo.columns;
849
+ var hideBadge = props.hideBadge || false;
850
+ var isItemSelected = isSelected(props.rowID);
851
+ var _React$useState = React.useState(Array.from({
852
+ length: subTables.length
853
+ }).fill(false)),
854
+ _React$useState2 = _slicedToArray(_React$useState, 2),
855
+ reveal = _React$useState2[0],
856
+ setReveal = _React$useState2[1];
857
+ var toggleSubRow = React.useCallback(function (index) {
858
+ setReveal(function (previous) {
859
+ var next = _toConsumableArray(previous);
860
+ next[index] = !next[index];
861
+ return next;
862
+ });
863
+ }, []);
864
+ var handleRowKeyDown = React.useCallback(function (event) {
865
+ if (selectRows && (event.key === " " || event.key === "Enter")) {
866
+ event.preventDefault();
867
+ handleClick(event, props.rowID);
868
+ }
869
+ }, [selectRows, handleClick, props.rowID]);
870
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(material.TableRow, {
871
+ tabIndex: selectRows ? 0 : -1,
872
+ hover: selectRows,
873
+ role: selectRows ? "checkbox" : "row",
874
+ selected: isItemSelected,
875
+ "aria-checked": isItemSelected,
876
+ onKeyDown: handleRowKeyDown
877
+ }, selectRows && /*#__PURE__*/React.createElement(material.TableCell, {
878
+ padding: "checkbox"
879
+ }, /*#__PURE__*/React.createElement(material.Checkbox, {
880
+ color: "primary",
881
+ checked: isItemSelected,
882
+ onClick: function onClick(event) {
883
+ return handleClick(event, props.rowID);
884
+ }
885
+ })), subTables.map(function (header, index) {
886
+ return /*#__PURE__*/React.createElement(SubRowToggleCell, {
887
+ key: header.id || index,
888
+ header: header,
889
+ isOpen: reveal[index],
890
+ onToggle: function onToggle() {
891
+ return toggleSubRow(index);
892
+ },
893
+ rowValues: rowValues,
894
+ hideBadge: hideBadge
895
+ });
896
+ }), renderDataCells(columns, rowValues)), subTables.map(function (table, index) {
897
+ return /*#__PURE__*/React.createElement(SubTableRow, {
898
+ key: table.id || index,
899
+ table: table,
900
+ isOpen: reveal[index],
901
+ rowValues: rowValues,
902
+ colSpan: props.headers.length + 1
903
+ });
904
+ }));
905
+ });
906
+ DataRow.propTypes = {
907
+ rowValues: PropTypes.object.isRequired,
908
+ headers: PropTypes.array.isRequired,
909
+ selectRows: PropTypes.bool,
910
+ isSelected: PropTypes.func.isRequired,
911
+ handleClick: PropTypes.func,
912
+ hideBadge: PropTypes.bool,
913
+ rowID: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired
914
+ };
915
+
916
+ var TableLoader = function TableLoader() {
917
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(material.TableHead, null), /*#__PURE__*/React.createElement(material.TableBody, null, Array.from({
918
+ length: 5
919
+ }).map(function (_, index) {
920
+ return /*#__PURE__*/React.createElement(material.TableRow, {
921
+ key: index
922
+ }, Array.from({
923
+ length: 4
924
+ }).map(function (_, cellIndex) {
925
+ return /*#__PURE__*/React.createElement(material.TableCell, {
926
+ key: cellIndex
927
+ }, /*#__PURE__*/React.createElement(material.Skeleton, {
928
+ height: 30
929
+ }));
930
+ }));
931
+ })));
932
+ };
933
+
934
+ function EnhancedTable(props) {
935
+ var headers = props.headers,
936
+ rows = props.rows,
937
+ subTable = props.subTable,
938
+ selected = props.selected,
939
+ selectID = props.selectID;
940
+ var _useEnhancedTableStat = useEnhancedTableState({
941
+ rows: rows,
942
+ subTable: subTable,
943
+ resetFlag: props.resetFlag
944
+ }),
945
+ order = _useEnhancedTableStat.order,
946
+ orderBy = _useEnhancedTableStat.orderBy,
947
+ page = _useEnhancedTableStat.page,
948
+ rowsPerPage = _useEnhancedTableStat.rowsPerPage,
949
+ handleRequestSort = _useEnhancedTableStat.handleRequestSort,
950
+ handleChangePage = _useEnhancedTableStat.handleChangePage,
951
+ handleChangeRowsPerPage = _useEnhancedTableStat.handleChangeRowsPerPage;
952
+ var emptyRows = Math.max(0, rowsPerPage - Math.min(rowsPerPage, rows.length - page * rowsPerPage));
953
+ var isSelected = React.useCallback(function (id) {
954
+ return selected.includes(id);
955
+ }, [selected]);
956
+ var visibleRows = React.useMemo(function () {
957
+ return stableSort(rows, getComparator(order, orderBy), headers).slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);
958
+ }, [headers, order, orderBy, page, rows, rowsPerPage]);
959
+ return /*#__PURE__*/React.createElement(material.TableContainer, null, /*#__PURE__*/React.createElement(material.Table, {
960
+ sx: {
961
+ minWidth: 750
962
+ },
963
+ size: "small" ,
964
+ "aria-label": props.name || "data table"
965
+ }, props.loading ? /*#__PURE__*/React.createElement(TableLoader, null) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(EnhancedTableHead, {
966
+ order: order,
967
+ orderBy: orderBy,
968
+ onRequestSort: handleRequestSort,
969
+ headings: headers,
970
+ selectRows: props.selectRows,
971
+ numSelected: selected.length,
972
+ rowCount: rows.length,
973
+ onSelectAllClick: props.handleSelectAllClick
974
+ }), /*#__PURE__*/React.createElement(material.TableBody, null, visibleRows.map(function (row, index) {
975
+ var rowKey = selectID ? row[selectID] : "row-".concat(page * rowsPerPage + index);
976
+ var rowID = getSelectableRowId(row, index, selectID);
977
+ return /*#__PURE__*/React.createElement(DataRow, {
978
+ key: rowKey,
979
+ rowID: rowID,
980
+ headers: headers,
981
+ rowValues: row,
982
+ hideBadge: props.hideBadge,
983
+ selectRows: props.selectRows,
984
+ handleClick: props.handleClick,
985
+ isSelected: isSelected
986
+ });
987
+ }), !subTable && emptyRows > 0 && /*#__PURE__*/React.createElement(material.TableRow, {
988
+ style: {
989
+ height: (33 ) * emptyRows
990
+ }
991
+ }, /*#__PURE__*/React.createElement(material.TableCell, {
992
+ colSpan: headers.length
993
+ }))))), subTable ? /*#__PURE__*/React.createElement(material.Box, {
994
+ sx: {
995
+ mb: 3
996
+ }
997
+ }) : /*#__PURE__*/React.createElement(material.TablePagination, {
998
+ rowsPerPageOptions: props.pageSizeOptions || getPageOptions(rows.length),
999
+ component: "div",
1000
+ count: rows.length,
1001
+ rowsPerPage: rowsPerPage,
1002
+ page: page,
1003
+ onPageChange: handleChangePage,
1004
+ onRowsPerPageChange: handleChangeRowsPerPage,
1005
+ sx: {
1006
+ overflow: "visible"
1007
+ },
1008
+ showFirstButton: true,
1009
+ showLastButton: true
1010
+ }));
1011
+ }
1012
+ EnhancedTable.propTypes = {
1013
+ headers: PropTypes.array.isRequired,
1014
+ rows: PropTypes.array.isRequired,
1015
+ subTable: PropTypes.bool,
1016
+ hideBadge: PropTypes.bool,
1017
+ loading: PropTypes.bool,
1018
+ selectRows: PropTypes.bool,
1019
+ handleSelectAllClick: PropTypes.func,
1020
+ handleClick: PropTypes.func,
1021
+ selected: PropTypes.array,
1022
+ selectID: PropTypes.string,
1023
+ resetFlag: PropTypes.string,
1024
+ pageSizeOptions: PropTypes.arrayOf(PropTypes.number),
1025
+ name: PropTypes.string
1026
+ };
1027
+
1028
+ function UniversalTable(_ref) {
1029
+ var loading = _ref.loading,
1030
+ setLoading = _ref.setLoading,
1031
+ onReload = _ref.onReload,
1032
+ _ref$lazyloading = _ref.lazyloading,
1033
+ lazyloading = _ref$lazyloading === void 0 ? false : _ref$lazyloading,
1034
+ currentPage = _ref.currentPage,
1035
+ totalPages = _ref.totalPages,
1036
+ data = _ref.data,
1037
+ headers = _ref.headers,
1038
+ name = _ref.name,
1039
+ reloadBtnLoading = _ref.reloadBtnLoading,
1040
+ _ref$subTable = _ref.subTable,
1041
+ subTable = _ref$subTable === void 0 ? false : _ref$subTable,
1042
+ _ref$hideBadge = _ref.hideBadge,
1043
+ hideBadge = _ref$hideBadge === void 0 ? false : _ref$hideBadge,
1044
+ _ref$selectRows = _ref.selectRows,
1045
+ selectRows = _ref$selectRows === void 0 ? false : _ref$selectRows,
1046
+ selectID = _ref.selectID,
1047
+ selectIcon = _ref.selectIcon,
1048
+ onSelection = _ref.onSelection,
1049
+ pageSizeOptions = _ref.pageSizeOptions,
1050
+ persistSearch = _ref.persistSearch;
1051
+ var head = headers || [];
1052
+ var _useSearchableRows = useSearchableRows(data, head),
1053
+ rows = _useSearchableRows.rows,
1054
+ searchTerm = _useSearchableRows.searchTerm,
1055
+ setSearchTerm = _useSearchableRows.setSearchTerm;
1056
+ var _useSelectableRows = useSelectableRows({
1057
+ rows: rows,
1058
+ selectRows: selectRows,
1059
+ selectID: selectID
1060
+ }),
1061
+ selected = _useSelectableRows.selected,
1062
+ clearSelection = _useSelectableRows.clearSelection,
1063
+ handleSelectAllClick = _useSelectableRows.handleSelectAllClick,
1064
+ handleClick = _useSelectableRows.handleClick;
1065
+ var handleSearchChange = React.useCallback(function (value) {
1066
+ clearSelection();
1067
+ setSearchTerm(value);
1068
+ }, [clearSelection, setSearchTerm]);
1069
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(LazyLoadingIndicator, {
1070
+ show: lazyloading,
1071
+ currentPage: currentPage,
1072
+ totalPages: totalPages
1073
+ }), /*#__PURE__*/React.createElement(Paper, {
1074
+ sx: _objectSpread2({}, subTable && {
1075
+ boxShadow: "none"
1076
+ })
1077
+ }, /*#__PURE__*/React.createElement(TableSelectionBanner, {
1078
+ selected: selected,
1079
+ onSelection: onSelection,
1080
+ selectIcon: selectIcon
1081
+ }), /*#__PURE__*/React.createElement(TableTitle, {
1082
+ name: name,
1083
+ subTable: subTable
1084
+ }), !subTable && /*#__PURE__*/React.createElement(TableToolbarContent, {
1085
+ setLoading: setLoading,
1086
+ onReload: onReload,
1087
+ reloadBtnLoading: reloadBtnLoading,
1088
+ searchTerm: searchTerm,
1089
+ onSearchChange: handleSearchChange,
1090
+ name: name,
1091
+ persistSearch: persistSearch
1092
+ }), /*#__PURE__*/React.createElement(EnhancedTable, {
1093
+ headers: head,
1094
+ rows: rows,
1095
+ resetFlag: searchTerm,
1096
+ subTable: subTable,
1097
+ hideBadge: hideBadge,
1098
+ loading: loading,
1099
+ selectRows: selectRows,
1100
+ handleSelectAllClick: handleSelectAllClick,
1101
+ handleClick: handleClick,
1102
+ selected: selected,
1103
+ selectID: selectID,
1104
+ pageSizeOptions: pageSizeOptions,
1105
+ name: name
1106
+ })));
1107
+ }
1108
+ UniversalTable.propTypes = {
1109
+ loading: PropTypes.bool,
1110
+ setLoading: PropTypes.func,
1111
+ /** Preferred callback — fires when the user clicks reload. */
1112
+ onReload: PropTypes.func,
1113
+ lazyloading: PropTypes.bool,
1114
+ currentPage: PropTypes.number,
1115
+ totalPages: PropTypes.number,
1116
+ data: PropTypes.array.isRequired,
1117
+ headers: PropTypes.array.isRequired,
1118
+ name: PropTypes.string,
1119
+ reloadBtnLoading: PropTypes.bool,
1120
+ subTable: PropTypes.bool,
1121
+ hideBadge: PropTypes.bool,
1122
+ selectRows: PropTypes.bool,
1123
+ selectID: PropTypes.string,
1124
+ selectIcon: PropTypes.element,
1125
+ onSelection: PropTypes.func,
1126
+ /** Override default page size options (e.g. [10, 25, 50]). Default auto-computed. */
1127
+ pageSizeOptions: PropTypes.arrayOf(PropTypes.number),
1128
+ /** Persist search term to sessionStorage (requires name prop). Default: false */
1129
+ persistSearch: PropTypes.bool
1130
+ };
1131
+
1132
+ var UniversalTable$1 = /*#__PURE__*/Object.freeze({
1133
+ __proto__: null,
1134
+ default: UniversalTable
1135
+ });
1136
+
1137
+ exports.UniversalTable = UniversalTable;
1138
+ exports.default = UniversalTable;
1139
+ //# sourceMappingURL=index.js.map