@economic/taco 2.45.3 → 2.46.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. package/dist/components/Provider/Localization.d.ts +2 -0
  2. package/dist/components/Report/Report.d.ts +1 -1
  3. package/dist/components/Table3/Table3.d.ts +2 -14
  4. package/dist/components/Table3/components/Columns/Internal/EditingActionsMenu.d.ts +1 -2
  5. package/dist/components/Table3/components/Editing/DiscardChangesConfirmationDialog.d.ts +7 -0
  6. package/dist/components/Table3/components/Row/Editing/CreateNewRow.d.ts +14 -0
  7. package/dist/components/Table3/components/Row/Editing/TemporaryRow.d.ts +11 -0
  8. package/dist/components/Table3/features/useEditingState.d.ts +29 -0
  9. package/dist/components/Table3/features/useTableEditing.d.ts +26 -36
  10. package/dist/components/Table3/listeners/useTableEditingListener.d.ts +1 -1
  11. package/dist/components/Table3/types.d.ts +24 -8
  12. package/dist/components/Table3/useTable3.d.ts +6 -0
  13. package/dist/components/Table3/util/editing.d.ts +7 -1
  14. package/dist/esm/index.css +28 -4
  15. package/dist/esm/packages/taco/src/components/ModeSwitch/ModeSwitch.js +2 -2
  16. package/dist/esm/packages/taco/src/components/ModeSwitch/ModeSwitch.js.map +1 -1
  17. package/dist/esm/packages/taco/src/components/Provider/Localization.js +5 -3
  18. package/dist/esm/packages/taco/src/components/Provider/Localization.js.map +1 -1
  19. package/dist/esm/packages/taco/src/components/Select2/Select2.js +1 -1
  20. package/dist/esm/packages/taco/src/components/Select2/Select2.js.map +1 -1
  21. package/dist/esm/packages/taco/src/components/Switch/Switch.js +1 -1
  22. package/dist/esm/packages/taco/src/components/Switch/Switch.js.map +1 -1
  23. package/dist/esm/packages/taco/src/components/Table3/Table3.js +14 -6
  24. package/dist/esm/packages/taco/src/components/Table3/Table3.js.map +1 -1
  25. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Cell/Editing/RowMoveIndicator.js +1 -2
  26. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Cell/Editing/RowMoveIndicator.js.map +1 -1
  27. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Cell/EditingControlCell.js +25 -15
  28. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Cell/EditingControlCell.js.map +1 -1
  29. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Internal/EditingActionsMenu.js +5 -37
  30. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Internal/EditingActionsMenu.js.map +1 -1
  31. package/dist/esm/packages/taco/src/components/Table3/components/Editing/Alert.js +17 -12
  32. package/dist/esm/packages/taco/src/components/Table3/components/Editing/Alert.js.map +1 -1
  33. package/dist/esm/packages/taco/src/components/Table3/components/Editing/DiscardChangesConfirmationDialog.js +34 -0
  34. package/dist/esm/packages/taco/src/components/Table3/components/Editing/DiscardChangesConfirmationDialog.js.map +1 -0
  35. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateNewRow.js +103 -0
  36. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateNewRow.js.map +1 -0
  37. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/SaveStatus.js +2 -14
  38. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/SaveStatus.js.map +1 -1
  39. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/TemporaryRow.js +96 -0
  40. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/TemporaryRow.js.map +1 -0
  41. package/dist/esm/packages/taco/src/components/Table3/components/Row/Row.js +39 -6
  42. package/dist/esm/packages/taco/src/components/Table3/components/Row/Row.js.map +1 -1
  43. package/dist/esm/packages/taco/src/components/Table3/components/Toolbar/Editing/Editing.js +4 -17
  44. package/dist/esm/packages/taco/src/components/Table3/components/Toolbar/Editing/Editing.js.map +1 -1
  45. package/dist/esm/packages/taco/src/components/Table3/features/useEditingState.js +519 -0
  46. package/dist/esm/packages/taco/src/components/Table3/features/useEditingState.js.map +1 -0
  47. package/dist/esm/packages/taco/src/components/Table3/features/useTableEditing.js +29 -406
  48. package/dist/esm/packages/taco/src/components/Table3/features/useTableEditing.js.map +1 -1
  49. package/dist/esm/packages/taco/src/components/Table3/listeners/useTableEditingListener.js +44 -33
  50. package/dist/esm/packages/taco/src/components/Table3/listeners/useTableEditingListener.js.map +1 -1
  51. package/dist/esm/packages/taco/src/components/Table3/useTable3.js +27 -9
  52. package/dist/esm/packages/taco/src/components/Table3/useTable3.js.map +1 -1
  53. package/dist/esm/packages/taco/src/components/Table3/util/editing.js +11 -23
  54. package/dist/esm/packages/taco/src/components/Table3/util/editing.js.map +1 -1
  55. package/dist/esm/packages/taco/src/primitives/Table/Core/Table.js +1 -3
  56. package/dist/esm/packages/taco/src/primitives/Table/Core/Table.js.map +1 -1
  57. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Cell/BuiltIns/GroupedCell.js +9 -3
  58. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Cell/BuiltIns/GroupedCell.js.map +1 -1
  59. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Internal/Actions.js +9 -7
  60. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Internal/Actions.js.map +1 -1
  61. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Footer/Footer.js.map +1 -1
  62. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/BuiltIns/DisplayRow.js +1 -1
  63. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/BuiltIns/DisplayRow.js.map +1 -1
  64. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/Row.js +4 -2
  65. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/Row.js.map +1 -1
  66. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/RowContext.js +2 -1
  67. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/RowContext.js.map +1 -1
  68. package/dist/esm/packages/taco/src/primitives/Table/Core/features/useTableRenderer.js +29 -7
  69. package/dist/esm/packages/taco/src/primitives/Table/Core/features/useTableRenderer.js.map +1 -1
  70. package/dist/esm/packages/taco/src/primitives/Table/Core/useTable.js +2 -2
  71. package/dist/esm/packages/taco/src/primitives/Table/Core/useTable.js.map +1 -1
  72. package/dist/esm/packages/taco/src/primitives/Table/types.js.map +1 -1
  73. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/features/useTableRowSelection.js +2 -1
  74. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/features/useTableRowSelection.js.map +1 -1
  75. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/useTableManager.js +1 -1
  76. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/useTableManager.js.map +1 -1
  77. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/util/setup.js +11 -0
  78. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/util/setup.js.map +1 -1
  79. package/dist/esm/packages/taco/src/utils/dom.js +7 -4
  80. package/dist/esm/packages/taco/src/utils/dom.js.map +1 -1
  81. package/dist/index.css +28 -4
  82. package/dist/primitives/Table/Core/components/Columns/Internal/Actions.d.ts +3 -1
  83. package/dist/primitives/Table/Core/components/Footer/Footer.d.ts +2 -2
  84. package/dist/primitives/Table/Core/components/Row/RowContext.d.ts +1 -0
  85. package/dist/primitives/Table/Core/features/useTableRenderer.d.ts +2 -2
  86. package/dist/primitives/Table/Core/types.d.ts +4 -0
  87. package/dist/primitives/Table/Core/useTable.d.ts +2 -2
  88. package/dist/primitives/Table/types.d.ts +1 -1
  89. package/dist/primitives/Table/useTableManager/useTableManager.d.ts +1 -1
  90. package/dist/taco.cjs.development.js +982 -661
  91. package/dist/taco.cjs.development.js.map +1 -1
  92. package/dist/taco.cjs.production.min.js +1 -1
  93. package/dist/taco.cjs.production.min.js.map +1 -1
  94. package/dist/utils/dom.d.ts +1 -0
  95. package/package.json +2 -2
  96. package/dist/components/Table3/components/Row/Editing/CreateRowButton.d.ts +0 -11
  97. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateRowButton.js +0 -90
  98. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateRowButton.js.map +0 -1
@@ -43,7 +43,8 @@ var set = _interopDefault(require('lodash/set'));
43
43
  var unset = _interopDefault(require('lodash/unset'));
44
44
  var compact = _interopDefault(require('lodash/compact'));
45
45
  var pullAt = _interopDefault(require('lodash/pullAt'));
46
- var lodash = require('lodash');
46
+ var omit = _interopDefault(require('lodash/omit'));
47
+ var setWith = _interopDefault(require('lodash/setWith'));
47
48
  var TabsPrimitive = require('@radix-ui/react-tabs');
48
49
  var Joyride = require('react-joyride');
49
50
  var Joyride__default = _interopDefault(Joyride);
@@ -4212,7 +4213,7 @@ const getOverlaySelector = element => {
4212
4213
  return undefined;
4213
4214
  }
4214
4215
  };
4215
- function isElementInsideOrTriggeredFromContainer(element, container) {
4216
+ function isElementTriggeredFromContainer(element, container) {
4216
4217
  var _getOverlaySelector, _element$closest;
4217
4218
  const selector = (_getOverlaySelector = getOverlaySelector(element)) !== null && _getOverlaySelector !== void 0 ? _getOverlaySelector : getOverlaySelector((_element$closest = element === null || element === void 0 ? void 0 : element.closest('[role=dialog],[role=menu]')) !== null && _element$closest !== void 0 ? _element$closest : null);
4218
4219
  if (selector) {
@@ -4222,11 +4223,14 @@ function isElementInsideOrTriggeredFromContainer(element, container) {
4222
4223
  const elementInDocument = document.querySelector(selector);
4223
4224
  // if the element does exist, see if it is itself connected to somethng that was triggered from the container
4224
4225
  if (elementInDocument) {
4225
- return isElementInsideOrTriggeredFromContainer(elementInDocument, container);
4226
+ return isElementTriggeredFromContainer(elementInDocument, container);
4226
4227
  }
4227
4228
  return false;
4228
4229
  }
4229
- return !!(container !== null && container !== void 0 && container.contains(element));
4230
+ return false;
4231
+ }
4232
+ function isElementInsideOrTriggeredFromContainer(element, container) {
4233
+ return isElementTriggeredFromContainer(element, container) || !!(container !== null && container !== void 0 && container.contains(element));
4230
4234
  }
4231
4235
  function isElementInsideOverlay(element) {
4232
4236
  return !!(element !== null && element !== void 0 && element.closest('[role=dialog],[role=menu]'));
@@ -4720,7 +4724,9 @@ const defaultLocalisationTexts = {
4720
4724
  tooltip: 'Edit table'
4721
4725
  },
4722
4726
  create: {
4723
- label: 'New'
4727
+ label: 'New',
4728
+ disabled: 'Existing new row must be saved',
4729
+ saving: 'Saving...'
4724
4730
  }
4725
4731
  },
4726
4732
  clearChangesConfirmationDialog: {
@@ -4742,8 +4748,8 @@ const defaultLocalisationTexts = {
4742
4748
  },
4743
4749
  validation: {
4744
4750
  alert: {
4745
- titleOne: '[COUNT] unsaved entry:',
4746
- titlePlural: '[COUNT] unsaved entries:',
4751
+ titleOne: '[COUNT] unsaved row:',
4752
+ titlePlural: '[COUNT] unsaved rows:',
4747
4753
  messageOne: "[COLUMN] [ROW] is incomplete and hasn't been saved.",
4748
4754
  messagePlural: "[COLUMN] [ROW] are incomplete and haven't been saved.",
4749
4755
  messageRow: 'Row',
@@ -7639,7 +7645,7 @@ const Switch = /*#__PURE__*/React.forwardRef(function Switch(props, ref) {
7639
7645
  onCheckedChange: onChange,
7640
7646
  ref: ref
7641
7647
  }), /*#__PURE__*/React.createElement(PrimitiveSwitch.Thumb, {
7642
- className: "'will-change-transform mt-0.5 h-4 w-4 translate-x-[0.15rem] rounded-full bg-white transition-transform group-disabled:opacity-50 group-aria-checked:translate-x-[1.1rem]"
7648
+ className: "pointer-events-none mt-0.5 h-4 w-4 translate-x-[0.15rem] rounded-full bg-white transition-transform will-change-transform group-disabled:opacity-50 group-aria-checked:translate-x-[1.1rem]"
7643
7649
  }));
7644
7650
  if (label) {
7645
7651
  const labelContainerClassName = cn('flex self-start cursor-pointer', {
@@ -8699,10 +8705,10 @@ const ModeSwitch = /*#__PURE__*/React.forwardRef(function ModeSwitch(props, ref)
8699
8705
  onCheckedChange: onChange,
8700
8706
  ref: ref
8701
8707
  }), /*#__PURE__*/React.createElement(PrimitiveSwitch.Thumb, {
8702
- className: "'will-change-transform flex h-6 w-6 items-center justify-center rounded-full bg-white transition-transform group-disabled:opacity-50 group-aria-checked:translate-x-[100%]"
8708
+ className: "pointer-events-none flex h-6 w-6 items-center justify-center rounded-full bg-white transition-transform will-change-transform group-disabled:opacity-50 group-aria-checked:translate-x-[100%]"
8703
8709
  }, /*#__PURE__*/React.createElement(Icon, {
8704
8710
  name: "edit-simple",
8705
- className: "!h-5 !w-5"
8711
+ className: "pointer-events-none !h-5 !w-5"
8706
8712
  })));
8707
8713
  });
8708
8714
  ModeSwitch.displayName = 'ModeSwitch';
@@ -10405,6 +10411,15 @@ function configureReactTableOptions(options, props, localization) {
10405
10411
  // We don't want to expose internal Tanstack Table row, so we need to wrap enableRowSelection callback into additional function,
10406
10412
  // which receives the React Table Row object and passes row.original to a callback.
10407
10413
  const reactTableEnableRowSelection = typeof options.enableRowSelection === 'function' ? row => options.enableRowSelection(row.original) : options.enableRowSelection;
10414
+ let getRowId;
10415
+ if (props.rowIdentityAccessor) {
10416
+ getRowId = (originalRow, index) => {
10417
+ if (originalRow) {
10418
+ return String(originalRow[props.rowIdentityAccessor]);
10419
+ }
10420
+ return String(index);
10421
+ };
10422
+ }
10408
10423
  const tableOptions = {
10409
10424
  defaultColumn: {
10410
10425
  enableColumnFilter: options.enableFiltering || true,
@@ -10423,11 +10438,13 @@ function configureReactTableOptions(options, props, localization) {
10423
10438
  enableGrouping: true,
10424
10439
  enableHiding: (_options$enableColumn2 = options.enableColumnHiding) !== null && _options$enableColumn2 !== void 0 ? _options$enableColumn2 : false,
10425
10440
  enablePinning: (_options$enableColumn3 = options.enableColumnFreezing) !== null && _options$enableColumn3 !== void 0 ? _options$enableColumn3 : false,
10441
+ enableRowPinning: true,
10426
10442
  enableRowSelection: reactTableEnableRowSelection !== null && reactTableEnableRowSelection !== void 0 ? reactTableEnableRowSelection : false,
10427
10443
  enableSorting: (_options$enableSortin = options.enableSorting) !== null && _options$enableSortin !== void 0 ? _options$enableSortin : false,
10428
10444
  // models for default features
10429
10445
  getExpandedRowModel: reactTable.getExpandedRowModel(),
10430
10446
  getGroupedRowModel: reactTable.getGroupedRowModel(),
10447
+ getRowId,
10431
10448
  groupedColumnMode: false
10432
10449
  };
10433
10450
  if (tableOptions.enableColumnResizing) {
@@ -10909,6 +10926,7 @@ function useTableRowHeight(isEnabled = false, defaultRowHeight = 'medium') {
10909
10926
  function useTableRowSelection(isEnabled = false) {
10910
10927
  const lastSelectedRowIndex = React__default.useRef();
10911
10928
  const onKeyDown = React__default.useCallback((event, table) => {
10929
+ var _event$target;
10912
10930
  if (!isEnabled || !table.options.enableRowSelection || event.defaultPrevented) {
10913
10931
  return;
10914
10932
  }
@@ -10923,7 +10941,7 @@ function useTableRowSelection(isEnabled = false) {
10923
10941
  (_rows$rowActiveIndex2 = rows[rowActiveIndex]) === null || _rows$rowActiveIndex2 === void 0 ? void 0 : _rows$rowActiveIndex2.toggleSelected();
10924
10942
  }
10925
10943
  return;
10926
- } else if ((event.ctrlKey || event.metaKey) && event.key === 'a') {
10944
+ } else if ((event.ctrlKey || event.metaKey) && event.key === 'a' && !['INPUT', 'TEXTAREA'].includes((_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.tagName)) {
10927
10945
  event.preventDefault();
10928
10946
  table.toggleAllRowsSelected();
10929
10947
  return;
@@ -11760,7 +11778,7 @@ function useTableManager(props, meta, internalColumns) {
11760
11778
  rowDrag,
11761
11779
  rowDrop: rowDrop,
11762
11780
  rowExpansion: rowExpansion,
11763
- rowIdentityColumnId: props.rowIdentityColumnId,
11781
+ rowIdentityAccessor: props.rowIdentityAccessor,
11764
11782
  rowGoto,
11765
11783
  rowGroups: rowGroups,
11766
11784
  rowHeight,
@@ -12098,7 +12116,8 @@ const Skeleton = /*#__PURE__*/React__default.forwardRef(function Skeleton(props,
12098
12116
 
12099
12117
  const RowContext = /*#__PURE__*/React__default.createContext({
12100
12118
  isHovered: false,
12101
- rowIndex: -1
12119
+ rowIndex: -1,
12120
+ hideRowActions: false
12102
12121
  });
12103
12122
 
12104
12123
  /* anonymous functions will break the memoisation on each render, wrap handlers in callbacks */
@@ -12106,6 +12125,7 @@ function Row(props) {
12106
12125
  const {
12107
12126
  renderer: RowRenderer,
12108
12127
  cellRenderer: CellRenderer,
12128
+ hideRowActions = false,
12109
12129
  ...displayRowProps
12110
12130
  } = props;
12111
12131
  const tableMeta = props.table.options.meta;
@@ -12113,8 +12133,9 @@ function Row(props) {
12113
12133
  // context - it must be here for cells to read it, since they render alongside the row inside DisplayRow
12114
12134
  const contextValue = React__default.useMemo(() => ({
12115
12135
  isHovered,
12116
- rowIndex: props.index
12117
- }), [isHovered, props.index]);
12136
+ rowIndex: props.index,
12137
+ hideRowActions
12138
+ }), [isHovered, props.index, hideRowActions]);
12118
12139
  if (props.row.original === undefined) {
12119
12140
  return /*#__PURE__*/React__default.createElement(SkeletonRow, Object.assign({}, props));
12120
12141
  }
@@ -12125,11 +12146,35 @@ function Row(props) {
12125
12146
  })));
12126
12147
  }
12127
12148
 
12128
- function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex) {
12129
- var _table$getState$group, _virtualItems$padding, _virtualItems$padding2, _virtualItems$padding3, _ref, _virtualItems;
12149
+ // scroll padding end is designed to always show half of the next row
12150
+ function getScrollPaddingEndOffset(table) {
12151
+ const tableMeta = table.options.meta;
12152
+ let offset = 2;
12153
+ if (tableMeta.footer.isEnabled) {
12154
+ offset += 1;
12155
+ }
12156
+ if (table.getHeaderGroups().length > 1) {
12157
+ offset += table.getHeaderGroups().length - 1;
12158
+ }
12159
+ let height = ROW_HEIGHT_ESTIMATES.medium * offset;
12160
+ const bottomRows = table.getBottomRows();
12161
+ if (bottomRows.length) {
12162
+ // 1.4 offsets for half rows and also accounts for increased row heights (which is likely in pinned rows)
12163
+ height += ROW_HEIGHT_ESTIMATES[tableMeta.rowHeight.height] * 1.4 * bottomRows.length;
12164
+ }
12165
+ return height;
12166
+ }
12167
+ // scroll padding end is designed to always show half of the next row
12168
+ function getPaddingEndOffset(table, options) {
12169
+ var _table$getBottomRows, _options$virtualiserP;
12170
+ const bottomRows = (_table$getBottomRows = table.getBottomRows()) !== null && _table$getBottomRows !== void 0 ? _table$getBottomRows : [];
12171
+ return ROW_HEIGHT_ESTIMATES.medium * ((_options$virtualiserP = options === null || options === void 0 ? void 0 : options.virtualiserPaddingEndOffset) !== null && _options$virtualiserP !== void 0 ? _options$virtualiserP : 1) * bottomRows.length;
12172
+ }
12173
+ function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex, options) {
12174
+ var _table$getState$group, _table$getCenterRows, _virtualItems$padding, _virtualItems$padding2, _virtualItems$padding3, _ref, _virtualItems;
12130
12175
  const tableMeta = table.options.meta;
12131
- const rows = table.getRowModel().rows;
12132
12176
  const isTableRowGrouped = !!((_table$getState$group = table.getState().grouping) !== null && _table$getState$group !== void 0 && _table$getState$group.length);
12177
+ const rows = (_table$getCenterRows = table.getCenterRows()) !== null && _table$getCenterRows !== void 0 ? _table$getCenterRows : [];
12133
12178
  // expanded rows
12134
12179
  const {
12135
12180
  createRowMeasurer,
@@ -12139,9 +12184,6 @@ function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex) {
12139
12184
  const rangeExtractor = useRowGroupVirtualisation(table);
12140
12185
  // account for thead and tfoot in the scroll area - both are always medium row height
12141
12186
  const scrollPaddingStart = ROW_HEIGHT_ESTIMATES.medium;
12142
- // column groups offset the bottom padding :shrug:, multiplying by 1.5 ensures the bottom padding remains
12143
- // consistent when there are groups and when there aren't. 1.5 is relatively arbitrary, but it gives alignment
12144
- const scrollPaddingEnd = ROW_HEIGHT_ESTIMATES.medium * (table.getHeaderGroups().length > 1 ? 1.5 : 1);
12145
12187
  const virtualiser = reactVirtual.useVirtualizer({
12146
12188
  count: rows.length,
12147
12189
  estimateSize,
@@ -12150,7 +12192,8 @@ function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex) {
12150
12192
  rangeExtractor,
12151
12193
  // correctly sets the scroll padding offset, e.g. when keyboard navigating rows in the list
12152
12194
  scrollPaddingStart,
12153
- scrollPaddingEnd: tableMeta.footer.isEnabled ? scrollPaddingEnd * 2 : scrollPaddingEnd
12195
+ scrollPaddingEnd: getScrollPaddingEndOffset(table),
12196
+ paddingEnd: getPaddingEndOffset(table, options)
12154
12197
  });
12155
12198
  const totalSize = virtualiser.getTotalSize();
12156
12199
  const virtualItems = virtualiser.getVirtualItems();
@@ -12307,12 +12350,14 @@ function Actions$1(props) {
12307
12350
  actionsLength,
12308
12351
  data,
12309
12352
  isActiveRow,
12310
- rowId
12353
+ rowId,
12354
+ table
12311
12355
  } = props;
12312
12356
  const {
12313
12357
  texts
12314
12358
  } = useLocalization();
12315
- const visibleActions = actions.map(action => action(data, rowId)).filter(action => !!action);
12359
+ // we don't want to document passing table, so it isn't on the type
12360
+ const visibleActions = actions.map(action => action(data, rowId, table)).filter(action => !!action);
12316
12361
  const actionsOnRow = visibleActions.length === actionsLength ? visibleActions : visibleActions.slice(0, actionsLength - 1);
12317
12362
  const actionsInMenu = visibleActions.slice(visibleActions.length === actionsLength ? actionsLength : actionsLength - 1);
12318
12363
  const className = cn('flex justify-end text-right bg-[inherit] shadow-[-6px_0px_6px_var(--table-row-actions-shadow)] print:hidden');
@@ -12352,7 +12397,8 @@ const Cell = /*#__PURE__*/React__default.memo(function MemoedCell(context) {
12352
12397
  } = context;
12353
12398
  const {
12354
12399
  isHovered,
12355
- rowIndex
12400
+ rowIndex,
12401
+ hideRowActions
12356
12402
  } = React__default.useContext(RowContext);
12357
12403
  const tableMeta = table.options.meta;
12358
12404
  const actions = tableMeta.rowActions.rowActions;
@@ -12360,15 +12406,14 @@ const Cell = /*#__PURE__*/React__default.memo(function MemoedCell(context) {
12360
12406
  const isActiveRow = tableMeta.rowActive.rowActiveIndex === rowIndex;
12361
12407
  const isResizingColumn = !!table.getState().columnSizingInfo.isResizingColumn;
12362
12408
  const isHoverStatePaused = tableMeta.rowActive.isHoverStatePaused;
12363
- // We don't want to show actions in edit mode, since we have editing actions,
12364
- // which is shown in edit mode instead.
12365
- if (actions !== null && actions !== void 0 && actions.length && (isActiveRow || isHovered && !isHoverStatePaused && !isResizingColumn)) {
12409
+ if (!hideRowActions && actions !== null && actions !== void 0 && actions.length && (isActiveRow || isHovered && !isHoverStatePaused && !isResizingColumn)) {
12366
12410
  return /*#__PURE__*/React__default.createElement(Actions$1, {
12367
12411
  actions: actions,
12368
12412
  actionsLength: actionsLength,
12369
12413
  data: row.original,
12370
12414
  isActiveRow: isActiveRow,
12371
- rowId: row.id
12415
+ rowId: row.id,
12416
+ table: table
12372
12417
  });
12373
12418
  }
12374
12419
  return null;
@@ -12618,13 +12663,13 @@ const INTERNAL_RENDERERS = {
12618
12663
  rowExpansion: renderer$2,
12619
12664
  rowSelection: renderer$3
12620
12665
  };
12621
- function useTable(props, externalRef, renderers, meta) {
12666
+ function useTable(props, externalRef, renderers, meta, options) {
12622
12667
  // create a ref and merge with the consumer's ref
12623
12668
  const ref = useMergedRef(externalRef);
12624
12669
  // configure the table
12625
12670
  const manager = useTableManager(props, meta, INTERNAL_RENDERERS);
12626
12671
  // configure the virtualised renderer
12627
- const renderer = useTableRenderer(renderers, manager.instance, ref, props.defaultRowActiveIndex);
12672
+ const renderer = useTableRenderer(renderers, manager.instance, ref, props.defaultRowActiveIndex, options);
12628
12673
  // configure dynamic styling
12629
12674
  const {
12630
12675
  style,
@@ -12725,7 +12770,10 @@ function GroupedCell(props) {
12725
12770
  index,
12726
12771
  isHighlighted
12727
12772
  } = props;
12728
- const tableMeta = cell.getContext().table.options.meta;
12773
+ const {
12774
+ table
12775
+ } = cell.getContext();
12776
+ const tableMeta = table.options.meta;
12729
12777
  const columnMeta = cell.column.columnDef.meta;
12730
12778
  const attributes = getCellAttributes(cell, index, isHighlighted);
12731
12779
  const {
@@ -12743,7 +12791,8 @@ function GroupedCell(props) {
12743
12791
  colSpan: colSpan,
12744
12792
  rowActions: tableMeta.rowGroups.rowActionsForGroup,
12745
12793
  rowId: cell.row.id,
12746
- subRows: subRows
12794
+ subRows: subRows,
12795
+ table: table
12747
12796
  }), content);
12748
12797
  }
12749
12798
  const MemoedGroupedCell = /*#__PURE__*/React__default.memo(function MemoedGroupedCell(props) {
@@ -12755,6 +12804,7 @@ const MemoedGroupedCell = /*#__PURE__*/React__default.memo(function MemoedGroupe
12755
12804
  rowActions,
12756
12805
  rowId,
12757
12806
  subRows,
12807
+ table,
12758
12808
  ...attributes
12759
12809
  } = props;
12760
12810
  return /*#__PURE__*/React__default.createElement("td", Object.assign({}, attributes, {
@@ -12769,7 +12819,8 @@ const MemoedGroupedCell = /*#__PURE__*/React__default.memo(function MemoedGroupe
12769
12819
  actionsLength: 4,
12770
12820
  data: subRows,
12771
12821
  isActiveRow: true,
12772
- rowId: rowId
12822
+ rowId: rowId,
12823
+ table: table
12773
12824
  })) : null);
12774
12825
  });
12775
12826
 
@@ -12909,7 +12960,7 @@ const DisplayRow = /*#__PURE__*/React__default.memo(function DisplayRow(props) {
12909
12960
  const expansionRef = React__default.useRef(null);
12910
12961
  const isExpanded = !!attributes['data-row-expanded'];
12911
12962
  useSetVirtualisedRowHeight(measureRow, ref.current, expansionRef.current, isExpanded);
12912
- const className = cn('group/row', {
12963
+ const className = cn('group/row', otherAttributes.className, {
12913
12964
  'hover:cursor-grab': tableMeta.rowDrag.isEnabled && typeof attributes.onClick !== 'function',
12914
12965
  'hover:cursor-pointer': typeof attributes.onClick === 'function'
12915
12966
  });
@@ -15765,7 +15816,7 @@ const Select2 = /*#__PURE__*/React__default.forwardRef(function Select2(props, r
15765
15816
  var _listboxRef$current;
15766
15817
  if (open) {
15767
15818
  event.preventDefault();
15768
- } else if (isElementInsideTable3OrReport(event.currentTarget)) {
15819
+ } else if (isElementInsideTable3OrReport(event.currentTarget) && isAriaDirectionKey(event)) {
15769
15820
  return;
15770
15821
  } else if (!event.ctrlKey && !event.metaKey && (event.key === 'ArrowDown' || /^[a-z0-9]$/i.test(event.key))) {
15771
15822
  setOpen(true);
@@ -16777,8 +16828,6 @@ function TableGrid(props) {
16777
16828
  table.meta.rowActive.handleFocus(event, table.meta.length, table.renderer.scrollToIndex);
16778
16829
  } : undefined;
16779
16830
  const filterReason = getFilterReason(table);
16780
- const searchNotApplied = !table.state.globalFilter || table.state.globalFilter === '';
16781
- const filtersNotApplied = !table.state.columnFilters || table.state.columnFilters.length === 0;
16782
16831
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("style", null, table.stylesheet), /*#__PURE__*/React__default.createElement(focus.FocusScope, null, /*#__PURE__*/React__default.createElement("table", Object.assign({}, attributes, {
16783
16832
  id: table.id,
16784
16833
  "data-table-font-size": table.meta.fontSize.size,
@@ -16811,7 +16860,7 @@ function TableGrid(props) {
16811
16860
  ...table.renderer.style,
16812
16861
  height: table.renderer.style.height + ROW_HEIGHT_ESTIMATES[table.meta.rowHeight.height]
16813
16862
  } : table.renderer.style
16814
- }, table.renderer.rows, searchNotApplied && filtersNotApplied && props.children), table.meta.footer.isEnabled ? /*#__PURE__*/React__default.createElement(Foot, {
16863
+ }, table.renderer.rows, props.children), table.meta.footer.isEnabled ? /*#__PURE__*/React__default.createElement(Foot, {
16815
16864
  table: table.instance
16816
16865
  }) : null)))));
16817
16866
  }
@@ -18314,71 +18363,6 @@ const useTableRowCreation = (data, tableRef) => {
18314
18363
  };
18315
18364
  };
18316
18365
 
18317
- function useTableEditingListener(table, tableRef) {
18318
- const tableMeta = table.options.meta;
18319
- const completedRowsCount = tableMeta.editing.getCompletedRowsCount();
18320
- const localization = useLocalization();
18321
- const saveChanges = () => {
18322
- requestAnimationFrame(() => {
18323
- tableMeta.editing.saveChanges();
18324
- });
18325
- };
18326
- // save when the row changes
18327
- useLazyEffect(() => {
18328
- if (tableMeta.editing.isEditing) {
18329
- saveChanges();
18330
- }
18331
- }, [tableMeta.rowActive.rowActiveIndex]);
18332
- useLazyEffect(() => {
18333
- if (tableMeta.editing.isEditing) {
18334
- if (tableMeta.rowActive.rowActiveIndex === undefined) {
18335
- tableMeta.rowActive.setRowActiveIndex(0);
18336
- }
18337
- } else {
18338
- // save
18339
- saveChanges();
18340
- // reset detailed mode
18341
- tableMeta.editing.toggleDetailedMode(false);
18342
- // reset the last index back to the first focusable element, when editing gets turned off
18343
- tableMeta.editing.setLastFocusedCellIndex(undefined);
18344
- }
18345
- }, [tableMeta.editing.isEditing]);
18346
- // show a warning if the user navigates away without triggering save, such as using the browser back/forward button
18347
- const hasChanges = tableMeta.editing.hasChanges();
18348
- React__default.useEffect(() => {
18349
- function showUnsavedChangesWarning(event) {
18350
- if (tableMeta.editing.isEditing && hasChanges) {
18351
- event.returnValue = true;
18352
- return true;
18353
- }
18354
- return false;
18355
- }
18356
- window.addEventListener('beforeunload', showUnsavedChangesWarning);
18357
- return () => {
18358
- window.removeEventListener('beforeunload', showUnsavedChangesWarning);
18359
- };
18360
- }, [tableMeta.editing.isEditing, hasChanges]);
18361
- React__default.useEffect(() => {
18362
- if (completedRowsCount > 0) {
18363
- resetHighlightedColumnIndexes(table.getState().globalFilter, table, localization);
18364
- }
18365
- }, [completedRowsCount]);
18366
- React__default.useEffect(() => {
18367
- const onClickOutside = event => {
18368
- if (tableMeta.editing.isEditing) {
18369
- var _event$target$getAttr, _event$target;
18370
- const element = (_event$target$getAttr = (_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.getAttribute('data-taco')) !== null && _event$target$getAttr !== void 0 ? _event$target$getAttr : '';
18371
- const insideTable = isElementInsideOrTriggeredFromContainer(event.target, tableRef.current) || element === 'backdrop';
18372
- if (!insideTable) {
18373
- saveChanges();
18374
- }
18375
- }
18376
- };
18377
- document.addEventListener('click', onClickOutside);
18378
- return () => document.removeEventListener('click', onClickOutside);
18379
- }, [saveChanges, tableMeta.editing.isEditing]);
18380
- }
18381
-
18382
18366
  function willRowMove(cell, change, rowIndex, localization) {
18383
18367
  const {
18384
18368
  table
@@ -18458,444 +18442,642 @@ function willRowMoveAfterSorting(cell, change, rowIndex) {
18458
18442
  }
18459
18443
  return ((_resortedRows$index = resortedRows[index]) === null || _resortedRows$index === void 0 ? void 0 : _resortedRows$index.id) !== cell.row.id;
18460
18444
  }
18461
- function animateCreateRow(id) {
18462
- const templateRow = document.querySelector(`[data-row-id="${id}"]`);
18463
- if (templateRow) {
18464
- const firstCell = templateRow.querySelector(':first-child');
18465
- const checkbox = firstCell === null || firstCell === void 0 ? void 0 : firstCell.querySelector('[data-taco="checkbox"]');
18466
- firstCell === null || firstCell === void 0 ? void 0 : firstCell.focus();
18467
- if (checkbox) {
18468
- setDataFocusAttribute(checkbox);
18469
- }
18470
- templateRow.scrollIntoView();
18471
- const keyframes = [{
18472
- background: '#b2c7ef'
18473
- }, {
18474
- background: '#ebebeb'
18475
- }];
18476
- for (const child of templateRow.children) {
18477
- child.animate(keyframes, {
18478
- duration: 1000,
18479
- easing: 'ease-out'
18480
- });
18481
- }
18445
+ const TEMPORARY_ROW_ID_PREFIX = 'temp-';
18446
+ function isTemporaryRow(rowId) {
18447
+ if (rowId === undefined) {
18448
+ return false;
18482
18449
  }
18450
+ return String(rowId).startsWith(TEMPORARY_ROW_ID_PREFIX);
18483
18451
  }
18452
+ const shortcut = {
18453
+ key: 'e',
18454
+ meta: true,
18455
+ shift: false
18456
+ };
18484
18457
 
18485
- function useTableEditing(isEnabled = false, handleSave, handleChange, validator) {
18486
- // used to switch the table into editing mode
18487
- const [isEditing, toggleEditing] = React__default.useState(false);
18488
- // used to switch the editing between "detailed" mode
18489
- const [isDetailedMode, toggleDetailedMode] = React__default.useState(false);
18490
- // store the last focused cell, so that up/down arrow key navigation remains in the same column
18491
- const [lastFocusedCellIndex, setLastFocusedCellIndex] = useLastFocusedCellIndex();
18492
- // store pending changes for each row
18493
- // changes are saved as soon as the active row changes, so in most cases this will only contain the active row's changes
18494
- // but not always - if validation or server requests fail when saving, those rows remain until the failure is resolved
18495
- const pendingChangesFns = usePendingChanges(isEnabled, handleSave, handleChange, validator);
18496
- useGlobalKeyDown(isEnabled && isEditing ? {
18458
+ function useTableEditingListener(table, tableRef, scrollToIndex) {
18459
+ const tableMeta = table.options.meta;
18460
+ const localization = useLocalization();
18461
+ // save when the row changes
18462
+ // store the last row active index, otherwise everytime tableMeta.editing.saveChanges changes the hook runs again
18463
+ const lastRowActiveIndexRef = React__default.useRef(tableMeta.rowActive.rowActiveIndex);
18464
+ useLazyEffect(() => {
18465
+ if (tableMeta.editing.isEditing && lastRowActiveIndexRef.current !== undefined && tableMeta.rowActive.rowActiveIndex !== lastRowActiveIndexRef.current) {
18466
+ lastRowActiveIndexRef.current = tableMeta.rowActive.rowActiveIndex;
18467
+ tableMeta.editing.saveChanges(table);
18468
+ }
18469
+ }, [tableMeta.rowActive.rowActiveIndex, tableMeta.editing.saveChanges]);
18470
+ // show a warning if the user navigates away without triggering save, such as using the browser back/forward button
18471
+ const hasChanges = tableMeta.editing.hasChanges();
18472
+ React__default.useEffect(() => {
18473
+ function showUnsavedChangesWarning(event) {
18474
+ if (tableMeta.editing.isEditing && hasChanges) {
18475
+ event.returnValue = true;
18476
+ return true;
18477
+ }
18478
+ return false;
18479
+ }
18480
+ window.addEventListener('beforeunload', showUnsavedChangesWarning);
18481
+ return () => {
18482
+ window.removeEventListener('beforeunload', showUnsavedChangesWarning);
18483
+ };
18484
+ }, [tableMeta.editing.isEditing, hasChanges]);
18485
+ const hasSavedChanges = tableMeta.editing.hasSaved();
18486
+ useLazyEffect(() => {
18487
+ if (hasSavedChanges) {
18488
+ resetHighlightedColumnIndexes(table.getState().globalFilter, table, localization);
18489
+ }
18490
+ }, [hasSavedChanges]);
18491
+ React__default.useEffect(() => {
18492
+ const onClickOutside = event => {
18493
+ if (tableMeta.editing.isEditing) {
18494
+ const element = event.target;
18495
+ const insideTable = element.getAttribute('data-taco') === 'backdrop' || element.getAttribute('data-table') === 'editing-toggle' || isElementInsideOrTriggeredFromContainer(element, tableRef.current);
18496
+ // users can click the white space below rows which could be inside the table, but a valid scenario to save
18497
+ if (!insideTable || element.tagName === 'TABLE' || element.tagName === 'TBODY') {
18498
+ tableMeta.editing.saveChanges(table);
18499
+ }
18500
+ }
18501
+ };
18502
+ document.addEventListener('click', onClickOutside);
18503
+ return () => document.removeEventListener('click', onClickOutside);
18504
+ }, [tableMeta.editing.isEditing, tableMeta.editing.saveChanges]);
18505
+ const rows = table.getRowModel().rows;
18506
+ // make sure pending changes are removed for rows that no longer exist
18507
+ useLazyEffect(() => {
18508
+ const pendingChanges = tableMeta.editing.getErrorsShownInAlert();
18509
+ pendingChanges.forEach(pendingChange => {
18510
+ try {
18511
+ table.getRow(pendingChange.rowId);
18512
+ } catch {
18513
+ tableMeta.editing.discardChanges(pendingChange.rowId, table);
18514
+ }
18515
+ });
18516
+ }, [rows.length]);
18517
+ // shortcuts
18518
+ useGlobalKeyDown(tableMeta.editing.isEnabled ? shortcut : undefined, event => {
18519
+ event.preventDefault();
18520
+ tableMeta.editing.toggleEditing(!tableMeta.editing.isEditing, table, scrollToIndex);
18521
+ });
18522
+ useGlobalKeyDown(tableMeta.editing.isEditing ? {
18497
18523
  key: 's',
18498
18524
  meta: true,
18499
18525
  shift: false
18500
18526
  } : undefined, event => {
18501
18527
  event.preventDefault();
18502
- pendingChangesFns.saveChanges();
18528
+ tableMeta.editing.saveChanges(table);
18503
18529
  });
18504
- return {
18505
- isEnabled,
18506
- isEditing,
18507
- isDetailedMode,
18508
- toggleDetailedMode: isEnabled ? toggleDetailedMode : () => undefined,
18509
- toggleEditing: isEnabled ? toggleEditing : () => undefined,
18510
- lastFocusedCellIndex,
18511
- setLastFocusedCellIndex,
18512
- ...pendingChangesFns
18513
- };
18514
18530
  }
18515
- function usePendingChanges(isEnabled, handleSave, handleChange, validator) {
18516
- const saveChanges = function (rowId = undefined) {
18531
+
18532
+ const DELAY_BEFORE_REMOVING_SAVE_STATUS = 3000;
18533
+ function reducer$2(state, action) {
18534
+ const {
18535
+ type,
18536
+ rowId,
18537
+ payload
18538
+ } = action;
18539
+ switch (type) {
18540
+ case 'setCellValue':
18541
+ {
18542
+ const {
18543
+ columnId,
18544
+ row,
18545
+ value
18546
+ } = payload;
18547
+ return {
18548
+ ...state,
18549
+ changes: {
18550
+ ...state.changes,
18551
+ rows: setWith(state.changes.rows, `${rowId}.${columnId}`, value, Object),
18552
+ originals: setWith(state.changes.originals, rowId, row, Object)
18553
+ }
18554
+ };
18555
+ }
18556
+ case 'removeCellValue':
18557
+ {
18558
+ const {
18559
+ columnId,
18560
+ rowIdentityAccessor
18561
+ } = payload;
18562
+ const changes = omit(state.changes.rows, `${rowId}.${columnId}`);
18563
+ // if there are no changes left, remove the row
18564
+ if (!Object.keys(changes[rowId]).length) {
18565
+ return reducer$2(state, {
18566
+ type: 'removeRow',
18567
+ rowId,
18568
+ payload: {
18569
+ rowIdentityAccessor
18570
+ }
18571
+ });
18572
+ }
18573
+ return {
18574
+ ...state,
18575
+ changes: {
18576
+ ...state.changes,
18577
+ rows: omit(state.changes.rows, `${rowId}.${columnId}`),
18578
+ errors: omit(state.changes.errors, `${rowId}.cells.${columnId}`),
18579
+ moveReasons: omit(state.changes.moveReasons, `${rowId}.${columnId}`)
18580
+ }
18581
+ };
18582
+ }
18583
+ case 'updateRow':
18584
+ {
18585
+ const {
18586
+ cellErrors,
18587
+ moveReasons,
18588
+ original,
18589
+ value
18590
+ } = payload;
18591
+ return {
18592
+ ...state,
18593
+ changes: {
18594
+ ...state.changes,
18595
+ rows: setWith(state.changes.rows, rowId, value, Object),
18596
+ errors: setWith(state.changes.errors, `${rowId}.cells`, cellErrors !== null && cellErrors !== void 0 ? cellErrors : state.changes.errors.cells[rowId], Object),
18597
+ originals: setWith(state.changes.originals, rowId, original !== null && original !== void 0 ? original : state.changes.originals[rowId], Object),
18598
+ moveReasons: setWith(state.changes.moveReasons, rowId, moveReasons !== null && moveReasons !== void 0 ? moveReasons : state.changes.moveReasons[rowId], Object),
18599
+ // status can be undefined, so don't use ??
18600
+ status: setWith(state.changes.status, rowId, undefined, Object)
18601
+ }
18602
+ };
18603
+ }
18604
+ case 'removeRow':
18605
+ {
18606
+ const {
18607
+ rowIdentityAccessor
18608
+ } = payload;
18609
+ return {
18610
+ ...state,
18611
+ changes: {
18612
+ ...state.changes,
18613
+ rows: omit(state.changes.rows, rowId),
18614
+ errors: omit(state.changes.errors, rowId),
18615
+ moveReasons: omit(state.changes.moveReasons, rowId),
18616
+ originals: omit(state.changes.originals, rowId),
18617
+ status: omit(state.changes.status, rowId)
18618
+ },
18619
+ temporaryRows: state.temporaryRows.filter(row => row[rowIdentityAccessor] !== rowId)
18620
+ };
18621
+ }
18622
+ case 'setRowStatus':
18623
+ {
18624
+ const {
18625
+ status
18626
+ } = payload;
18627
+ return {
18628
+ ...state,
18629
+ changes: {
18630
+ ...state.changes,
18631
+ status: status ? setWith(state.changes.status, rowId, status, Object) : omit(state.changes.status, rowId)
18632
+ }
18633
+ };
18634
+ }
18635
+ case 'setRowErrors':
18636
+ {
18637
+ const {
18638
+ ...errors
18639
+ } = payload;
18640
+ return {
18641
+ ...state,
18642
+ changes: {
18643
+ ...state.changes,
18644
+ errors: setWith(state.changes.errors, rowId, errors, Object)
18645
+ }
18646
+ };
18647
+ }
18648
+ case 'createRow':
18649
+ {
18650
+ const {
18651
+ value
18652
+ } = payload;
18653
+ return {
18654
+ ...state,
18655
+ temporaryRows: state.temporaryRows.concat(value),
18656
+ changes: {
18657
+ ...state.changes,
18658
+ rows: setWith(state.changes.rows, rowId, value, Object),
18659
+ originals: setWith(state.changes.originals, rowId, value, Object)
18660
+ }
18661
+ };
18662
+ }
18663
+ default:
18664
+ return state;
18665
+ }
18666
+ }
18667
+ function usePendingChangesState(handleSave, handleChange, rowIdentityAccessor, validator) {
18668
+ const saveChanges = function (table, rowId = undefined) {
18517
18669
  try {
18518
18670
  let _exit = false;
18519
18671
  if (!handleSave) {
18520
18672
  console.warn('Tried to save, but Table has no onEditingSave handler');
18521
- return Promise.resolve();
18673
+ return Promise.resolve(false);
18522
18674
  }
18523
- // we save back to pendingChanges, so make a copy of it's state when save was triggered
18524
- const changesToSave = rowId ? {
18525
- [rowId]: pendingChanges[rowId]
18526
- } : {
18527
- ...pendingChanges
18528
- };
18529
- const changes = Object.keys(changesToSave);
18530
- return Promise.resolve(function () {
18531
- if (changes.length) {
18532
- return _forOf(changes, function (rowId) {
18533
- const pendingChange = changesToSave[rowId];
18534
- const changeSet = getChangesetFromChanges(pendingChange);
18535
- return _catch(function () {
18536
- function _temp3(_result) {
18537
- return _exit ? _result : Promise.resolve(handleSave(changeSet)).then(function () {
18538
- // cleanup changes, we don't need them after saving
18539
- resetChanges(rowId);
18540
- setRowSaveStatus(rowId, 'complete');
18541
- });
18542
- }
18543
- if (getRowSaveStatus(rowId) === 'pending') {
18544
- _exit = true;
18545
- return;
18546
- }
18547
- // set saving = true
18548
- setRowSaveStatus(rowId, 'pending');
18549
- // re-run validation, maybe a cell is already invalid but has never been blurred
18550
- const _temp2 = function () {
18551
- if (validator) {
18552
- return Promise.resolve(validator(changeSet)).then(function (errors) {
18553
- if (errors && Object.keys(errors).length) {
18554
- throw errors;
18555
- }
18556
- });
18557
- }
18558
- }();
18559
- return _temp2 && _temp2.then ? _temp2.then(_temp3) : _temp3(_temp2); // send new data to the server
18560
- }, function (error) {
18561
- // the onEditingSave handler should throw errors when something fails, e.g. validation, network errors etc
18562
- // this code handles those errors and maps them either to row errors or cell specific errors
18563
- let rowError;
18564
- let cellErrors;
18565
- if (typeof error === 'string') {
18566
- rowError = error;
18567
- } else if (error instanceof Error) {
18568
- var _error$response;
18569
- rowError = error.message;
18570
- // most of our apis return error objects within this shape
18571
- if (typeof ((_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.data) === 'object') {
18572
- var _error$response2;
18573
- cellErrors = (_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.data;
18675
+ // sometimes we only want to save one row
18676
+ const changes = rowId ? {
18677
+ [rowId]: state.changes.rows[rowId]
18678
+ } : state.changes.rows;
18679
+ let completed = true;
18680
+ const _temp9 = _forOf(Object.keys(changes), function (rowId) {
18681
+ const status = getRowStatus(rowId);
18682
+ return _catch(function () {
18683
+ function _temp8(_result) {
18684
+ return _exit ? _result : Promise.resolve(handleSave(changeSet)).then(function () {
18685
+ // cleanup changes, we don't need them after saving
18686
+ discardChanges(rowId, table);
18687
+ // show the saved status, then remove it after a delay
18688
+ setRowStatus(rowId, 'saved');
18689
+ setTimeout(() => {
18690
+ setRowStatus(rowId, undefined);
18691
+ }, DELAY_BEFORE_REMOVING_SAVE_STATUS);
18692
+ });
18693
+ }
18694
+ // don't try to save if - already saving, or there are known errors
18695
+ if (status === 'saving' || status === 'errored') {
18696
+ return;
18697
+ }
18698
+ setRowStatus(rowId, 'saving');
18699
+ const changeSet = {
18700
+ ...state.changes.originals[rowId],
18701
+ ...changes[rowId]
18702
+ };
18703
+ // if we had to create a temporary id, delete it first - it's our data, not theirs
18704
+ if (isTemporaryRow(changeSet[rowIdentityAccessor])) {
18705
+ delete changeSet[rowIdentityAccessor];
18706
+ }
18707
+ // re-run validation, maybe a cell is already invalid but has never been blurred
18708
+ const _temp7 = function () {
18709
+ if (validator) {
18710
+ return Promise.resolve(validator(changeSet)).then(function (errors) {
18711
+ if (errors && Object.keys(errors).length) {
18712
+ throw errors;
18574
18713
  }
18575
- } else if (typeof error === 'object') {
18576
- cellErrors = error;
18577
- }
18578
- if (rowError || cellErrors) {
18579
- setPendingChanges(currentChanges => {
18580
- const nextChanges = {
18581
- ...currentChanges
18582
- };
18583
- nextChanges[rowId]._meta.errors = {
18584
- row: rowError,
18585
- cells: cellErrors,
18586
- shouldShowErrorAlert: true
18587
- };
18588
- return nextChanges;
18589
- });
18714
+ });
18715
+ }
18716
+ }();
18717
+ return _temp7 && _temp7.then ? _temp7.then(_temp8) : _temp8(_temp7); // send new data to the server
18718
+ }, function (error) {
18719
+ var _error$response;
18720
+ if (error instanceof ReferenceError || error instanceof TypeError || (error === null || error === void 0 ? void 0 : (_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.status) >= 500) {
18721
+ console.error(error);
18722
+ }
18723
+ // the onEditingSave handler should throw errors when something fails, e.g. validation, network errors etc
18724
+ // this code handles those errors and maps them either to row errors or cell specific errors
18725
+ let rowError;
18726
+ let cellErrors;
18727
+ if (typeof error === 'string') {
18728
+ rowError = error;
18729
+ } else if (error instanceof Error) {
18730
+ var _error$response2;
18731
+ rowError = error.message;
18732
+ // most of our apis return error objects within this shape
18733
+ if (typeof ((_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.data) === 'object') {
18734
+ var _error$response3;
18735
+ cellErrors = (_error$response3 = error.response) === null || _error$response3 === void 0 ? void 0 : _error$response3.data;
18736
+ }
18737
+ } else if (typeof error === 'object') {
18738
+ cellErrors = error;
18739
+ }
18740
+ if (rowError || cellErrors) {
18741
+ dispatch({
18742
+ type: 'setRowErrors',
18743
+ rowId,
18744
+ payload: {
18745
+ row: rowError,
18746
+ cells: cellErrors,
18747
+ shouldShowErrorAlert: true
18590
18748
  }
18591
- setRowSaveStatus(rowId, undefined);
18592
18749
  });
18593
- }, function () {
18594
- return _exit;
18595
- });
18596
- }
18597
- }());
18750
+ }
18751
+ setRowStatus(rowId, 'errored');
18752
+ completed = false;
18753
+ });
18754
+ }, function () {
18755
+ return _exit;
18756
+ });
18757
+ return Promise.resolve(_temp9 && _temp9.then ? _temp9.then(function (_result3) {
18758
+ return _exit ? _result3 : completed;
18759
+ }) : _exit ? _temp9 : completed);
18598
18760
  } catch (e) {
18599
18761
  return Promise.reject(e);
18600
18762
  }
18601
18763
  };
18602
- const validateCell = function (cell) {
18764
+ const onCellChanged = function (cell, rowIndex, shouldRunUpdaters = true) {
18603
18765
  try {
18604
- if (!validator || !isEnabled) {
18605
- return Promise.resolve();
18606
- }
18607
- const changeSet = getChangesetFromChanges(pendingChanges[cell.row.id]);
18608
- // only validate if the cell being blurred actually has any changes
18609
- const _temp = function () {
18610
- if (cell.column.id in changeSet) {
18611
- return Promise.resolve(validator(changeSet)).then(function (errors) {
18612
- setPendingChanges(currentChanges => {
18613
- const nextChanges = {
18614
- ...currentChanges
18615
- };
18616
- nextChanges[cell.row.id]._meta = {
18617
- ...nextChanges[cell.row.id]._meta,
18618
- errors: {
18619
- ...nextChanges[cell.row.id]._meta.errors,
18620
- cells: errors,
18621
- shouldShowErrorAlert: !Object.keys(errors).length ? false : nextChanges[cell.row.id]._meta.errors.shouldShowErrorAlert
18766
+ function _temp6() {
18767
+ var _state$changes$errors11;
18768
+ function _temp4() {
18769
+ // only set errors and move reasons for the cells we're currently acting on
18770
+ // why? because the UX is not good if we set them for cells the user hasn't touched yet
18771
+ const cellsToActOn = [cell.column.id, ...Object.keys(updatesForOtherCells)];
18772
+ const allCells = cell.row._getAllCellsByColumnId();
18773
+ cellsToActOn.forEach(accessor => {
18774
+ if (validationErrors[accessor]) {
18775
+ nextCellErrors[accessor] = validationErrors[accessor];
18776
+ // don't show move indicator for cells with errors, they aren't valid and can't be saved
18777
+ delete nextMoveReasons[accessor];
18778
+ } else {
18779
+ var _allCells$accessor;
18780
+ // there isn't any error in this run, remove any error set in state
18781
+ delete nextCellErrors[accessor];
18782
+ if ((_allCells$accessor = allCells[accessor]) !== null && _allCells$accessor !== void 0 && _allCells$accessor.column.getIsSorted()) {
18783
+ // run row move determination
18784
+ const reason = willRowMove(cell, nextChanges[accessor], rowIndex, localization);
18785
+ // if the row will move based on this change save why, otherwise delete any existing state
18786
+ if (reason) {
18787
+ nextMoveReasons[accessor] = reason;
18788
+ } else {
18789
+ delete nextMoveReasons[accessor];
18622
18790
  }
18623
- };
18624
- return nextChanges;
18791
+ }
18792
+ }
18793
+ });
18794
+ dispatch({
18795
+ type: 'updateRow',
18796
+ rowId: cell.row.id,
18797
+ payload: {
18798
+ cellErrors: nextCellErrors,
18799
+ moveReasons: nextMoveReasons,
18800
+ value: nextChanges
18801
+ }
18802
+ });
18803
+ }
18804
+ // create a projection of the next state, so we can act against it
18805
+ const nextChanges = {
18806
+ ...state.changes.rows[cell.row.id],
18807
+ ...updatesForOtherCells
18808
+ };
18809
+ const nextMoveReasons = {
18810
+ ...state.changes.moveReasons[cell.row.id]
18811
+ };
18812
+ const nextCellErrors = {
18813
+ ...((_state$changes$errors11 = state.changes.errors[cell.row.id]) === null || _state$changes$errors11 === void 0 ? void 0 : _state$changes$errors11.cells)
18814
+ };
18815
+ // run validation
18816
+ let validationErrors = {};
18817
+ const _temp3 = function () {
18818
+ if (validator) {
18819
+ const nextRowValue = {
18820
+ ...state.changes.originals[cell.row.id],
18821
+ ...changes,
18822
+ ...updatesForOtherCells
18823
+ };
18824
+ return Promise.resolve(validator(nextRowValue)).then(function (_validator2) {
18825
+ validationErrors = _validator2 !== null && _validator2 !== void 0 ? _validator2 : {};
18625
18826
  });
18827
+ }
18828
+ }();
18829
+ return _temp3 && _temp3.then ? _temp3.then(_temp4) : _temp4(_temp3);
18830
+ }
18831
+ const changes = state.changes.rows[cell.row.id];
18832
+ if (!changes) {
18833
+ return Promise.resolve();
18834
+ }
18835
+ let updatesForOtherCells = {};
18836
+ // run the updater handler if there is one, to see if there are any other cells to update
18837
+ const _temp5 = function () {
18838
+ if (typeof handleChange === 'function' && shouldRunUpdaters) {
18839
+ const previousRowValue = {
18840
+ ...state.changes.originals[cell.row.id]
18841
+ };
18842
+ const nextRowValue = {
18843
+ ...state.changes.originals[cell.row.id],
18844
+ ...changes
18845
+ };
18846
+ return Promise.resolve(handleChange(cell.column.id, changes[cell.column.id], nextRowValue, previousRowValue)).then(function (_handleChange) {
18847
+ updatesForOtherCells = _handleChange !== null && _handleChange !== void 0 ? _handleChange : {};
18626
18848
  });
18627
18849
  }
18628
18850
  }();
18629
- return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
18630
- } catch (e) {
18631
- return Promise.reject(e);
18632
- }
18633
- };
18634
- const setCellValue = function (cell, change, rowIndex) {
18635
- try {
18636
- const changes = {
18637
- [cell.column.id]: change
18638
- };
18639
- setPendingChanges(currentChanges => {
18640
- const nextChanges = createPendingChangesSetter(currentChanges, cell.row, rowIndex, changes, localization);
18641
- pendingChangesUpdater.syncCellChanges(nextChanges);
18642
- return nextChanges;
18643
- });
18644
- pendingChangesUpdater.runCellUpdates(changes, cell, rowIndex);
18645
- return Promise.resolve();
18851
+ return Promise.resolve(_temp5 && _temp5.then ? _temp5.then(_temp6) : _temp6(_temp5));
18646
18852
  } catch (e) {
18647
18853
  return Promise.reject(e);
18648
18854
  }
18649
- };
18650
- const addCreatedRowChangeset = function (row) {
18855
+ }; // general
18856
+ // rows
18857
+ const setRowValue = function (rowId, original, value) {
18651
18858
  try {
18652
- const cells = row.getAllCells();
18653
- setPendingChanges(currentChanges => {
18654
- return cells.reduce((changes, cell) => {
18655
- if (cell.getValue()) {
18656
- var _currentChanges$cell$, _currentChanges$cell$2, _currentChanges$cell$3;
18657
- return {
18658
- ...changes,
18659
- [cell.row.id]: {
18660
- ...changes[cell.row.id],
18661
- [cell.column.id]: cell.getValue(),
18662
- _meta: {
18663
- ...((_currentChanges$cell$ = currentChanges[cell.row.id]) === null || _currentChanges$cell$ === void 0 ? void 0 : _currentChanges$cell$._meta),
18664
- original: cell.row.original,
18665
- moveReason: {
18666
- ...((_currentChanges$cell$2 = currentChanges[cell.row.id]) === null || _currentChanges$cell$2 === void 0 ? void 0 : _currentChanges$cell$2._meta.moveReason)
18667
- },
18668
- errors: {
18669
- ...((_currentChanges$cell$3 = currentChanges[cell.row.id]) === null || _currentChanges$cell$3 === void 0 ? void 0 : _currentChanges$cell$3._meta.errors)
18670
- }
18671
- }
18672
- }
18673
- };
18674
- } else {
18675
- return changes;
18859
+ function _temp2() {
18860
+ dispatch({
18861
+ type: 'updateRow',
18862
+ rowId,
18863
+ payload: {
18864
+ cellErrors,
18865
+ original,
18866
+ value
18676
18867
  }
18677
- }, currentChanges);
18678
- });
18679
- return Promise.resolve();
18868
+ });
18869
+ }
18870
+ let cellErrors;
18871
+ const _temp = function () {
18872
+ if (validator) {
18873
+ const row = {
18874
+ ...original,
18875
+ ...value
18876
+ };
18877
+ return Promise.resolve(validator(row)).then(function (_validator) {
18878
+ cellErrors = _validator !== null && _validator !== void 0 ? _validator : {};
18879
+ });
18880
+ }
18881
+ }();
18882
+ return Promise.resolve(_temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp));
18680
18883
  } catch (e) {
18681
18884
  return Promise.reject(e);
18682
18885
  }
18683
18886
  };
18684
18887
  const localization = useLocalization();
18685
- const [pendingChanges, setPendingChanges] = React__default.useState({});
18686
- // we maintain save status as separate state because 'complete' needs to briefly show after pendingChanges are deleted
18687
- const [saveStates, setSaveState] = React__default.useState({});
18688
- function getCellValue(cell) {
18689
- var _pendingChanges$cell$;
18690
- return (_pendingChanges$cell$ = pendingChanges[cell.row.id]) === null || _pendingChanges$cell$ === void 0 ? void 0 : _pendingChanges$cell$[cell.column.id];
18888
+ const [state, dispatch] = React__default.useReducer(reducer$2, {
18889
+ changes: {
18890
+ rows: {},
18891
+ errors: {},
18892
+ moveReasons: {},
18893
+ originals: {},
18894
+ status: {}
18895
+ },
18896
+ temporaryRows: []
18897
+ });
18898
+ function getRowValue(rowId) {
18899
+ var _state$changes$rows$r, _state$changes$rows;
18900
+ return (_state$changes$rows$r = (_state$changes$rows = state.changes.rows) === null || _state$changes$rows === void 0 ? void 0 : _state$changes$rows[rowId]) !== null && _state$changes$rows$r !== void 0 ? _state$changes$rows$r : undefined;
18691
18901
  }
18692
- function getCellError(cell) {
18693
- var _pendingChanges$cell$2, _pendingChanges$cell$3, _pendingChanges$cell$4;
18694
- return (_pendingChanges$cell$2 = pendingChanges[cell.row.id]) === null || _pendingChanges$cell$2 === void 0 ? void 0 : (_pendingChanges$cell$3 = _pendingChanges$cell$2._meta.errors) === null || _pendingChanges$cell$3 === void 0 ? void 0 : (_pendingChanges$cell$4 = _pendingChanges$cell$3.cells) === null || _pendingChanges$cell$4 === void 0 ? void 0 : _pendingChanges$cell$4[cell.column.id];
18902
+ function getRowMoveReason(rowId) {
18903
+ var _Object$values$, _state$changes$moveRe, _state$changes$moveRe2;
18904
+ return (_Object$values$ = Object.values((_state$changes$moveRe = (_state$changes$moveRe2 = state.changes.moveReasons) === null || _state$changes$moveRe2 === void 0 ? void 0 : _state$changes$moveRe2[rowId]) !== null && _state$changes$moveRe !== void 0 ? _state$changes$moveRe : {})[0]) !== null && _Object$values$ !== void 0 ? _Object$values$ : undefined;
18695
18905
  }
18696
- const pendingChangesUpdater = usePendingChangesUpdater(handleChange, setPendingChanges);
18697
18906
  function hasRowErrors(rowId) {
18698
- var _pendingChanges$rowId, _pendingChanges$rowId2, _pendingChanges$rowId3, _pendingChanges$rowId4, _pendingChanges$rowId5;
18699
- if (!isEnabled) {
18700
- return false;
18701
- }
18702
- return !!((_pendingChanges$rowId = pendingChanges[rowId]) !== null && _pendingChanges$rowId !== void 0 && (_pendingChanges$rowId2 = _pendingChanges$rowId._meta.errors) !== null && _pendingChanges$rowId2 !== void 0 && _pendingChanges$rowId2.row) || !!Object.keys((_pendingChanges$rowId3 = (_pendingChanges$rowId4 = pendingChanges[rowId]) === null || _pendingChanges$rowId4 === void 0 ? void 0 : (_pendingChanges$rowId5 = _pendingChanges$rowId4._meta.errors) === null || _pendingChanges$rowId5 === void 0 ? void 0 : _pendingChanges$rowId5.cells) !== null && _pendingChanges$rowId3 !== void 0 ? _pendingChanges$rowId3 : {}).length;
18907
+ var _state$changes$errors, _state$changes$errors2, _state$changes$errors3;
18908
+ return !!((_state$changes$errors = state.changes.errors[rowId]) !== null && _state$changes$errors !== void 0 && _state$changes$errors.row) || !!Object.keys((_state$changes$errors2 = (_state$changes$errors3 = state.changes.errors[rowId]) === null || _state$changes$errors3 === void 0 ? void 0 : _state$changes$errors3.cells) !== null && _state$changes$errors2 !== void 0 ? _state$changes$errors2 : {}).length;
18703
18909
  }
18704
- function hasRowErrorsSeen(rowId) {
18705
- var _pendingChanges$rowId6;
18706
- if (!isEnabled) {
18910
+ function hasRowErrorsShownInAlert(rowId) {
18911
+ var _state$changes$errors4;
18912
+ return hasRowErrors(rowId) && !!((_state$changes$errors4 = state.changes.errors[rowId]) !== null && _state$changes$errors4 !== void 0 && _state$changes$errors4.shouldShowErrorAlert);
18913
+ }
18914
+ function hasTemporaryRowErrors() {
18915
+ var _state$temporaryRows, _state$changes$errors5, _state$changes$errors6, _state$changes$errors7;
18916
+ const newRow = (_state$temporaryRows = state.temporaryRows) === null || _state$temporaryRows === void 0 ? void 0 : _state$temporaryRows[0];
18917
+ if (!newRow) {
18707
18918
  return false;
18708
18919
  }
18709
- return hasRowErrors(rowId) && !!((_pendingChanges$rowId6 = pendingChanges[rowId]._meta.errors) !== null && _pendingChanges$rowId6 !== void 0 && _pendingChanges$rowId6.shouldShowErrorAlert);
18920
+ const rowId = newRow[rowIdentityAccessor];
18921
+ return !!((_state$changes$errors5 = state.changes.errors[rowId]) !== null && _state$changes$errors5 !== void 0 && _state$changes$errors5.row) || !!Object.keys((_state$changes$errors6 = (_state$changes$errors7 = state.changes.errors[rowId]) === null || _state$changes$errors7 === void 0 ? void 0 : _state$changes$errors7.cells) !== null && _state$changes$errors6 !== void 0 ? _state$changes$errors6 : {}).length;
18710
18922
  }
18711
- function getRowPendingChange(rowId) {
18712
- const rowPendingChanges = pendingChanges[rowId];
18713
- if (rowPendingChanges) {
18714
- const {
18715
- _meta,
18716
- ...pendingChange
18717
- } = rowPendingChanges;
18718
- return pendingChange;
18719
- }
18720
- return undefined;
18923
+ function getRowStatus(rowId) {
18924
+ return state.changes.status[rowId];
18721
18925
  }
18722
- function getRowSaveStatus(rowId) {
18723
- if (!isEnabled) {
18724
- return false;
18725
- }
18726
- return saveStates[rowId];
18926
+ function setRowStatus(rowId, status) {
18927
+ dispatch({
18928
+ type: 'setRowStatus',
18929
+ rowId,
18930
+ payload: {
18931
+ status
18932
+ }
18933
+ });
18727
18934
  }
18728
- function setRowSaveStatus(rowId, status) {
18729
- setSaveState(currentStates => {
18730
- const nextStates = {
18731
- ...currentStates
18732
- };
18733
- if (status) {
18734
- nextStates[rowId] = status;
18735
- } else {
18736
- delete nextStates[rowId];
18935
+ function createRow(data) {
18936
+ const newRowId = `${TEMPORARY_ROW_ID_PREFIX}${uuid.v4()}`;
18937
+ const value = {
18938
+ ...data,
18939
+ [rowIdentityAccessor]: newRowId
18940
+ };
18941
+ dispatch({
18942
+ type: 'createRow',
18943
+ rowId: newRowId,
18944
+ payload: {
18945
+ value
18737
18946
  }
18738
- return nextStates;
18739
18947
  });
18948
+ return newRowId;
18949
+ }
18950
+ // cells
18951
+ function setCellValue(cell, value) {
18952
+ const rowId = cell.row.id;
18953
+ const columnId = cell.column.id;
18954
+ // update if the change is different to the original value
18955
+ if (value !== cell.row.original[columnId]) {
18956
+ dispatch({
18957
+ type: 'setCellValue',
18958
+ rowId,
18959
+ payload: {
18960
+ columnId,
18961
+ row: cell.row.original,
18962
+ value
18963
+ }
18964
+ });
18965
+ }
18966
+ // otherwise remove any previous change - no point saving the same value
18967
+ else if (cell.row.id in state.changes.rows) {
18968
+ dispatch({
18969
+ type: 'removeCellValue',
18970
+ rowId,
18971
+ payload: {
18972
+ columnId,
18973
+ rowIdentityAccessor
18974
+ }
18975
+ });
18976
+ }
18740
18977
  }
18741
- function getRowMoveReason(rowId) {
18742
- var _pendingChanges$rowId7;
18743
- return (_pendingChanges$rowId7 = pendingChanges[rowId]) !== null && _pendingChanges$rowId7 !== void 0 && _pendingChanges$rowId7._meta.moveReason ? Object.values(pendingChanges[rowId]._meta.moveReason)[0] : undefined;
18978
+ function getCellValue(cell) {
18979
+ var _state$changes$rows2, _state$changes$rows2$;
18980
+ return (_state$changes$rows2 = state.changes.rows) === null || _state$changes$rows2 === void 0 ? void 0 : (_state$changes$rows2$ = _state$changes$rows2[cell.row.id]) === null || _state$changes$rows2$ === void 0 ? void 0 : _state$changes$rows2$[cell.column.id];
18744
18981
  }
18745
- function hasChanges(rowId) {
18746
- if (!isEnabled) {
18747
- return false;
18748
- }
18749
- return rowId ? !!pendingChanges[rowId] : !!Object.keys(pendingChanges).length;
18982
+ function getCellError(cell) {
18983
+ var _state$changes$errors8, _state$changes$errors9, _state$changes$errors10;
18984
+ return (_state$changes$errors8 = state.changes.errors) === null || _state$changes$errors8 === void 0 ? void 0 : (_state$changes$errors9 = _state$changes$errors8[cell.row.id]) === null || _state$changes$errors9 === void 0 ? void 0 : (_state$changes$errors10 = _state$changes$errors9.cells) === null || _state$changes$errors10 === void 0 ? void 0 : _state$changes$errors10[cell.column.id];
18750
18985
  }
18751
- function hasAlertErrors() {
18752
- if (!isEnabled) {
18753
- return false;
18986
+ function getErrorsShownInAlert() {
18987
+ const rowsWithErrors = Object.keys(state.changes.errors);
18988
+ if (!rowsWithErrors.length) {
18989
+ return [];
18754
18990
  }
18755
- return !!getAlertErrors().length;
18756
- }
18757
- function getAlertErrors() {
18758
- return Object.keys(pendingChanges).filter(hasRowErrorsSeen).map(rowId => ({
18991
+ return rowsWithErrors.filter(hasRowErrorsShownInAlert).map(rowId => ({
18759
18992
  rowId,
18760
- pendingChange: pendingChanges[rowId]
18993
+ changes: state.changes.rows[rowId],
18994
+ errors: state.changes.errors[rowId]
18761
18995
  }));
18762
18996
  }
18763
- function resetChanges(rowId) {
18764
- setPendingChanges(currentChanges => {
18765
- const nextChanges = {
18766
- ...currentChanges
18767
- };
18768
- delete nextChanges[rowId];
18769
- return nextChanges;
18770
- });
18997
+ function hasSaved() {
18998
+ return !!Object.values(state.changes.status).filter(value => value === 'saved').length;
18999
+ }
19000
+ function hasChanges(rowId) {
19001
+ return rowId ? !!state.changes.rows[rowId] : !!Object.keys(state.changes.rows).length;
18771
19002
  }
18772
- function getCompletedRowsCount() {
18773
- return Object.values(saveStates).filter(value => value === 'complete').length;
19003
+ function discardChanges(rowId, table) {
19004
+ // remove any new rows from pinned state before discarding them
19005
+ table.resetRowPinning(true);
19006
+ dispatch({
19007
+ type: 'removeRow',
19008
+ rowId,
19009
+ payload: {
19010
+ rowIdentityAccessor
19011
+ }
19012
+ });
18774
19013
  }
18775
19014
  return {
19015
+ // row
19016
+ setRowValue,
19017
+ getRowValue,
19018
+ getRowMoveReason,
19019
+ hasRowErrors,
19020
+ hasRowErrorsShownInAlert,
19021
+ hasTemporaryRowErrors,
19022
+ getRowStatus,
19023
+ setRowStatus,
19024
+ // cells
19025
+ setCellValue,
18776
19026
  getCellValue,
18777
19027
  getCellError,
18778
- setCellValue,
18779
- validateCell,
18780
- addCreatedRowChangeset,
19028
+ onCellChanged,
19029
+ // general
19030
+ getErrorsShownInAlert,
18781
19031
  hasChanges,
18782
- hasAlertErrors,
18783
- getAlertErrors,
18784
19032
  saveChanges,
18785
- resetChanges,
18786
- hasRowErrors,
18787
- hasRowErrorsSeen,
18788
- getRowPendingChange,
18789
- getRowSaveStatus,
18790
- setRowSaveStatus,
18791
- getRowMoveReason,
18792
- getCompletedRowsCount
19033
+ discardChanges,
19034
+ hasSaved,
19035
+ // new rows
19036
+ createRow,
19037
+ temporaryRows: state.temporaryRows
18793
19038
  };
18794
19039
  }
18795
- function useLastFocusedCellIndex() {
19040
+
19041
+ function useTableEditing(isEnabled = false, handleSave, handleChange, rowIdentityAccessor, validator) {
19042
+ // used to switch the table into editing mode
19043
+ const [isEditing, setEditing] = React__default.useState(false);
19044
+ // used to switch the editing between "detailed" mode
19045
+ const [isDetailedMode, toggleDetailedMode] = React__default.useState(false);
19046
+ // used to contain ref to the create button
19047
+ const createRowButtonRef = React__default.useRef(null);
18796
19048
  // store the last focused cell, so that up/down arrow key navigation remains in the same column
18797
- const lastFocusedCellIndexRef = React__default.useRef(undefined);
18798
- const setLastFocusedCellIndex = React__default.useCallback(index => {
18799
- lastFocusedCellIndexRef.current = index;
18800
- }, []);
18801
- return [lastFocusedCellIndexRef.current, setLastFocusedCellIndex];
18802
- }
18803
- function usePendingChangesUpdater(handleChange, setPendingChanges) {
18804
- const localization = useLocalization();
18805
- const updatersRef = React__default.useRef({});
18806
- const runCellUpdates = React__default.useCallback(lodash.debounce(function (changes, cell, rowIndex) {
18807
- try {
18808
- const _temp4 = function () {
18809
- if (typeof handleChange === 'function') {
18810
- const previousValues = {
18811
- ...cell.row.original,
18812
- ...getChangesetFromChanges(updatersRef.current[cell.row.id])
18813
- };
18814
- const nextValues = {
18815
- ...previousValues,
18816
- ...changes
18817
- };
18818
- return Promise.resolve(handleChange(cell.column.id, changes[cell.column.id], nextValues, previousValues)).then(function (updates) {
18819
- if (updates && Object.keys(updates).length) {
18820
- setPendingChanges(currentChanges => createPendingChangesSetter(currentChanges, cell.row, rowIndex, updates, localization));
18821
- }
18822
- });
18823
- }
18824
- }();
18825
- return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(function () {}) : void 0);
18826
- } catch (e) {
18827
- return Promise.reject(e);
19049
+ const [lastFocusedCellIndex, setLastFocusedCellIndex] = React__default.useState(undefined);
19050
+ const pendingChangesFns = usePendingChangesState(handleSave, handleChange, rowIdentityAccessor, validator);
19051
+ function toggleEditing(enabled, table, scrollToIndex) {
19052
+ var _tableMeta$rowActive$, _table$getRowModel$ro;
19053
+ if (!enabled) {
19054
+ // save
19055
+ pendingChangesFns.saveChanges(table);
19056
+ // reset detailed mode
19057
+ toggleDetailedMode(false);
19058
+ // reset the last index back to the first focusable element, when editing gets turned off
19059
+ setLastFocusedCellIndex(undefined);
18828
19060
  }
18829
- }, 250), []);
18830
- function syncCellChanges(changes) {
18831
- updatersRef.current = changes;
18832
- }
18833
- return {
18834
- syncCellChanges,
18835
- runCellUpdates
18836
- };
18837
- }
18838
- function createPendingChangesSetter(currentChanges, row, rowIndex, changes, localization) {
18839
- var _currentChanges$row$i, _currentChanges$row$i2, _currentChanges$row$i3;
18840
- // prepare
18841
- const nextChanges = {
18842
- ...currentChanges
18843
- };
18844
- const rowChanges = {
18845
- ...currentChanges[row.id],
18846
- _meta: {
18847
- ...((_currentChanges$row$i = currentChanges[row.id]) === null || _currentChanges$row$i === void 0 ? void 0 : _currentChanges$row$i._meta),
18848
- original: row.original,
18849
- moveReason: {
18850
- ...((_currentChanges$row$i2 = currentChanges[row.id]) === null || _currentChanges$row$i2 === void 0 ? void 0 : _currentChanges$row$i2._meta.moveReason)
18851
- },
18852
- errors: {
18853
- ...((_currentChanges$row$i3 = currentChanges[row.id]) === null || _currentChanges$row$i3 === void 0 ? void 0 : _currentChanges$row$i3._meta.errors)
18854
- }
19061
+ const tableMeta = table.options.meta;
19062
+ const index = (_tableMeta$rowActive$ = tableMeta.rowActive.rowActiveIndex) !== null && _tableMeta$rowActive$ !== void 0 ? _tableMeta$rowActive$ : 0;
19063
+ if (tableMeta.rowActive.rowActiveIndex === undefined) {
19064
+ tableMeta.rowActive.setRowActiveIndex(index);
18855
19065
  }
18856
- };
18857
- // run changes
18858
- const cells = row._getAllCellsByColumnId();
18859
- for (const [accessor, change] of Object.entries(changes)) {
18860
- // update if the change is different to the original (saved) value,
18861
- // otherwise remove any change - no point saving the same value
18862
- if (change !== row.original[accessor]) {
18863
- rowChanges[accessor] = change;
18864
- // consumers sometimes include properties in onEditingChange that aren't rendered as columns, we need to guard against that.
18865
- // eslint-disable-next-line no-prototype-builtins
18866
- if (cells.hasOwnProperty(accessor)) {
18867
- // determine if the row will move position based on this change, and save why it will move
18868
- const reason = willRowMove(cells[accessor], change, rowIndex, localization);
18869
- if (reason) {
18870
- rowChanges._meta.moveReason[accessor] = reason;
18871
- } else {
18872
- delete rowChanges._meta.moveReason[accessor];
18873
- }
18874
- }
18875
- } else {
18876
- delete rowChanges[accessor];
18877
- delete rowChanges._meta.moveReason[accessor];
19066
+ setEditing(enabled);
19067
+ if (!isTemporaryRow((_table$getRowModel$ro = table.getRowModel().rows[index]) === null || _table$getRowModel$ro === void 0 ? void 0 : _table$getRowModel$ro.id)) {
19068
+ scrollToIndex(index);
18878
19069
  }
18879
19070
  }
18880
- // set changes
18881
- // or delete if there are no changes left, so that we don't store changes with unchanged data
18882
- if (Object.keys(rowChanges).filter(k => k !== '_meta').length) {
18883
- nextChanges[row.id] = rowChanges;
18884
- } else {
18885
- delete nextChanges[row.id];
18886
- }
18887
- return nextChanges;
18888
- }
18889
- function getChangesetFromChanges(changes) {
18890
- // extract the original data from the row changes
18891
- const {
18892
- _meta,
18893
- ...changeset
18894
- } = changes !== null && changes !== void 0 ? changes : {};
18895
- // and mix them in with the changes, ready to send to the server
18896
19071
  return {
18897
- ...(_meta === null || _meta === void 0 ? void 0 : _meta.original),
18898
- ...changeset
19072
+ isEnabled,
19073
+ isEditing,
19074
+ isDetailedMode,
19075
+ toggleDetailedMode: isEnabled ? toggleDetailedMode : () => undefined,
19076
+ toggleEditing: isEnabled ? toggleEditing : () => undefined,
19077
+ lastFocusedCellIndex,
19078
+ setLastFocusedCellIndex,
19079
+ createRowButtonRef,
19080
+ ...pendingChangesFns
18899
19081
  };
18900
19082
  }
18901
19083
 
@@ -18939,7 +19121,6 @@ function RowMoveIndicator(props) {
18939
19121
  if (!show) {
18940
19122
  return null;
18941
19123
  }
18942
- const className = 'wcag-blue-500 absolute left-0 top-full ml-1 whitespace-nowrap rounded-b-md px-1 py-1 text-xs font-bold z-10';
18943
19124
  const {
18944
19125
  title,
18945
19126
  description
@@ -18948,7 +19129,7 @@ function RowMoveIndicator(props) {
18948
19129
  placement: "bottom",
18949
19130
  title: description.replace('[COLUMN]', columnMeta.header)
18950
19131
  }, /*#__PURE__*/React__default.createElement("span", {
18951
- className: className
19132
+ "data-row-move-indicator": true
18952
19133
  }, /*#__PURE__*/React__default.createElement(Icon, {
18953
19134
  name: "info",
18954
19135
  className: "-mt-0.5 mr-1 !h-4 !w-4 rounded-full bg-white !p-0 text-blue-500"
@@ -19137,13 +19318,31 @@ function EditingControlCell(props) {
19137
19318
  const {
19138
19319
  rowIndex
19139
19320
  } = React__default.useContext(RowContext);
19140
- const tableMeta = cell.getContext().table.options.meta;
19321
+ const {
19322
+ table
19323
+ } = cell.getContext();
19324
+ const tableMeta = table.options.meta;
19141
19325
  const columnMeta = cell.column.columnDef.meta;
19142
19326
  const isActiveRow = tableMeta.rowActive.rowActiveIndex === rowIndex;
19327
+ const type = (_columnMeta$control = columnMeta.control) !== null && _columnMeta$control !== void 0 ? _columnMeta$control : 'input';
19143
19328
  const handleFocus = useEditingCellAutofocus(props);
19329
+ const value = cell.getValue();
19330
+ // some controls, like select2, should trigger cell changed (validation, updates) as the value changes
19331
+ const hasNonTextControl = React__default.useMemo(() => {
19332
+ var _cellRef$current;
19333
+ return typeof type === 'function' && !!((_cellRef$current = cellRef.current) !== null && _cellRef$current !== void 0 && _cellRef$current.querySelector('[data-taco="Select2"],[data-taco="switch"],[data-taco="checkbox"]'));
19334
+ }, [cellRef.current]);
19335
+ const handleChange = nextValue => {
19336
+ if (nextValue !== value) {
19337
+ tableMeta.editing.setCellValue(cell, nextValue);
19338
+ if (hasNonTextControl) {
19339
+ tableMeta.editing.onCellChanged(cell, rowIndex);
19340
+ }
19341
+ }
19342
+ };
19144
19343
  const handleBlur = () => {
19145
19344
  tableMeta.editing.toggleDetailedMode(false);
19146
- tableMeta.editing.validateCell(cell);
19345
+ tableMeta.editing.onCellChanged(cell, rowIndex, !hasNonTextControl);
19147
19346
  };
19148
19347
  // ensure that blur runs when the cell gets unmounted (when vertically arrow key navigating)
19149
19348
  React__default.useEffect(() => {
@@ -19163,14 +19362,13 @@ function EditingControlCell(props) {
19163
19362
  isDetailedMode: tableMeta.editing.isDetailedMode,
19164
19363
  isTruncated: !!columnMeta.enableTruncate,
19165
19364
  onBlur: handleBlur,
19166
- onChange: value => tableMeta.editing.setCellValue(cell, value, rowIndex),
19365
+ onChange: handleChange,
19167
19366
  row: cell.row.original,
19168
- rowPendingChanges: tableMeta.editing.getRowPendingChange(cell.row.id),
19367
+ rowPendingChanges: tableMeta.editing.getRowValue(cell.row.id),
19169
19368
  tabIndex: isActiveRow ? 0 : -1,
19170
- toggleEditing: tableMeta.editing.toggleEditing,
19171
19369
  toggleDetailedMode: tableMeta.editing.toggleDetailedMode,
19172
- type: (_columnMeta$control = columnMeta.control) !== null && _columnMeta$control !== void 0 ? _columnMeta$control : 'input',
19173
- value: cell.getValue()
19370
+ type,
19371
+ value
19174
19372
  };
19175
19373
  const cellAttributes = {
19176
19374
  ...getCellAttributes(cell, index, isHighlighted),
@@ -19202,7 +19400,6 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19202
19400
  row,
19203
19401
  rowPendingChanges,
19204
19402
  tabIndex = -1,
19205
- toggleEditing,
19206
19403
  toggleDetailedMode,
19207
19404
  type = 'input',
19208
19405
  value
@@ -19268,8 +19465,8 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19268
19465
  }
19269
19466
  // reset the value, or exit edit mode when pressing escape
19270
19467
  if (event.key === 'Escape') {
19271
- event.preventDefault();
19272
19468
  if (isDetailedMode) {
19469
+ event.preventDefault();
19273
19470
  toggleDetailedMode(false);
19274
19471
  if (value !== currentValue) {
19275
19472
  props.onChange(currentValue);
@@ -19279,15 +19476,9 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19279
19476
  var _target$select2;
19280
19477
  return (_target$select2 = target.select) === null || _target$select2 === void 0 ? void 0 : _target$select2.call(target);
19281
19478
  });
19282
- } else {
19283
- toggleEditing(false);
19284
19479
  }
19285
19480
  return;
19286
19481
  }
19287
- const shortcutWhitelist = ['f', 'p', 'e']; // f = search, p = print, and e = edit
19288
- if (isPressingMetaKey(event) && !shortcutWhitelist.some(s => s === event.key)) {
19289
- event.stopPropagation();
19290
- }
19291
19482
  // toggle into detailed mode when actually inputting something
19292
19483
  if (!isPressingMetaKey(event) && (/^[a-z0-9]$/i.test(event.key) || event.key === 'Backspace')) {
19293
19484
  toggleDetailedMode(true);
@@ -19383,12 +19574,37 @@ function Cell$5(props) {
19383
19574
  return /*#__PURE__*/React__default.createElement(DisplayCell, Object.assign({}, props));
19384
19575
  }
19385
19576
 
19577
+ function DiscardChangesConfirmationDialog(props) {
19578
+ const {
19579
+ onDiscard: handleDiscard,
19580
+ ...dialogProps
19581
+ } = props;
19582
+ const {
19583
+ texts
19584
+ } = useLocalization();
19585
+ const handleClickInsideDialogContent = event => {
19586
+ // Prevents the click event from propagating to the table, ensuring the row isn't saved when a click occurs
19587
+ // inside the dialog
19588
+ event.stopPropagation();
19589
+ };
19590
+ return /*#__PURE__*/React__default.createElement(Dialog, Object.assign({}, dialogProps), /*#__PURE__*/React__default.createElement(Dialog.Content, {
19591
+ "aria-label": texts.table3.editing.clearChangesConfirmationDialog.title,
19592
+ onClick: handleClickInsideDialogContent
19593
+ }, /*#__PURE__*/React__default.createElement(Dialog.Title, null, texts.table3.editing.clearChangesConfirmationDialog.title), /*#__PURE__*/React__default.createElement("p", null, texts.table3.editing.clearChangesConfirmationDialog.description), /*#__PURE__*/React__default.createElement(Dialog.Footer, null, /*#__PURE__*/React__default.createElement(Group, null, /*#__PURE__*/React__default.createElement(Dialog.Close, null, /*#__PURE__*/React__default.createElement(Button$1, {
19594
+ tabIndex: 0
19595
+ }, texts.table3.editing.clearChangesConfirmationDialog.cancel)), /*#__PURE__*/React__default.createElement(Dialog.Close, null, /*#__PURE__*/React__default.createElement(Button$1, {
19596
+ autoFocus: true,
19597
+ tabIndex: 0,
19598
+ appearance: "primary",
19599
+ onClick: handleDiscard
19600
+ }, texts.table3.editing.clearChangesConfirmationDialog.confirm))))));
19601
+ }
19602
+
19386
19603
  function EditingActionMenu(props) {
19387
19604
  const {
19388
19605
  hasChanges,
19389
19606
  hasErrors,
19390
- onClear: handleClear,
19391
- onExit: handleExit,
19607
+ onDiscard: handleDiscard,
19392
19608
  onEditingSave: handleSave,
19393
19609
  isLastRow
19394
19610
  } = props;
@@ -19410,7 +19626,6 @@ function EditingActionMenu(props) {
19410
19626
  return /*#__PURE__*/React__default.createElement(IconButton, {
19411
19627
  appearance: "transparent",
19412
19628
  "aria-label": texts.table3.editing.actions.tooltip,
19413
- className: "group-[[data-row-editing-status]]/row:hidden",
19414
19629
  icon: "more",
19415
19630
  onKeyDown: handleKeyDown,
19416
19631
  menu: menuProps => (/*#__PURE__*/React__default.createElement(Menu$1, Object.assign({}, menuProps), /*#__PURE__*/React__default.createElement(Menu$1.Content, {
@@ -19422,42 +19637,13 @@ function EditingActionMenu(props) {
19422
19637
  }, texts.table3.editing.actions.save), /*#__PURE__*/React__default.createElement(Menu$1.Item, {
19423
19638
  icon: "close",
19424
19639
  disabled: !hasChanges,
19425
- dialog: props => /*#__PURE__*/React__default.createElement(ConfirmClearChangesDialog, Object.assign({}, props, {
19426
- onClear: handleClear
19640
+ dialog: props => /*#__PURE__*/React__default.createElement(DiscardChangesConfirmationDialog, Object.assign({}, props, {
19641
+ onDiscard: handleDiscard
19427
19642
  }))
19428
- }, texts.table3.editing.actions.clear), /*#__PURE__*/React__default.createElement(Menu$1.Item, {
19429
- icon: "undo",
19430
- onClick: handleExit
19431
- }, texts.table3.editing.actions.exit))))
19643
+ }, texts.table3.editing.actions.clear))))
19432
19644
  });
19433
19645
  }
19434
- function ConfirmClearChangesDialog(props) {
19435
- const {
19436
- onClear: handleClear,
19437
- ...dialogProps
19438
- } = props;
19439
- const {
19440
- texts
19441
- } = useLocalization();
19442
- const handleClickInsideDialogContent = event => {
19443
- // Prevents the click event from propagating to the table, ensuring the row isn't saved when a click occurs
19444
- // inside the dialog
19445
- event.stopPropagation();
19446
- };
19447
- return /*#__PURE__*/React__default.createElement(Dialog, Object.assign({}, dialogProps), /*#__PURE__*/React__default.createElement(Dialog.Content, {
19448
- "aria-label": texts.table3.editing.clearChangesConfirmationDialog.title,
19449
- onClick: handleClickInsideDialogContent
19450
- }, /*#__PURE__*/React__default.createElement(Dialog.Title, null, texts.table3.editing.clearChangesConfirmationDialog.title), /*#__PURE__*/React__default.createElement("p", null, texts.table3.editing.clearChangesConfirmationDialog.description), /*#__PURE__*/React__default.createElement(Dialog.Footer, null, /*#__PURE__*/React__default.createElement(Group, null, /*#__PURE__*/React__default.createElement(Dialog.Close, null, /*#__PURE__*/React__default.createElement(Button$1, {
19451
- tabIndex: 0
19452
- }, texts.table3.editing.clearChangesConfirmationDialog.cancel)), /*#__PURE__*/React__default.createElement(Dialog.Close, null, /*#__PURE__*/React__default.createElement(Button$1, {
19453
- autoFocus: true,
19454
- tabIndex: 0,
19455
- appearance: "primary",
19456
- onClick: handleClear
19457
- }, texts.table3.editing.clearChangesConfirmationDialog.confirm))))));
19458
- }
19459
19646
 
19460
- const COMPLETE_INDICATOR_DELAY = 3000;
19461
19647
  function SaveStatus(props) {
19462
19648
  const {
19463
19649
  rowId,
@@ -19467,18 +19653,7 @@ function SaveStatus(props) {
19467
19653
  texts
19468
19654
  } = useLocalization();
19469
19655
  const tableMeta = table.options.meta;
19470
- const status = tableMeta.editing.getRowSaveStatus(rowId);
19471
- React__default.useEffect(() => {
19472
- let timeout;
19473
- if (status === 'complete') {
19474
- timeout = setTimeout(() => {
19475
- tableMeta.editing.setRowSaveStatus(rowId, undefined);
19476
- }, COMPLETE_INDICATOR_DELAY);
19477
- }
19478
- return () => {
19479
- clearTimeout(timeout);
19480
- };
19481
- }, [status]);
19656
+ const status = tableMeta.editing.getRowStatus(rowId);
19482
19657
  const className = cn('col-span-full sticky ml-auto right-0 top-0 -mb-[100%] z-10 h-8 bg-[inherit] flex items-center px-1.5 shadow-[-6px_0px_6px_var(--table-row-actions-shadow)]', {
19483
19658
  'mt-0.5': tableMeta.rowHeight.height === 'short',
19484
19659
  'mt-1': tableMeta.rowHeight.height === 'medium',
@@ -19489,7 +19664,7 @@ function SaveStatus(props) {
19489
19664
  className: "!contents"
19490
19665
  }, /*#__PURE__*/React__default.createElement("span", {
19491
19666
  className: className
19492
- }, status === 'pending' ? (/*#__PURE__*/React__default.createElement(Tooltip, {
19667
+ }, status === 'saving' ? (/*#__PURE__*/React__default.createElement(Tooltip, {
19493
19668
  title: texts.table3.editing.saving.progress
19494
19669
  }, /*#__PURE__*/React__default.createElement(Spinner, {
19495
19670
  delay: 0,
@@ -19527,15 +19702,46 @@ function Row$2(props) {
19527
19702
  }
19528
19703
  }
19529
19704
  }, [tableMeta.editing.isEditing, isActiveRow]);
19705
+ const rowStatus = tableMeta.editing.getRowStatus(row.id);
19706
+ // discard new row
19707
+ const [showDiscardDialog, setShowDiscardDialog] = React__default.useState(false);
19708
+ function handleDiscard() {
19709
+ tableMeta.editing.discardChanges(row.id, table);
19710
+ requestAnimationFrame(() => {
19711
+ if (isTemporaryRow(row.id)) {
19712
+ var _tableMeta$editing$cr;
19713
+ (_tableMeta$editing$cr = tableMeta.editing.createRowButtonRef.current) === null || _tableMeta$editing$cr === void 0 ? void 0 : _tableMeta$editing$cr.focus();
19714
+ } else {
19715
+ focusManager.focusFirst();
19716
+ }
19717
+ });
19718
+ }
19719
+ function handleKeyDown(event) {
19720
+ if (props.onKeyDown) {
19721
+ props.onKeyDown(event);
19722
+ }
19723
+ if (event.isDefaultPrevented() || event.isPropagationStopped()) {
19724
+ return;
19725
+ }
19726
+ if (event.key === 'Escape' && tableMeta.editing.hasChanges(row.id) && !isElementTriggeredFromContainer(event.target, event.currentTarget)) {
19727
+ event.preventDefault();
19728
+ setShowDiscardDialog(true);
19729
+ }
19730
+ }
19530
19731
  const attributes = {
19531
- 'data-row-editing-invalid': tableMeta.editing.isEnabled && tableMeta.editing.hasRowErrors(row.id) ? !tableMeta.editing.hasRowErrorsSeen(row.id) ? 'unseen' : true : undefined,
19532
- 'data-row-editing-status': tableMeta.editing.isEnabled && tableMeta.editing.getRowSaveStatus(row.id) ? tableMeta.editing.getRowSaveStatus(row.id) : undefined,
19533
- onFocus: handleFocus
19732
+ 'data-row-editing-invalid': tableMeta.editing.hasRowErrors(row.id) ? !tableMeta.editing.hasRowErrorsShownInAlert(row.id) ? 'unseen' : true : undefined,
19733
+ 'data-row-editing-status': rowStatus,
19734
+ onFocus: handleFocus,
19735
+ onKeyDown: handleKeyDown
19534
19736
  };
19535
- return /*#__PURE__*/React__default.createElement(DisplayRow, Object.assign({}, props, attributes), tableMeta.editing.getRowSaveStatus(row.id) ? /*#__PURE__*/React__default.createElement(SaveStatus, {
19737
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(DisplayRow, Object.assign({}, props, attributes), rowStatus === 'saving' || rowStatus === 'saved' ? /*#__PURE__*/React__default.createElement(SaveStatus, {
19536
19738
  rowId: row.id,
19537
19739
  table: table
19538
- }) : null);
19740
+ }) : null), /*#__PURE__*/React__default.createElement(DiscardChangesConfirmationDialog, {
19741
+ open: showDiscardDialog,
19742
+ onChange: setShowDiscardDialog,
19743
+ onDiscard: handleDiscard
19744
+ }));
19539
19745
  }
19540
19746
 
19541
19747
  const RENDERERS$1 = {
@@ -19543,29 +19749,47 @@ const RENDERERS$1 = {
19543
19749
  cell: Cell$5
19544
19750
  };
19545
19751
  function useTable3(props, ref) {
19546
- const editing = useTableEditing(props.enableEditing, props.onEditingSave, props.onEditingChange, props.validator);
19752
+ const editing = useTableEditing(props.enableEditing, props.onEditingSave, props.onEditingChange, props.rowIdentityAccessor, props.validator);
19547
19753
  const creationEnabled = editing.isEnabled && !!props.onEditingCreate;
19754
+ // this gives me the performance heeby jeebies, but can't think of a better way to internalise the state
19755
+ const data = React__default.useMemo(() => {
19756
+ if (editing.temporaryRows.length) {
19757
+ var _props$data;
19758
+ return ((_props$data = props.data) !== null && _props$data !== void 0 ? _props$data : []).concat(editing.temporaryRows);
19759
+ }
19760
+ return props.data;
19761
+ }, [JSON.stringify(props.data), editing.temporaryRows.length]);
19548
19762
  const extendedProps = {
19549
19763
  ...props,
19764
+ data,
19550
19765
  enableRowActions: editing.isEditing ? true : props.enableRowActions,
19551
- rowActions: editing.isEditing ? [(_, rowId) => (/*#__PURE__*/React__default.createElement(EditingActionMenu, {
19766
+ // Display EditingActionMenu instead of row actions while editing
19767
+ rowActions: editing.isEditing ? [(_, rowId, table) => (/*#__PURE__*/React__default.createElement(EditingActionMenu, {
19552
19768
  hasChanges: editing.hasChanges(rowId),
19553
19769
  hasErrors: editing.hasRowErrors(rowId),
19554
- onClear: () => editing.resetChanges(rowId),
19555
- onEditingSave: () => editing.saveChanges(rowId),
19556
- onExit: () => editing.toggleEditing(false),
19770
+ onDiscard: () => editing.discardChanges(rowId, table),
19771
+ onEditingSave: function () {
19772
+ try {
19773
+ return Promise.resolve(editing.saveChanges(table, rowId)).then(function () {});
19774
+ } catch (e) {
19775
+ return Promise.reject(e);
19776
+ }
19777
+ },
19557
19778
  isLastRow: !creationEnabled && table.meta.rowActive.rowActiveIndex === table.meta.length - 1
19558
19779
  }))] : props.rowActions
19559
19780
  };
19560
19781
  const meta = {
19561
19782
  editing
19562
19783
  };
19563
- const table = useTable(extendedProps, ref, RENDERERS$1, meta);
19784
+ const options = {
19785
+ virtualiserPaddingEndOffset: props.enableEditing && props.onEditingCreate ? editing.hasTemporaryRowErrors() ? 1.4 : 1 : 0
19786
+ };
19787
+ const table = useTable(extendedProps, ref, RENDERERS$1, meta, options);
19564
19788
  // listeners
19565
- useTableEditingListener(table.instance, table.ref);
19789
+ useTableEditingListener(table.instance, table.ref, table.renderer.scrollToIndex);
19566
19790
  React__default.useEffect(() => {
19567
19791
  if (table.ref.current) {
19568
- table.ref.current.instance.toggleEditing = enabled => table.meta.editing.toggleEditing(enabled !== null && enabled !== void 0 ? enabled : editing => !editing);
19792
+ table.ref.current.instance.toggleEditing = enabled => table.meta.editing.toggleEditing(enabled !== null && enabled !== void 0 ? enabled : editing => !editing, table.instance, table.renderer.scrollToIndex);
19569
19793
  }
19570
19794
  }, [table.ref.current]);
19571
19795
  return table;
@@ -19584,7 +19808,7 @@ function Alert$1(props) {
19584
19808
  const validationTexts = texts.table3.editing.validation;
19585
19809
  const tableMeta = table.options.meta;
19586
19810
  const [showFilterResetDialog, setShowFilterResetDialog] = React__default.useState(false);
19587
- const pendingChangesWithErrors = tableMeta.editing.getAlertErrors();
19811
+ const pendingChangesWithErrors = tableMeta.editing.getErrorsShownInAlert();
19588
19812
  function scrollToRow(rowIndex) {
19589
19813
  tableMeta.rowActive.setRowActiveIndex(rowIndex);
19590
19814
  scrollToIndex(rowIndex, {
@@ -19603,38 +19827,43 @@ function Alert$1(props) {
19603
19827
  const title = (pendingChangesWithErrors.length === 1 ? validationTexts.alert.titleOne : validationTexts.alert.titlePlural).replace('[COUNT]', String(pendingChangesWithErrors.length));
19604
19828
  // generate links to each invalid row, to go into the error message
19605
19829
  const links = [];
19606
- const rowIdentityColumn = tableMeta.rowIdentityColumnId ? table.getColumn(tableMeta.rowIdentityColumnId) : undefined;
19607
- pendingChangesWithErrors.forEach((error, index) => {
19830
+ const visibleColumns = table.getVisibleFlatColumns().map(c => c.id);
19831
+ const rowIdentityColumn = tableMeta.rowIdentityAccessor && visibleColumns.includes(String(tableMeta.rowIdentityAccessor)) ? table.getColumn(String(tableMeta.rowIdentityAccessor)) : undefined;
19832
+ pendingChangesWithErrors.forEach((pendingChangeWithError, index) => {
19608
19833
  // if appropriate, concatenate the item with the text "and"
19609
19834
  if (pendingChangesWithErrors.length > 1 && index === pendingChangesWithErrors.length - 1) {
19610
19835
  // Add space before and after `messageAnd` text
19611
19836
  links.push(` ${validationTexts.alert.messageAnd} `);
19612
19837
  }
19613
- const rowIndex = table.getRowModel().rows.findIndex(row => row.id === error.rowId);
19838
+ const rowIndex = table.getRowModel().rows.findIndex(row => row.id === pendingChangeWithError.rowId);
19614
19839
  const handleClick = () => {
19840
+ // if row is visible
19615
19841
  if (rowIndex > -1) {
19616
19842
  scrollToRow(rowIndex);
19617
- } else {
19618
- setShowFilterResetDialog(error.rowId);
19843
+ }
19844
+ // if row is filtered out
19845
+ else {
19846
+ setShowFilterResetDialog(pendingChangeWithError.rowId);
19619
19847
  }
19620
19848
  };
19621
19849
  let tooltip;
19622
- if (error.pendingChange._meta.errors.row) {
19623
- tooltip = error.pendingChange._meta.errors.row;
19850
+ if (pendingChangeWithError.errors.row) {
19851
+ tooltip = pendingChangeWithError.errors.row;
19624
19852
  } else {
19625
19853
  var _table$getAllColumns$, _table$getAllColumns$2;
19626
- const firstCellErrorColumnId = Object.keys(error.pendingChange._meta.errors.cells)[0];
19854
+ const firstCellErrorColumnId = Object.keys(pendingChangeWithError.errors.cells)[0];
19627
19855
  const columnName = (_table$getAllColumns$ = table.getAllColumns().find(column => column.id === firstCellErrorColumnId)) === null || _table$getAllColumns$ === void 0 ? void 0 : (_table$getAllColumns$2 = _table$getAllColumns$.columnDef.meta) === null || _table$getAllColumns$2 === void 0 ? void 0 : _table$getAllColumns$2.header;
19628
- tooltip = `${columnName}: ${error.pendingChange._meta.errors.cells[firstCellErrorColumnId]}`;
19856
+ tooltip = `${columnName}: ${pendingChangeWithError.errors.cells[firstCellErrorColumnId]}`;
19629
19857
  }
19858
+ const row = table.getRow(pendingChangeWithError.rowId).original;
19630
19859
  links.push(/*#__PURE__*/React__default.createElement(Tooltip, {
19631
- key: error.rowId,
19860
+ key: pendingChangeWithError.rowId,
19632
19861
  title: tooltip
19633
19862
  }, /*#__PURE__*/React__default.createElement("span", {
19634
19863
  className: "text-blue",
19635
19864
  onClick: handleClick,
19636
19865
  role: "button"
19637
- }, rowIdentityColumn ? error.pendingChange._meta.original[rowIdentityColumn.id] : rowIndex + 1)));
19866
+ }, rowIdentityColumn ? row[rowIdentityColumn.id] : rowIndex + 1)));
19638
19867
  // if appropriate, concatenate the item with the text ","
19639
19868
  if (pendingChangesWithErrors.length > 2 && index < pendingChangesWithErrors.length - 2) {
19640
19869
  links.push(', ');
@@ -19690,127 +19919,212 @@ function FilterResetDialog(props) {
19690
19919
  }, texts.table3.editing.validation.resetFiltersDialog.confirm)))));
19691
19920
  }
19692
19921
 
19693
- function CreateNewRowButton(props) {
19922
+ function Editing(props) {
19694
19923
  const {
19695
- onEditingCreate,
19696
19924
  scrollToIndex,
19697
- table,
19698
- tableMeta
19925
+ table
19699
19926
  } = props;
19700
19927
  const {
19701
19928
  texts
19702
19929
  } = useLocalization();
19703
- const rows = table.getCoreRowModel().rows.filter(row => row.original !== undefined);
19704
- const [rowCreated, setRowCreated] = React__default.useState({
19705
- rowFinder: undefined
19706
- });
19707
- const handleKeyDown = event => {
19708
- if (!tableMeta.editing.hasChanges() && event.key === 'Tab') {
19709
- tableMeta.editing.saveChanges();
19710
- }
19930
+ const ref = React__default.useRef(null);
19931
+ const tableMeta = table.options.meta;
19932
+ const handleChange = enabled => {
19933
+ tableMeta.editing.toggleEditing(enabled, table, scrollToIndex);
19711
19934
  };
19712
- const handleCreate = function () {
19935
+ const tooltip = /*#__PURE__*/React__default.createElement(React__default.Fragment, null, texts.table3.editing.buttons.edit.tooltip, /*#__PURE__*/React__default.createElement(Shortcut, {
19936
+ className: "ml-2",
19937
+ keys: shortcut
19938
+ }));
19939
+ return /*#__PURE__*/React__default.createElement(Tooltip, {
19940
+ title: tooltip
19941
+ }, /*#__PURE__*/React__default.createElement(ModeSwitch, {
19942
+ "data-table": "editing-toggle",
19943
+ checked: tableMeta.editing.isEditing,
19944
+ onChange: handleChange,
19945
+ ref: ref
19946
+ }));
19947
+ }
19948
+
19949
+ function CreateNewRow(props) {
19950
+ var _temporaryRows$0$tabl, _temporaryRows$, _table$getState$colum;
19951
+ const {
19952
+ buttonRef,
19953
+ onEditingCreate: handleEditingCreate,
19954
+ scrollToIndex,
19955
+ table,
19956
+ tableMeta,
19957
+ tableRef
19958
+ } = props;
19959
+ const {
19960
+ texts
19961
+ } = useLocalization();
19962
+ const temporaryRows = tableMeta.editing.temporaryRows;
19963
+ const temporaryRowId = (_temporaryRows$0$tabl = (_temporaryRows$ = temporaryRows[0]) === null || _temporaryRows$ === void 0 ? void 0 : _temporaryRows$[tableMeta.rowIdentityAccessor]) !== null && _temporaryRows$0$tabl !== void 0 ? _temporaryRows$0$tabl : '';
19964
+ const isDisabled = !!table.getState().globalFilter || !!((_table$getState$colum = table.getState().columnFilters) !== null && _table$getState$colum !== void 0 && _table$getState$colum.length) || !!temporaryRowId && !!tableMeta.editing.hasRowErrors(temporaryRowId);
19965
+ const isSaving = !!temporaryRowId && tableMeta.editing.getRowStatus(temporaryRowId) === 'saving';
19966
+ const createRow = function (row) {
19713
19967
  try {
19714
- if (!onEditingCreate) {
19968
+ if (!handleEditingCreate || isDisabled) {
19715
19969
  return Promise.resolve();
19716
19970
  }
19717
- const createdRow = rows.find(row => {
19718
- var _rowCreated$rowFinder;
19719
- return rowCreated === null || rowCreated === void 0 ? void 0 : (_rowCreated$rowFinder = rowCreated.rowFinder) === null || _rowCreated$rowFinder === void 0 ? void 0 : _rowCreated$rowFinder.call(rowCreated, row.original);
19720
- });
19721
- const _temp = function () {
19722
- if (createdRow) {
19723
- return Promise.resolve(tableMeta.editing.saveChanges()).then(function () {
19724
- if (!tableMeta.editing.hasRowErrors(createdRow.id)) {
19725
- const rowFinder = onEditingCreate();
19726
- setRowCreated({
19727
- rowFinder
19728
- });
19729
- }
19730
- });
19731
- } else {
19732
- const rowFinder = onEditingCreate();
19733
- setRowCreated({
19734
- rowFinder
19735
- });
19971
+ return Promise.resolve(tableMeta.editing.saveChanges(table)).then(function (saved) {
19972
+ if (!saved) {
19973
+ return;
19736
19974
  }
19737
- }();
19738
- return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
19975
+ const changeset = row !== null && row !== void 0 ? row : handleEditingCreate();
19976
+ try {
19977
+ if (changeset) {
19978
+ const rowId = tableMeta.editing.createRow(changeset);
19979
+ table.getRow(rowId).pin('bottom');
19980
+ // set the active row to the new row before toggling editing on
19981
+ const nextRowIndex = temporaryRows.length ? tableMeta.length + 1 : tableMeta.length;
19982
+ tableMeta.rowActive.setRowActiveIndex(nextRowIndex);
19983
+ tableMeta.editing.toggleEditing(true, table, scrollToIndex);
19984
+ tableMeta.editing.setLastFocusedCellIndex(0);
19985
+ }
19986
+ } catch (error) {
19987
+ console.error(error);
19988
+ }
19989
+ });
19739
19990
  } catch (e) {
19740
19991
  return Promise.reject(e);
19741
19992
  }
19742
19993
  };
19994
+ // allow programmatic access to creating rows from outside the table
19743
19995
  React__default.useEffect(() => {
19744
- if (typeof (rowCreated === null || rowCreated === void 0 ? void 0 : rowCreated.rowFinder) === 'function') {
19745
- const createdRow = rows.find(row => {
19746
- var _rowCreated$rowFinder2;
19747
- return rowCreated === null || rowCreated === void 0 ? void 0 : (_rowCreated$rowFinder2 = rowCreated.rowFinder) === null || _rowCreated$rowFinder2 === void 0 ? void 0 : _rowCreated$rowFinder2.call(rowCreated, row.original);
19748
- });
19749
- if (createdRow) {
19750
- const rowInTable = table.getRowModel().rows.filter(row => row.original !== undefined).find(row => {
19751
- var _rowCreated$rowFinder3;
19752
- return rowCreated === null || rowCreated === void 0 ? void 0 : (_rowCreated$rowFinder3 = rowCreated.rowFinder) === null || _rowCreated$rowFinder3 === void 0 ? void 0 : _rowCreated$rowFinder3.call(rowCreated, row.original);
19753
- });
19754
- if (rowInTable) {
19755
- tableMeta.editing.toggleEditing(true);
19756
- tableMeta.rowActive.setRowActiveIndex(createdRow.index);
19757
- scrollToIndex(createdRow.index);
19758
- requestAnimationFrame(() => animateCreateRow(createdRow.id));
19759
- }
19760
- requestAnimationFrame(() => tableMeta.editing.addCreatedRowChangeset(createdRow));
19761
- }
19996
+ if (tableRef.current) {
19997
+ tableRef.current.instance.createRow = createRow;
19762
19998
  }
19763
- }, [rowCreated]);
19999
+ }, [tableRef.current, createRow]);
20000
+ const handleCreate = function () {
20001
+ return createRow();
20002
+ };
20003
+ const shortcut = {
20004
+ key: 'Enter',
20005
+ shift: true
20006
+ };
20007
+ let tooltip;
20008
+ if (isSaving) {
20009
+ tooltip = texts.table3.editing.buttons.create.saving;
20010
+ } else if (isDisabled) {
20011
+ tooltip = texts.table3.editing.buttons.create.disabled;
20012
+ } else {
20013
+ tooltip = /*#__PURE__*/React__default.createElement(Shortcut, {
20014
+ keys: shortcut
20015
+ });
20016
+ }
20017
+ const isScrolled = tableRef.current ? tableRef.current.scrollHeight > tableRef.current.clientHeight : false;
20018
+ const className = cn('group/row border-grey-300 !sticky z-[21]', {
20019
+ 'bottom-10': tableMeta.footer.isEnabled,
20020
+ 'bottom-0': !tableMeta.footer.isEnabled,
20021
+ 'border-t-2': isScrolled,
20022
+ 'border-b': !isScrolled
20023
+ });
19764
20024
  return /*#__PURE__*/React__default.createElement("tr", {
19765
- onClick: handleCreate,
19766
- className: "border-grey-300 hover:bg-grey-100 group !sticky bottom-10 left-0 z-[21] !block cursor-pointer border-t"
20025
+ "data-row-create": true,
20026
+ className: className,
20027
+ tabIndex: -1
19767
20028
  }, /*#__PURE__*/React__default.createElement("td", {
19768
- className: "!border-t-0 !bg-transparent"
20029
+ className: "!bg-grey-50 col-span-full !border-b-0 !px-1"
19769
20030
  }, /*#__PURE__*/React__default.createElement(Button$1, {
19770
- onKeyDown: handleKeyDown,
19771
- className: "group-hover:bg-grey-200 sticky left-0",
19772
- appearance: "transparent"
19773
- }, "+ ", texts.table3.editing.buttons.create.label)));
20031
+ appearance: "transparent",
20032
+ className: "group-hover:bg-grey-200 sticky left-[4px]",
20033
+ disabled: isDisabled,
20034
+ onClick: handleCreate,
20035
+ ref: buttonRef,
20036
+ shortcut: shortcut,
20037
+ tooltip: tooltip
20038
+ }, /*#__PURE__*/React__default.createElement(Icon, {
20039
+ name: "circle-plus"
20040
+ }), texts.table3.editing.buttons.create.label)));
19774
20041
  }
19775
20042
 
19776
- function Editing(props) {
20043
+ function TemporaryRow(props) {
19777
20044
  const {
19778
- scrollToIndex,
19779
- table
20045
+ createRowButtonRef,
20046
+ table,
20047
+ tableMeta,
20048
+ tableRef
19780
20049
  } = props;
19781
- const {
19782
- texts
19783
- } = useLocalization();
19784
- const ref = React__default.useRef(null);
19785
- const tableMeta = table.options.meta;
19786
- const shortcut = {
19787
- key: 'e',
19788
- meta: true,
19789
- shift: false
20050
+ const handleKeyDown = function (event) {
20051
+ try {
20052
+ const _temp2 = function () {
20053
+ if (event.key === 'ArrowDown') {
20054
+ event.preventDefault();
20055
+ const _temp = function () {
20056
+ if (!isElementTriggeredFromContainer(event.target, event.currentTarget)) {
20057
+ return Promise.resolve(tableMeta.editing.saveChanges(table)).then(function (saved) {
20058
+ if (saved) {
20059
+ var _createRowButtonRef$c;
20060
+ (_createRowButtonRef$c = createRowButtonRef.current) === null || _createRowButtonRef$c === void 0 ? void 0 : _createRowButtonRef$c.focus();
20061
+ }
20062
+ });
20063
+ }
20064
+ }();
20065
+ if (_temp && _temp.then) return _temp.then(function () {});
20066
+ } else if (event.key === 'ArrowUp') {
20067
+ event.preventDefault();
20068
+ event.stopPropagation();
20069
+ if (tableRef.current) {
20070
+ var _tableRef$current$que, _tableRef$current$que2, _tableRef$current$que3;
20071
+ const availableRows = Array.from((_tableRef$current$que = tableRef.current.querySelectorAll(`tbody tr:not([data-row-id^='${TEMPORARY_ROW_ID_PREFIX}'])`)) !== null && _tableRef$current$que !== void 0 ? _tableRef$current$que : []);
20072
+ const footerHeight = (_tableRef$current$que2 = (_tableRef$current$que3 = tableRef.current.querySelector('tfoot')) === null || _tableRef$current$que3 === void 0 ? void 0 : _tableRef$current$que3.getBoundingClientRect().height) !== null && _tableRef$current$que2 !== void 0 ? _tableRef$current$que2 : 0;
20073
+ const newRowHeight = event.currentTarget.getBoundingClientRect().height;
20074
+ const visibleHeight = tableRef.current.clientHeight - footerHeight - newRowHeight;
20075
+ const tableTopOffset = tableRef.current.getBoundingClientRect().top;
20076
+ let nextRowIndex;
20077
+ // iterate available rows in reverse order, since we're working at the bottom
20078
+ for (let index = availableRows.length - 1; index >= 0; index--) {
20079
+ const rowRect = availableRows[index].getBoundingClientRect();
20080
+ const topPlusHalfRow = rowRect.top + rowRect.height / 2;
20081
+ if (topPlusHalfRow - tableTopOffset <= visibleHeight) {
20082
+ nextRowIndex = index;
20083
+ break;
20084
+ }
20085
+ }
20086
+ if (nextRowIndex) {
20087
+ tableMeta.rowActive.setRowActiveIndex(Number(availableRows[nextRowIndex < 0 ? 0 : nextRowIndex].getAttribute('data-row-index')));
20088
+ }
20089
+ }
20090
+ }
20091
+ }();
20092
+ return Promise.resolve(_temp2 && _temp2.then ? _temp2.then(function () {}) : void 0);
20093
+ } catch (e) {
20094
+ return Promise.reject(e);
20095
+ }
19790
20096
  };
19791
- const tooltip = /*#__PURE__*/React__default.createElement(React__default.Fragment, null, texts.table3.editing.buttons.edit.tooltip, /*#__PURE__*/React__default.createElement(Shortcut, {
19792
- className: "ml-2",
19793
- keys: shortcut
19794
- }));
19795
- useGlobalKeyDown(shortcut, event => {
19796
- var _ref$current;
19797
- event.preventDefault();
19798
- (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.click();
19799
- });
19800
- const handleChange = enabled => {
19801
- tableMeta.editing.toggleEditing(enabled);
19802
- requestAnimationFrame(() => {
19803
- var _tableMeta$rowActive$;
19804
- return scrollToIndex((_tableMeta$rowActive$ = tableMeta.rowActive.rowActiveIndex) !== null && _tableMeta$rowActive$ !== void 0 ? _tableMeta$rowActive$ : 0);
19805
- });
20097
+ const handleKeyDownCapture = event => {
20098
+ if (event.key === 'ArrowLeft' && tableMeta.editing.lastFocusedCellIndex === 0) {
20099
+ event.preventDefault();
20100
+ event.stopPropagation();
20101
+ } else if (event.key === 'ArrowRight' && tableMeta.editing.lastFocusedCellIndex) {
20102
+ if (tableMeta.editing.lastFocusedCellIndex === table.getVisibleFlatColumns().length - 1) {
20103
+ event.preventDefault();
20104
+ event.stopPropagation();
20105
+ }
20106
+ }
19806
20107
  };
19807
- return /*#__PURE__*/React__default.createElement(Tooltip, {
19808
- title: tooltip
19809
- }, /*#__PURE__*/React__default.createElement(ModeSwitch, {
19810
- checked: tableMeta.editing.isEditing,
19811
- onChange: handleChange,
19812
- ref: ref
19813
- }));
20108
+ const isScrolled = tableRef.current ? tableRef.current.scrollHeight > tableRef.current.clientHeight : false;
20109
+ const className = cn('group/row border-grey-300 !sticky z-[22]', {
20110
+ 'bottom-[calc(5rem_+_3px)] data-[row-editing-move]:bottom-[calc(5rem_+_2px)]': tableMeta.footer.isEnabled,
20111
+ 'bottom-[calc(2.5rem_+_3px)] data-[row-editing-move]:bottom-[calc(2.5rem_+_2px)]': !tableMeta.footer.isEnabled,
20112
+ 'border-t-2 shadow-[0px_-5px_20px_0px_rgba(0,0,0,0.1)] [&>td]:!border-b-0': isScrolled
20113
+ });
20114
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, table.getBottomRows().map(row => (/*#__PURE__*/React__default.createElement(Row, {
20115
+ key: row.id,
20116
+ cellRenderer: RENDERERS$1.cell,
20117
+ index: tableMeta.length,
20118
+ measureRow: () => null,
20119
+ renderer: RENDERERS$1.row,
20120
+ row: row,
20121
+ table: table,
20122
+ className: className,
20123
+ onKeyDown: handleKeyDown,
20124
+ onKeyDownCapture: handleKeyDownCapture,
20125
+ // Row actions should only be hidden on temporary rows when editing is turned off
20126
+ hideRowActions: !tableMeta.editing.isEditing
20127
+ }))));
19814
20128
  }
19815
20129
 
19816
20130
  function Column$3(_) {
@@ -19828,8 +20142,8 @@ const BaseTable3 = /*#__PURE__*/fixedForwardRef(function BaseTable3(props, ref)
19828
20142
  'data-table-editing-mode': (_table3$meta$editing = table3.meta.editing) !== null && _table3$meta$editing !== void 0 && _table3$meta$editing.isEditing ? (_table3$meta$editing2 = table3.meta.editing) !== null && _table3$meta$editing2 !== void 0 && _table3$meta$editing2.isDetailedMode ? 'detailed' : 'normal' : undefined,
19829
20143
  enableHorizontalArrowKeyNavigation: table3.meta.editing.isEditing
19830
20144
  };
19831
- const hasAlertErrors = table3.meta.editing.hasAlertErrors();
19832
- const showCreateRowButton = table3.meta.editing.isEnabled && props.onEditingCreate;
20145
+ const hasAlertErrors = table3.meta.editing.getErrorsShownInAlert().length;
20146
+ const hasCreateWorkflow = table3.meta.editing.isEnabled && props.onEditingCreate;
19833
20147
  return /*#__PURE__*/React__default.createElement(Table, null, /*#__PURE__*/React__default.createElement(Table.Toolbar, {
19834
20148
  table: table3
19835
20149
  }, table3.meta.editing.isEnabled ? (/*#__PURE__*/React__default.createElement(Editing, {
@@ -19843,12 +20157,19 @@ const BaseTable3 = /*#__PURE__*/fixedForwardRef(function BaseTable3(props, ref)
19843
20157
  })) : null, /*#__PURE__*/React__default.createElement(Table.Grid, Object.assign({}, gridAttributes, {
19844
20158
  "data-taco": "table3",
19845
20159
  table: table3
19846
- }), showCreateRowButton && (/*#__PURE__*/React__default.createElement(CreateNewRowButton, {
20160
+ }), hasCreateWorkflow ? (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(TemporaryRow, {
20161
+ createRowButtonRef: table3.meta.editing.createRowButtonRef,
19847
20162
  table: table3.instance,
19848
20163
  tableMeta: table3.meta,
20164
+ tableRef: table3.ref
20165
+ }), /*#__PURE__*/React__default.createElement(CreateNewRow, {
20166
+ buttonRef: table3.meta.editing.createRowButtonRef,
19849
20167
  onEditingCreate: props.onEditingCreate,
19850
- scrollToIndex: table3.renderer.scrollToIndex
19851
- }))));
20168
+ scrollToIndex: table3.renderer.scrollToIndex,
20169
+ table: table3.instance,
20170
+ tableMeta: table3.meta,
20171
+ tableRef: table3.ref
20172
+ }))) : null));
19852
20173
  });
19853
20174
  const Table3 = /*#__PURE__*/fixedForwardRef(function Table3(props, ref) {
19854
20175
  const stringifiedChildren = String(props.children);