mui-universal-table 1.0.7 → 1.0.9

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.esm.js CHANGED
@@ -254,12 +254,15 @@ function formatCellValue(header, rowValues) {
254
254
  }
255
255
  return browserDateTimeFormatter.format(d);
256
256
  }
257
- function stableSort(array, comparator, headers) {
257
+ function stableSort(array, comparator, headers, orderBy) {
258
258
  var dateColumns = new Set(headers.filter(function (object) {
259
259
  return object.date;
260
260
  }).map(function (value) {
261
261
  return value.id;
262
262
  }));
263
+ var findHeader = headers.find(function (header) {
264
+ return header.id === orderBy;
265
+ });
263
266
 
264
267
  // Build stable entries — compare pre-computed sort keys so we never
265
268
  // mutate the original data or its shallow copies.
@@ -280,17 +283,19 @@ function stableSort(array, comparator, headers) {
280
283
  }
281
284
  return [el, sortKey, index];
282
285
  });
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
- });
286
+ if ((findHeader === null || findHeader === void 0 ? void 0 : findHeader.sortable) === undefined || (findHeader === null || findHeader === void 0 ? void 0 : findHeader.sortable) === false) {
287
+ stabilizedThis.sort(function (a, b) {
288
+ var order = comparator(a[1], b[1]);
289
+ if (order !== 0) return order;
290
+ return a[2] - b[2];
291
+ });
292
+ }
288
293
  return stabilizedThis.map(function (el) {
289
294
  return el[0];
290
295
  });
291
296
  }
292
297
 
293
- function useSearchableRows(data, headers) {
298
+ function useSearchableRows(data, headers, async) {
294
299
  var _React$useState = React.useState(""),
295
300
  _React$useState2 = _slicedToArray(_React$useState, 2),
296
301
  searchTerm = _React$useState2[0],
@@ -299,8 +304,8 @@ function useSearchableRows(data, headers) {
299
304
  return getSearchableColumnIds(headers);
300
305
  }, [headers]);
301
306
  var rows = React.useMemo(function () {
302
- return filterRows(data, searchTerm, filterOptions);
303
- }, [data, filterOptions, searchTerm]);
307
+ return async ? data : filterRows(data, searchTerm, filterOptions);
308
+ }, [async, data, filterOptions, searchTerm]);
304
309
  return {
305
310
  rows: rows,
306
311
  searchTerm: searchTerm,
@@ -399,18 +404,15 @@ TableTitle.propTypes = {
399
404
  };
400
405
 
401
406
  function ReloadBtn(_ref) {
402
- var setLoading = _ref.setLoading,
403
- loading = _ref.loading,
407
+ var loading = _ref.loading,
404
408
  onReload = _ref.onReload;
405
- var canReload = typeof onReload === "function" || typeof setLoading === "function";
409
+ var canReload = typeof onReload === "function";
406
410
  if (!canReload) {
407
411
  return null;
408
412
  }
409
413
  var handleClick = function handleClick() {
410
414
  if (typeof onReload === "function") {
411
415
  onReload();
412
- } else if (typeof setLoading === "function") {
413
- setLoading(true);
414
416
  }
415
417
  };
416
418
  return /*#__PURE__*/React.createElement(Tooltip, {
@@ -423,7 +425,6 @@ function ReloadBtn(_ref) {
423
425
  }, /*#__PURE__*/React.createElement(RefreshIcon, null)));
424
426
  }
425
427
  ReloadBtn.propTypes = {
426
- setLoading: PropTypes.func,
427
428
  loading: PropTypes.bool,
428
429
  /** Preferred callback — fires when the user clicks reload. */
429
430
  onReload: PropTypes.func
@@ -432,18 +433,14 @@ ReloadBtn.propTypes = {
432
433
  function FancySearch(_ref) {
433
434
  var value = _ref.value,
434
435
  onSubmit = _ref.onSubmit;
435
- var _React$useState = React.useState(value),
436
+ var _React$useState = React.useState(Boolean(value)),
436
437
  _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);
438
+ hover = _React$useState2[0],
439
+ setHover = _React$useState2[1];
440
+ var expanded = hover || Boolean(value);
444
441
  var handleSubmit = function handleSubmit(e) {
445
442
  e.preventDefault();
446
- onSubmit(search);
443
+ onSubmit(value);
447
444
  };
448
445
  var handleEndHover = function handleEndHover() {
449
446
  setHover(false);
@@ -453,22 +450,6 @@ function FancySearch(_ref) {
453
450
  // A ref tracks whether this sync came from the user typing or from a parent
454
451
  // update, so the debounce only fires for genuine user input.
455
452
  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
453
  return /*#__PURE__*/React.createElement("form", {
473
454
  onSubmit: handleSubmit
474
455
  }, /*#__PURE__*/React.createElement(Paper, {
@@ -494,10 +475,10 @@ function FancySearch(_ref) {
494
475
  }
495
476
  }, /*#__PURE__*/React.createElement(InputBase, {
496
477
  placeholder: "Search",
497
- value: search,
478
+ value: value,
498
479
  onChange: function onChange(e) {
499
480
  isUserType.current = true;
500
- setSearch(e.target.value);
481
+ onSubmit(e.target.value);
501
482
  },
502
483
  sx: _objectSpread2({
503
484
  ml: 1,
@@ -508,7 +489,7 @@ function FancySearch(_ref) {
508
489
  }),
509
490
  onBlur: handleEndHover
510
491
  }), /*#__PURE__*/React.createElement(Collapse, {
511
- "in": Boolean(search),
492
+ "in": Boolean(value),
512
493
  orientation: "horizontal",
513
494
  unmountOnExit: true
514
495
  }, /*#__PURE__*/React.createElement(Stack, {
@@ -521,7 +502,6 @@ function FancySearch(_ref) {
521
502
  }, /*#__PURE__*/React.createElement(IconButton, {
522
503
  onClick: function onClick() {
523
504
  isUserType.current = false;
524
- setSearch("");
525
505
  // Immediately clear instead of waiting for the debounce
526
506
  onSubmit("");
527
507
  }
@@ -567,8 +547,7 @@ SearchArea.propTypes = {
567
547
  };
568
548
 
569
549
  function TableToolbarContent(_ref) {
570
- var setLoading = _ref.setLoading,
571
- onReload = _ref.onReload,
550
+ var onReload = _ref.onReload,
572
551
  reloadBtnLoading = _ref.reloadBtnLoading,
573
552
  searchTerm = _ref.searchTerm,
574
553
  onSearchChange = _ref.onSearchChange,
@@ -604,7 +583,6 @@ function TableToolbarContent(_ref) {
604
583
  },
605
584
  id: "tableTitle"
606
585
  }, /*#__PURE__*/React.createElement(ReloadBtn, {
607
- setLoading: setLoading,
608
586
  onReload: onReload,
609
587
  loading: reloadBtnLoading
610
588
  })), /*#__PURE__*/React.createElement(SearchArea, {
@@ -615,7 +593,6 @@ function TableToolbarContent(_ref) {
615
593
  })));
616
594
  }
617
595
  TableToolbarContent.propTypes = {
618
- setLoading: PropTypes.func,
619
596
  onReload: PropTypes.func,
620
597
  reloadBtnLoading: PropTypes.bool,
621
598
  searchTerm: PropTypes.string,
@@ -627,25 +604,24 @@ TableToolbarContent.propTypes = {
627
604
  function useEnhancedTableState(_ref) {
628
605
  var rows = _ref.rows,
629
606
  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 () {
607
+ resetFlag = _ref.resetFlag,
608
+ apiCall = _ref.apiCall,
609
+ searchTerm = _ref.searchTerm,
610
+ setOrder = _ref.setOrder,
611
+ setOrderBy = _ref.setOrderBy,
612
+ order = _ref.order,
613
+ orderBy = _ref.orderBy,
614
+ asyncPages = _ref.asyncPages;
615
+ var _React$useState = React.useState(function () {
640
616
  return {
641
617
  page: 0,
642
618
  rowsPerPage: subTable ? rows.length : 5,
643
619
  resetFlag: resetFlag
644
620
  };
645
621
  }),
646
- _React$useState6 = _slicedToArray(_React$useState5, 2),
647
- pagination = _React$useState6[0],
648
- setPagination = _React$useState6[1];
622
+ _React$useState2 = _slicedToArray(_React$useState, 2),
623
+ pagination = _React$useState2[0],
624
+ setPagination = _React$useState2[1];
649
625
  React.useEffect(function () {
650
626
  // eslint-disable-next-line react-hooks/set-state-in-effect
651
627
  setPagination(function (previous) {
@@ -660,11 +636,11 @@ function useEnhancedTableState(_ref) {
660
636
  }, [resetFlag]);
661
637
  var page = pagination.page;
662
638
  var rowsPerPage = subTable ? rows.length : pagination.rowsPerPage;
663
- var handleRequestSort = React.useCallback(function (event, property) {
639
+ var handleRequestSort = React.useCallback(function (property) {
664
640
  var isAsc = orderBy === property && order === "asc";
665
641
  setOrder(isAsc ? "desc" : "asc");
666
642
  setOrderBy(property);
667
- }, [order, orderBy]);
643
+ }, [order, orderBy, setOrder, setOrderBy]);
668
644
  var handleChangePage = React.useCallback(function (event, newPage) {
669
645
  setPagination(function (previous) {
670
646
  return _objectSpread2(_objectSpread2({}, previous), {}, {
@@ -680,14 +656,29 @@ function useEnhancedTableState(_ref) {
680
656
  });
681
657
  });
682
658
  }, []);
659
+ var handleSort = function handleSort(column, apiSortable) {
660
+ if (apiSortable) {
661
+ var direction = order === "asc" ? "desc" : "asc";
662
+ apiCall({
663
+ searchTerm: searchTerm,
664
+ column: column,
665
+ direction: direction,
666
+ pages: asyncPages !== null && asyncPages !== void 0 ? asyncPages : 1
667
+ });
668
+ setOrder(direction);
669
+ setOrderBy(column);
670
+ return;
671
+ }
672
+ handleRequestSort(column);
673
+ };
683
674
  return {
684
675
  order: order,
685
676
  orderBy: orderBy,
686
677
  page: page,
687
678
  rowsPerPage: rowsPerPage,
688
- handleRequestSort: handleRequestSort,
689
679
  handleChangePage: handleChangePage,
690
- handleChangeRowsPerPage: handleChangeRowsPerPage
680
+ handleChangeRowsPerPage: handleChangeRowsPerPage,
681
+ handleSort: handleSort
691
682
  };
692
683
  }
693
684
 
@@ -698,12 +689,8 @@ function EnhancedTableHead(props) {
698
689
  selectRows = props.selectRows,
699
690
  numSelected = props.numSelected,
700
691
  rowCount = props.rowCount,
701
- onSelectAllClick = props.onSelectAllClick;
702
- var createSortHandler = function createSortHandler(property) {
703
- return function (event) {
704
- onRequestSort(event, property);
705
- };
706
- };
692
+ onSelectAllClick = props.onSelectAllClick,
693
+ async = props.async;
707
694
  return /*#__PURE__*/React.createElement(TableHead, null, /*#__PURE__*/React.createElement(TableRow, null, selectRows && /*#__PURE__*/React.createElement(TableCell, {
708
695
  padding: "checkbox"
709
696
  }, /*#__PURE__*/React.createElement(Checkbox, {
@@ -720,7 +707,9 @@ function EnhancedTableHead(props) {
720
707
  }, /*#__PURE__*/React.createElement(TableSortLabel, {
721
708
  active: orderBy === headCell.id,
722
709
  direction: orderBy === headCell.id ? order : "asc",
723
- onClick: createSortHandler(headCell.id),
710
+ onClick: function onClick() {
711
+ return onRequestSort(headCell.id, headCell.sortable && async);
712
+ },
724
713
  disabled: headCell.subRow
725
714
  }, headCell.label, orderBy === headCell.id ? /*#__PURE__*/React.createElement(Box, {
726
715
  component: "span",
@@ -736,7 +725,8 @@ EnhancedTableHead.propTypes = {
736
725
  selectRows: PropTypes.bool,
737
726
  numSelected: PropTypes.number,
738
727
  rowCount: PropTypes.number,
739
- onSelectAllClick: PropTypes.func
728
+ onSelectAllClick: PropTypes.func,
729
+ async: PropTypes.bool
740
730
  };
741
731
 
742
732
  /**
@@ -937,17 +927,30 @@ function EnhancedTable(props) {
937
927
  rows = props.rows,
938
928
  subTable = props.subTable,
939
929
  selected = props.selected,
940
- selectID = props.selectID;
930
+ selectID = props.selectID,
931
+ setLoading = props.setLoading,
932
+ searchTerm = props.searchTerm,
933
+ setOrder = props.setOrder,
934
+ setOrderBy = props.setOrderBy,
935
+ order = props.order,
936
+ orderBy = props.orderBy,
937
+ async = props.async,
938
+ asyncPages = props.asyncPages;
941
939
  var _useEnhancedTableStat = useEnhancedTableState({
942
940
  rows: rows,
943
941
  subTable: subTable,
944
- resetFlag: props.resetFlag
942
+ resetFlag: props.resetFlag,
943
+ apiCall: setLoading,
944
+ searchTerm: searchTerm,
945
+ setOrder: setOrder,
946
+ setOrderBy: setOrderBy,
947
+ order: order,
948
+ orderBy: orderBy,
949
+ asyncPages: asyncPages
945
950
  }),
946
- order = _useEnhancedTableStat.order,
947
- orderBy = _useEnhancedTableStat.orderBy,
948
951
  page = _useEnhancedTableStat.page,
949
952
  rowsPerPage = _useEnhancedTableStat.rowsPerPage,
950
- handleRequestSort = _useEnhancedTableStat.handleRequestSort,
953
+ handleSort = _useEnhancedTableStat.handleSort,
951
954
  handleChangePage = _useEnhancedTableStat.handleChangePage,
952
955
  handleChangeRowsPerPage = _useEnhancedTableStat.handleChangeRowsPerPage;
953
956
  var emptyRows = Math.max(0, rowsPerPage - Math.min(rowsPerPage, rows.length - page * rowsPerPage));
@@ -955,7 +958,7 @@ function EnhancedTable(props) {
955
958
  return selected.includes(id);
956
959
  }, [selected]);
957
960
  var visibleRows = React.useMemo(function () {
958
- return stableSort(rows, getComparator(order, orderBy), headers).slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);
961
+ return stableSort(rows, getComparator(order, orderBy), headers, orderBy).slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);
959
962
  }, [headers, order, orderBy, page, rows, rowsPerPage]);
960
963
  return /*#__PURE__*/React.createElement(TableContainer, null, /*#__PURE__*/React.createElement(Table, {
961
964
  sx: {
@@ -966,12 +969,13 @@ function EnhancedTable(props) {
966
969
  }, props.loading ? /*#__PURE__*/React.createElement(TableLoader, null) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(EnhancedTableHead, {
967
970
  order: order,
968
971
  orderBy: orderBy,
969
- onRequestSort: handleRequestSort,
972
+ onRequestSort: handleSort,
970
973
  headings: headers,
971
974
  selectRows: props.selectRows,
972
975
  numSelected: selected.length,
973
976
  rowCount: rows.length,
974
- onSelectAllClick: props.handleSelectAllClick
977
+ onSelectAllClick: props.handleSelectAllClick,
978
+ async: async
975
979
  }), /*#__PURE__*/React.createElement(TableBody, null, visibleRows.map(function (row, index) {
976
980
  var rowKey = selectID ? row[selectID] : "row-".concat(page * rowsPerPage + index);
977
981
  var rowID = getSelectableRowId(row, index, selectID);
@@ -1021,9 +1025,17 @@ EnhancedTable.propTypes = {
1021
1025
  handleClick: PropTypes.func,
1022
1026
  selected: PropTypes.array,
1023
1027
  selectID: PropTypes.string,
1028
+ async: PropTypes.bool,
1024
1029
  resetFlag: PropTypes.string,
1025
1030
  pageSizeOptions: PropTypes.arrayOf(PropTypes.number),
1026
- name: PropTypes.string
1031
+ name: PropTypes.string,
1032
+ setLoading: PropTypes.func,
1033
+ searchTerm: PropTypes.string,
1034
+ setOrder: PropTypes.func,
1035
+ setOrderBy: PropTypes.func,
1036
+ order: PropTypes.string,
1037
+ orderBy: PropTypes.string,
1038
+ asyncPages: PropTypes.number
1027
1039
  };
1028
1040
 
1029
1041
  function UniversalTable(_ref) {
@@ -1048,12 +1060,23 @@ function UniversalTable(_ref) {
1048
1060
  selectIcon = _ref.selectIcon,
1049
1061
  onSelection = _ref.onSelection,
1050
1062
  pageSizeOptions = _ref.pageSizeOptions,
1051
- persistSearch = _ref.persistSearch;
1063
+ persistSearch = _ref.persistSearch,
1064
+ asyncPages = _ref.asyncPages;
1065
+ var debounceRef = React.useRef(null);
1066
+ var async = typeof asyncPages === "number" && asyncPages > 0;
1052
1067
  var head = headers || [];
1053
- var _useSearchableRows = useSearchableRows(data, head),
1068
+ var _useSearchableRows = useSearchableRows(data, head, async),
1054
1069
  rows = _useSearchableRows.rows,
1055
1070
  searchTerm = _useSearchableRows.searchTerm,
1056
1071
  setSearchTerm = _useSearchableRows.setSearchTerm;
1072
+ var _React$useState = React.useState("asc"),
1073
+ _React$useState2 = _slicedToArray(_React$useState, 2),
1074
+ order = _React$useState2[0],
1075
+ setOrder = _React$useState2[1];
1076
+ var _React$useState3 = React.useState(""),
1077
+ _React$useState4 = _slicedToArray(_React$useState3, 2),
1078
+ orderBy = _React$useState4[0],
1079
+ setOrderBy = _React$useState4[1];
1057
1080
  var _useSelectableRows = useSelectableRows({
1058
1081
  rows: rows,
1059
1082
  selectRows: selectRows,
@@ -1067,6 +1090,41 @@ function UniversalTable(_ref) {
1067
1090
  clearSelection();
1068
1091
  setSearchTerm(value);
1069
1092
  }, [clearSelection, setSearchTerm]);
1093
+ var handleSearch = function handleSearch(searchValue) {
1094
+ if (async) {
1095
+ setSearchTerm(searchValue);
1096
+ clearTimeout(debounceRef.current);
1097
+ debounceRef.current = setTimeout(function () {
1098
+ setLoading({
1099
+ searchTerm: searchValue,
1100
+ direction: order,
1101
+ column: orderBy,
1102
+ pages: asyncPages
1103
+ });
1104
+ }, 500);
1105
+ } else {
1106
+ handleSearchChange(searchValue);
1107
+ }
1108
+ };
1109
+ React.useEffect(function () {
1110
+ return function () {
1111
+ return clearTimeout(debounceRef.current);
1112
+ };
1113
+ }, []);
1114
+ var handleReload = React.useCallback(function () {
1115
+ if (typeof onReload === "function") {
1116
+ onReload();
1117
+ return;
1118
+ }
1119
+ if (typeof setLoading === "function") {
1120
+ setLoading(async ? {
1121
+ searchTerm: searchTerm,
1122
+ direction: order,
1123
+ column: orderBy,
1124
+ pages: asyncPages
1125
+ } : true);
1126
+ }
1127
+ }, [async, onReload, setLoading, searchTerm, order, orderBy, asyncPages]);
1070
1128
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(LazyLoadingIndicator, {
1071
1129
  show: lazyloading,
1072
1130
  currentPage: currentPage,
@@ -1083,17 +1141,17 @@ function UniversalTable(_ref) {
1083
1141
  name: name,
1084
1142
  subTable: subTable
1085
1143
  }), !subTable && /*#__PURE__*/React.createElement(TableToolbarContent, {
1086
- setLoading: setLoading,
1087
- onReload: onReload,
1144
+ onReload: typeof onReload === "function" || typeof setLoading === "function" ? handleReload : undefined,
1088
1145
  reloadBtnLoading: reloadBtnLoading,
1089
1146
  searchTerm: searchTerm,
1090
- onSearchChange: handleSearchChange,
1147
+ onSearchChange: handleSearch,
1091
1148
  name: name,
1092
1149
  persistSearch: persistSearch
1093
1150
  }), /*#__PURE__*/React.createElement(EnhancedTable, {
1094
1151
  headers: head,
1095
1152
  rows: rows,
1096
1153
  resetFlag: searchTerm,
1154
+ searchTerm: searchTerm,
1097
1155
  subTable: subTable,
1098
1156
  hideBadge: hideBadge,
1099
1157
  loading: loading,
@@ -1103,7 +1161,14 @@ function UniversalTable(_ref) {
1103
1161
  selected: selected,
1104
1162
  selectID: selectID,
1105
1163
  pageSizeOptions: pageSizeOptions,
1106
- name: name
1164
+ name: name,
1165
+ setLoading: setLoading,
1166
+ order: order,
1167
+ orderBy: orderBy,
1168
+ setOrder: setOrder,
1169
+ setOrderBy: setOrderBy,
1170
+ asyncPages: asyncPages,
1171
+ async: async
1107
1172
  })));
1108
1173
  }
1109
1174
  UniversalTable.propTypes = {
@@ -1127,7 +1192,8 @@ UniversalTable.propTypes = {
1127
1192
  /** Override default page size options (e.g. [10, 25, 50]). Default auto-computed. */
1128
1193
  pageSizeOptions: PropTypes.arrayOf(PropTypes.number),
1129
1194
  /** Persist search term to sessionStorage (requires name prop). Default: false */
1130
- persistSearch: PropTypes.bool
1195
+ persistSearch: PropTypes.bool,
1196
+ asyncPages: PropTypes.number
1131
1197
  };
1132
1198
 
1133
1199
  var UniversalTable$1 = /*#__PURE__*/Object.freeze({