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.js CHANGED
@@ -258,12 +258,15 @@ function formatCellValue(header, rowValues) {
258
258
  }
259
259
  return browserDateTimeFormatter.format(d);
260
260
  }
261
- function stableSort(array, comparator, headers) {
261
+ function stableSort(array, comparator, headers, orderBy) {
262
262
  var dateColumns = new Set(headers.filter(function (object) {
263
263
  return object.date;
264
264
  }).map(function (value) {
265
265
  return value.id;
266
266
  }));
267
+ var findHeader = headers.find(function (header) {
268
+ return header.id === orderBy;
269
+ });
267
270
 
268
271
  // Build stable entries — compare pre-computed sort keys so we never
269
272
  // mutate the original data or its shallow copies.
@@ -284,17 +287,19 @@ function stableSort(array, comparator, headers) {
284
287
  }
285
288
  return [el, sortKey, index];
286
289
  });
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
- });
290
+ if ((findHeader === null || findHeader === void 0 ? void 0 : findHeader.sortable) === undefined || (findHeader === null || findHeader === void 0 ? void 0 : findHeader.sortable) === false) {
291
+ stabilizedThis.sort(function (a, b) {
292
+ var order = comparator(a[1], b[1]);
293
+ if (order !== 0) return order;
294
+ return a[2] - b[2];
295
+ });
296
+ }
292
297
  return stabilizedThis.map(function (el) {
293
298
  return el[0];
294
299
  });
295
300
  }
296
301
 
297
- function useSearchableRows(data, headers) {
302
+ function useSearchableRows(data, headers, async) {
298
303
  var _React$useState = React.useState(""),
299
304
  _React$useState2 = _slicedToArray(_React$useState, 2),
300
305
  searchTerm = _React$useState2[0],
@@ -303,8 +308,8 @@ function useSearchableRows(data, headers) {
303
308
  return getSearchableColumnIds(headers);
304
309
  }, [headers]);
305
310
  var rows = React.useMemo(function () {
306
- return filterRows(data, searchTerm, filterOptions);
307
- }, [data, filterOptions, searchTerm]);
311
+ return async ? data : filterRows(data, searchTerm, filterOptions);
312
+ }, [async, data, filterOptions, searchTerm]);
308
313
  return {
309
314
  rows: rows,
310
315
  searchTerm: searchTerm,
@@ -403,18 +408,15 @@ TableTitle.propTypes = {
403
408
  };
404
409
 
405
410
  function ReloadBtn(_ref) {
406
- var setLoading = _ref.setLoading,
407
- loading = _ref.loading,
411
+ var loading = _ref.loading,
408
412
  onReload = _ref.onReload;
409
- var canReload = typeof onReload === "function" || typeof setLoading === "function";
413
+ var canReload = typeof onReload === "function";
410
414
  if (!canReload) {
411
415
  return null;
412
416
  }
413
417
  var handleClick = function handleClick() {
414
418
  if (typeof onReload === "function") {
415
419
  onReload();
416
- } else if (typeof setLoading === "function") {
417
- setLoading(true);
418
420
  }
419
421
  };
420
422
  return /*#__PURE__*/React.createElement(material.Tooltip, {
@@ -427,7 +429,6 @@ function ReloadBtn(_ref) {
427
429
  }, /*#__PURE__*/React.createElement(RefreshIcon, null)));
428
430
  }
429
431
  ReloadBtn.propTypes = {
430
- setLoading: PropTypes.func,
431
432
  loading: PropTypes.bool,
432
433
  /** Preferred callback — fires when the user clicks reload. */
433
434
  onReload: PropTypes.func
@@ -436,18 +437,14 @@ ReloadBtn.propTypes = {
436
437
  function FancySearch(_ref) {
437
438
  var value = _ref.value,
438
439
  onSubmit = _ref.onSubmit;
439
- var _React$useState = React.useState(value),
440
+ var _React$useState = React.useState(Boolean(value)),
440
441
  _React$useState2 = _slicedToArray(_React$useState, 2),
441
- search = _React$useState2[0],
442
- setSearch = _React$useState2[1];
443
- var _React$useState3 = React.useState(Boolean(search)),
444
- _React$useState4 = _slicedToArray(_React$useState3, 2),
445
- hover = _React$useState4[0],
446
- setHover = _React$useState4[1];
447
- var expanded = hover || Boolean(search);
442
+ hover = _React$useState2[0],
443
+ setHover = _React$useState2[1];
444
+ var expanded = hover || Boolean(value);
448
445
  var handleSubmit = function handleSubmit(e) {
449
446
  e.preventDefault();
450
- onSubmit(search);
447
+ onSubmit(value);
451
448
  };
452
449
  var handleEndHover = function handleEndHover() {
453
450
  setHover(false);
@@ -457,22 +454,6 @@ function FancySearch(_ref) {
457
454
  // A ref tracks whether this sync came from the user typing or from a parent
458
455
  // update, so the debounce only fires for genuine user input.
459
456
  var isUserType = React.useRef(false);
460
- React.useEffect(function () {
461
- if (isUserType.current) {
462
- // User is typing — debounce as normal
463
- isUserType.current = false;
464
- var timer = setTimeout(function () {
465
- onSubmit(search);
466
- }, 700);
467
- return function () {
468
- return clearTimeout(timer);
469
- };
470
- }
471
- // External value change (parent reset, clear from clearSelection, etc.)
472
- // — sync state and do NOT fire a stale debounce.
473
- setSearch(value);
474
- return undefined;
475
- }, [search, value, onSubmit]);
476
457
  return /*#__PURE__*/React.createElement("form", {
477
458
  onSubmit: handleSubmit
478
459
  }, /*#__PURE__*/React.createElement(material.Paper, {
@@ -498,10 +479,10 @@ function FancySearch(_ref) {
498
479
  }
499
480
  }, /*#__PURE__*/React.createElement(material.InputBase, {
500
481
  placeholder: "Search",
501
- value: search,
482
+ value: value,
502
483
  onChange: function onChange(e) {
503
484
  isUserType.current = true;
504
- setSearch(e.target.value);
485
+ onSubmit(e.target.value);
505
486
  },
506
487
  sx: _objectSpread2({
507
488
  ml: 1,
@@ -512,7 +493,7 @@ function FancySearch(_ref) {
512
493
  }),
513
494
  onBlur: handleEndHover
514
495
  }), /*#__PURE__*/React.createElement(material.Collapse, {
515
- "in": Boolean(search),
496
+ "in": Boolean(value),
516
497
  orientation: "horizontal",
517
498
  unmountOnExit: true
518
499
  }, /*#__PURE__*/React.createElement(material.Stack, {
@@ -525,7 +506,6 @@ function FancySearch(_ref) {
525
506
  }, /*#__PURE__*/React.createElement(material.IconButton, {
526
507
  onClick: function onClick() {
527
508
  isUserType.current = false;
528
- setSearch("");
529
509
  // Immediately clear instead of waiting for the debounce
530
510
  onSubmit("");
531
511
  }
@@ -571,8 +551,7 @@ SearchArea.propTypes = {
571
551
  };
572
552
 
573
553
  function TableToolbarContent(_ref) {
574
- var setLoading = _ref.setLoading,
575
- onReload = _ref.onReload,
554
+ var onReload = _ref.onReload,
576
555
  reloadBtnLoading = _ref.reloadBtnLoading,
577
556
  searchTerm = _ref.searchTerm,
578
557
  onSearchChange = _ref.onSearchChange,
@@ -608,7 +587,6 @@ function TableToolbarContent(_ref) {
608
587
  },
609
588
  id: "tableTitle"
610
589
  }, /*#__PURE__*/React.createElement(ReloadBtn, {
611
- setLoading: setLoading,
612
590
  onReload: onReload,
613
591
  loading: reloadBtnLoading
614
592
  })), /*#__PURE__*/React.createElement(SearchArea, {
@@ -619,7 +597,6 @@ function TableToolbarContent(_ref) {
619
597
  })));
620
598
  }
621
599
  TableToolbarContent.propTypes = {
622
- setLoading: PropTypes.func,
623
600
  onReload: PropTypes.func,
624
601
  reloadBtnLoading: PropTypes.bool,
625
602
  searchTerm: PropTypes.string,
@@ -631,25 +608,24 @@ TableToolbarContent.propTypes = {
631
608
  function useEnhancedTableState(_ref) {
632
609
  var rows = _ref.rows,
633
610
  subTable = _ref.subTable,
634
- resetFlag = _ref.resetFlag;
635
- var _React$useState = React.useState("asc"),
636
- _React$useState2 = _slicedToArray(_React$useState, 2),
637
- order = _React$useState2[0],
638
- setOrder = _React$useState2[1];
639
- var _React$useState3 = React.useState(""),
640
- _React$useState4 = _slicedToArray(_React$useState3, 2),
641
- orderBy = _React$useState4[0],
642
- setOrderBy = _React$useState4[1];
643
- var _React$useState5 = React.useState(function () {
611
+ resetFlag = _ref.resetFlag,
612
+ apiCall = _ref.apiCall,
613
+ searchTerm = _ref.searchTerm,
614
+ setOrder = _ref.setOrder,
615
+ setOrderBy = _ref.setOrderBy,
616
+ order = _ref.order,
617
+ orderBy = _ref.orderBy,
618
+ asyncPages = _ref.asyncPages;
619
+ var _React$useState = React.useState(function () {
644
620
  return {
645
621
  page: 0,
646
622
  rowsPerPage: subTable ? rows.length : 5,
647
623
  resetFlag: resetFlag
648
624
  };
649
625
  }),
650
- _React$useState6 = _slicedToArray(_React$useState5, 2),
651
- pagination = _React$useState6[0],
652
- setPagination = _React$useState6[1];
626
+ _React$useState2 = _slicedToArray(_React$useState, 2),
627
+ pagination = _React$useState2[0],
628
+ setPagination = _React$useState2[1];
653
629
  React.useEffect(function () {
654
630
  // eslint-disable-next-line react-hooks/set-state-in-effect
655
631
  setPagination(function (previous) {
@@ -664,11 +640,11 @@ function useEnhancedTableState(_ref) {
664
640
  }, [resetFlag]);
665
641
  var page = pagination.page;
666
642
  var rowsPerPage = subTable ? rows.length : pagination.rowsPerPage;
667
- var handleRequestSort = React.useCallback(function (event, property) {
643
+ var handleRequestSort = React.useCallback(function (property) {
668
644
  var isAsc = orderBy === property && order === "asc";
669
645
  setOrder(isAsc ? "desc" : "asc");
670
646
  setOrderBy(property);
671
- }, [order, orderBy]);
647
+ }, [order, orderBy, setOrder, setOrderBy]);
672
648
  var handleChangePage = React.useCallback(function (event, newPage) {
673
649
  setPagination(function (previous) {
674
650
  return _objectSpread2(_objectSpread2({}, previous), {}, {
@@ -684,14 +660,29 @@ function useEnhancedTableState(_ref) {
684
660
  });
685
661
  });
686
662
  }, []);
663
+ var handleSort = function handleSort(column, apiSortable) {
664
+ if (apiSortable) {
665
+ var direction = order === "asc" ? "desc" : "asc";
666
+ apiCall({
667
+ searchTerm: searchTerm,
668
+ column: column,
669
+ direction: direction,
670
+ pages: asyncPages !== null && asyncPages !== void 0 ? asyncPages : 1
671
+ });
672
+ setOrder(direction);
673
+ setOrderBy(column);
674
+ return;
675
+ }
676
+ handleRequestSort(column);
677
+ };
687
678
  return {
688
679
  order: order,
689
680
  orderBy: orderBy,
690
681
  page: page,
691
682
  rowsPerPage: rowsPerPage,
692
- handleRequestSort: handleRequestSort,
693
683
  handleChangePage: handleChangePage,
694
- handleChangeRowsPerPage: handleChangeRowsPerPage
684
+ handleChangeRowsPerPage: handleChangeRowsPerPage,
685
+ handleSort: handleSort
695
686
  };
696
687
  }
697
688
 
@@ -702,12 +693,8 @@ function EnhancedTableHead(props) {
702
693
  selectRows = props.selectRows,
703
694
  numSelected = props.numSelected,
704
695
  rowCount = props.rowCount,
705
- onSelectAllClick = props.onSelectAllClick;
706
- var createSortHandler = function createSortHandler(property) {
707
- return function (event) {
708
- onRequestSort(event, property);
709
- };
710
- };
696
+ onSelectAllClick = props.onSelectAllClick,
697
+ async = props.async;
711
698
  return /*#__PURE__*/React.createElement(material.TableHead, null, /*#__PURE__*/React.createElement(material.TableRow, null, selectRows && /*#__PURE__*/React.createElement(material.TableCell, {
712
699
  padding: "checkbox"
713
700
  }, /*#__PURE__*/React.createElement(material.Checkbox, {
@@ -724,7 +711,9 @@ function EnhancedTableHead(props) {
724
711
  }, /*#__PURE__*/React.createElement(material.TableSortLabel, {
725
712
  active: orderBy === headCell.id,
726
713
  direction: orderBy === headCell.id ? order : "asc",
727
- onClick: createSortHandler(headCell.id),
714
+ onClick: function onClick() {
715
+ return onRequestSort(headCell.id, headCell.sortable && async);
716
+ },
728
717
  disabled: headCell.subRow
729
718
  }, headCell.label, orderBy === headCell.id ? /*#__PURE__*/React.createElement(material.Box, {
730
719
  component: "span",
@@ -740,7 +729,8 @@ EnhancedTableHead.propTypes = {
740
729
  selectRows: PropTypes.bool,
741
730
  numSelected: PropTypes.number,
742
731
  rowCount: PropTypes.number,
743
- onSelectAllClick: PropTypes.func
732
+ onSelectAllClick: PropTypes.func,
733
+ async: PropTypes.bool
744
734
  };
745
735
 
746
736
  /**
@@ -941,17 +931,30 @@ function EnhancedTable(props) {
941
931
  rows = props.rows,
942
932
  subTable = props.subTable,
943
933
  selected = props.selected,
944
- selectID = props.selectID;
934
+ selectID = props.selectID,
935
+ setLoading = props.setLoading,
936
+ searchTerm = props.searchTerm,
937
+ setOrder = props.setOrder,
938
+ setOrderBy = props.setOrderBy,
939
+ order = props.order,
940
+ orderBy = props.orderBy,
941
+ async = props.async,
942
+ asyncPages = props.asyncPages;
945
943
  var _useEnhancedTableStat = useEnhancedTableState({
946
944
  rows: rows,
947
945
  subTable: subTable,
948
- resetFlag: props.resetFlag
946
+ resetFlag: props.resetFlag,
947
+ apiCall: setLoading,
948
+ searchTerm: searchTerm,
949
+ setOrder: setOrder,
950
+ setOrderBy: setOrderBy,
951
+ order: order,
952
+ orderBy: orderBy,
953
+ asyncPages: asyncPages
949
954
  }),
950
- order = _useEnhancedTableStat.order,
951
- orderBy = _useEnhancedTableStat.orderBy,
952
955
  page = _useEnhancedTableStat.page,
953
956
  rowsPerPage = _useEnhancedTableStat.rowsPerPage,
954
- handleRequestSort = _useEnhancedTableStat.handleRequestSort,
957
+ handleSort = _useEnhancedTableStat.handleSort,
955
958
  handleChangePage = _useEnhancedTableStat.handleChangePage,
956
959
  handleChangeRowsPerPage = _useEnhancedTableStat.handleChangeRowsPerPage;
957
960
  var emptyRows = Math.max(0, rowsPerPage - Math.min(rowsPerPage, rows.length - page * rowsPerPage));
@@ -959,7 +962,7 @@ function EnhancedTable(props) {
959
962
  return selected.includes(id);
960
963
  }, [selected]);
961
964
  var visibleRows = React.useMemo(function () {
962
- return stableSort(rows, getComparator(order, orderBy), headers).slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);
965
+ return stableSort(rows, getComparator(order, orderBy), headers, orderBy).slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);
963
966
  }, [headers, order, orderBy, page, rows, rowsPerPage]);
964
967
  return /*#__PURE__*/React.createElement(material.TableContainer, null, /*#__PURE__*/React.createElement(material.Table, {
965
968
  sx: {
@@ -970,12 +973,13 @@ function EnhancedTable(props) {
970
973
  }, props.loading ? /*#__PURE__*/React.createElement(TableLoader, null) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(EnhancedTableHead, {
971
974
  order: order,
972
975
  orderBy: orderBy,
973
- onRequestSort: handleRequestSort,
976
+ onRequestSort: handleSort,
974
977
  headings: headers,
975
978
  selectRows: props.selectRows,
976
979
  numSelected: selected.length,
977
980
  rowCount: rows.length,
978
- onSelectAllClick: props.handleSelectAllClick
981
+ onSelectAllClick: props.handleSelectAllClick,
982
+ async: async
979
983
  }), /*#__PURE__*/React.createElement(material.TableBody, null, visibleRows.map(function (row, index) {
980
984
  var rowKey = selectID ? row[selectID] : "row-".concat(page * rowsPerPage + index);
981
985
  var rowID = getSelectableRowId(row, index, selectID);
@@ -1025,9 +1029,17 @@ EnhancedTable.propTypes = {
1025
1029
  handleClick: PropTypes.func,
1026
1030
  selected: PropTypes.array,
1027
1031
  selectID: PropTypes.string,
1032
+ async: PropTypes.bool,
1028
1033
  resetFlag: PropTypes.string,
1029
1034
  pageSizeOptions: PropTypes.arrayOf(PropTypes.number),
1030
- name: PropTypes.string
1035
+ name: PropTypes.string,
1036
+ setLoading: PropTypes.func,
1037
+ searchTerm: PropTypes.string,
1038
+ setOrder: PropTypes.func,
1039
+ setOrderBy: PropTypes.func,
1040
+ order: PropTypes.string,
1041
+ orderBy: PropTypes.string,
1042
+ asyncPages: PropTypes.number
1031
1043
  };
1032
1044
 
1033
1045
  function UniversalTable(_ref) {
@@ -1052,12 +1064,23 @@ function UniversalTable(_ref) {
1052
1064
  selectIcon = _ref.selectIcon,
1053
1065
  onSelection = _ref.onSelection,
1054
1066
  pageSizeOptions = _ref.pageSizeOptions,
1055
- persistSearch = _ref.persistSearch;
1067
+ persistSearch = _ref.persistSearch,
1068
+ asyncPages = _ref.asyncPages;
1069
+ var debounceRef = React.useRef(null);
1070
+ var async = typeof asyncPages === "number" && asyncPages > 0;
1056
1071
  var head = headers || [];
1057
- var _useSearchableRows = useSearchableRows(data, head),
1072
+ var _useSearchableRows = useSearchableRows(data, head, async),
1058
1073
  rows = _useSearchableRows.rows,
1059
1074
  searchTerm = _useSearchableRows.searchTerm,
1060
1075
  setSearchTerm = _useSearchableRows.setSearchTerm;
1076
+ var _React$useState = React.useState("asc"),
1077
+ _React$useState2 = _slicedToArray(_React$useState, 2),
1078
+ order = _React$useState2[0],
1079
+ setOrder = _React$useState2[1];
1080
+ var _React$useState3 = React.useState(""),
1081
+ _React$useState4 = _slicedToArray(_React$useState3, 2),
1082
+ orderBy = _React$useState4[0],
1083
+ setOrderBy = _React$useState4[1];
1061
1084
  var _useSelectableRows = useSelectableRows({
1062
1085
  rows: rows,
1063
1086
  selectRows: selectRows,
@@ -1071,6 +1094,41 @@ function UniversalTable(_ref) {
1071
1094
  clearSelection();
1072
1095
  setSearchTerm(value);
1073
1096
  }, [clearSelection, setSearchTerm]);
1097
+ var handleSearch = function handleSearch(searchValue) {
1098
+ if (async) {
1099
+ setSearchTerm(searchValue);
1100
+ clearTimeout(debounceRef.current);
1101
+ debounceRef.current = setTimeout(function () {
1102
+ setLoading({
1103
+ searchTerm: searchValue,
1104
+ direction: order,
1105
+ column: orderBy,
1106
+ pages: asyncPages
1107
+ });
1108
+ }, 500);
1109
+ } else {
1110
+ handleSearchChange(searchValue);
1111
+ }
1112
+ };
1113
+ React.useEffect(function () {
1114
+ return function () {
1115
+ return clearTimeout(debounceRef.current);
1116
+ };
1117
+ }, []);
1118
+ var handleReload = React.useCallback(function () {
1119
+ if (typeof onReload === "function") {
1120
+ onReload();
1121
+ return;
1122
+ }
1123
+ if (typeof setLoading === "function") {
1124
+ setLoading(async ? {
1125
+ searchTerm: searchTerm,
1126
+ direction: order,
1127
+ column: orderBy,
1128
+ pages: asyncPages
1129
+ } : true);
1130
+ }
1131
+ }, [async, onReload, setLoading, searchTerm, order, orderBy, asyncPages]);
1074
1132
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(LazyLoadingIndicator, {
1075
1133
  show: lazyloading,
1076
1134
  currentPage: currentPage,
@@ -1087,17 +1145,17 @@ function UniversalTable(_ref) {
1087
1145
  name: name,
1088
1146
  subTable: subTable
1089
1147
  }), !subTable && /*#__PURE__*/React.createElement(TableToolbarContent, {
1090
- setLoading: setLoading,
1091
- onReload: onReload,
1148
+ onReload: typeof onReload === "function" || typeof setLoading === "function" ? handleReload : undefined,
1092
1149
  reloadBtnLoading: reloadBtnLoading,
1093
1150
  searchTerm: searchTerm,
1094
- onSearchChange: handleSearchChange,
1151
+ onSearchChange: handleSearch,
1095
1152
  name: name,
1096
1153
  persistSearch: persistSearch
1097
1154
  }), /*#__PURE__*/React.createElement(EnhancedTable, {
1098
1155
  headers: head,
1099
1156
  rows: rows,
1100
1157
  resetFlag: searchTerm,
1158
+ searchTerm: searchTerm,
1101
1159
  subTable: subTable,
1102
1160
  hideBadge: hideBadge,
1103
1161
  loading: loading,
@@ -1107,7 +1165,14 @@ function UniversalTable(_ref) {
1107
1165
  selected: selected,
1108
1166
  selectID: selectID,
1109
1167
  pageSizeOptions: pageSizeOptions,
1110
- name: name
1168
+ name: name,
1169
+ setLoading: setLoading,
1170
+ order: order,
1171
+ orderBy: orderBy,
1172
+ setOrder: setOrder,
1173
+ setOrderBy: setOrderBy,
1174
+ asyncPages: asyncPages,
1175
+ async: async
1111
1176
  })));
1112
1177
  }
1113
1178
  UniversalTable.propTypes = {
@@ -1131,7 +1196,8 @@ UniversalTable.propTypes = {
1131
1196
  /** Override default page size options (e.g. [10, 25, 50]). Default auto-computed. */
1132
1197
  pageSizeOptions: PropTypes.arrayOf(PropTypes.number),
1133
1198
  /** Persist search term to sessionStorage (requires name prop). Default: false */
1134
- persistSearch: PropTypes.bool
1199
+ persistSearch: PropTypes.bool,
1200
+ asyncPages: PropTypes.number
1135
1201
  };
1136
1202
 
1137
1203
  var UniversalTable$1 = /*#__PURE__*/Object.freeze({