@economic/taco 2.44.4 → 2.44.5-create.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) 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 +13 -0
  7. package/dist/components/Table3/components/Row/Editing/TemporaryRow.d.ts +11 -0
  8. package/dist/components/Table3/features/useEditingState.d.ts +28 -0
  9. package/dist/components/Table3/features/useTableEditing.d.ts +25 -36
  10. package/dist/components/Table3/types.d.ts +23 -8
  11. package/dist/components/Table3/useTable3.d.ts +6 -0
  12. package/dist/components/Table3/util/editing.d.ts +2 -1
  13. package/dist/esm/index.css +6 -2
  14. package/dist/esm/node_modules/babel-plugin-transform-async-to-promises/helpers.mjs.js +17 -17
  15. package/dist/esm/node_modules/babel-plugin-transform-async-to-promises/helpers.mjs.js.map +1 -1
  16. package/dist/esm/packages/taco/src/components/ModeSwitch/ModeSwitch.js +2 -2
  17. package/dist/esm/packages/taco/src/components/ModeSwitch/ModeSwitch.js.map +1 -1
  18. package/dist/esm/packages/taco/src/components/Provider/Localization.js +5 -3
  19. package/dist/esm/packages/taco/src/components/Provider/Localization.js.map +1 -1
  20. package/dist/esm/packages/taco/src/components/Switch/Switch.js +1 -1
  21. package/dist/esm/packages/taco/src/components/Switch/Switch.js.map +1 -1
  22. package/dist/esm/packages/taco/src/components/Table3/Table3.js +19 -7
  23. package/dist/esm/packages/taco/src/components/Table3/Table3.js.map +1 -1
  24. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Cell/EditingControlCell.js +21 -10
  25. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Cell/EditingControlCell.js.map +1 -1
  26. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Internal/EditingActionsMenu.js +5 -37
  27. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Internal/EditingActionsMenu.js.map +1 -1
  28. package/dist/esm/packages/taco/src/components/Table3/components/Editing/Alert.js +17 -12
  29. package/dist/esm/packages/taco/src/components/Table3/components/Editing/Alert.js.map +1 -1
  30. package/dist/esm/packages/taco/src/components/Table3/components/Editing/DiscardChangesConfirmationDialog.js +34 -0
  31. package/dist/esm/packages/taco/src/components/Table3/components/Editing/DiscardChangesConfirmationDialog.js.map +1 -0
  32. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateNewRow.js +88 -0
  33. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateNewRow.js.map +1 -0
  34. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/SaveStatus.js +2 -14
  35. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/SaveStatus.js.map +1 -1
  36. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/TemporaryRow.js +95 -0
  37. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/TemporaryRow.js.map +1 -0
  38. package/dist/esm/packages/taco/src/components/Table3/components/Row/Row.js +39 -6
  39. package/dist/esm/packages/taco/src/components/Table3/components/Row/Row.js.map +1 -1
  40. package/dist/esm/packages/taco/src/components/Table3/components/Toolbar/Editing/Editing.js +7 -2
  41. package/dist/esm/packages/taco/src/components/Table3/components/Toolbar/Editing/Editing.js.map +1 -1
  42. package/dist/esm/packages/taco/src/components/Table3/features/useEditingState.js +512 -0
  43. package/dist/esm/packages/taco/src/components/Table3/features/useEditingState.js.map +1 -0
  44. package/dist/esm/packages/taco/src/components/Table3/features/useTableEditing.js +19 -406
  45. package/dist/esm/packages/taco/src/components/Table3/features/useTableEditing.js.map +1 -1
  46. package/dist/esm/packages/taco/src/components/Table3/listeners/useTableEditingListener.js +37 -32
  47. package/dist/esm/packages/taco/src/components/Table3/listeners/useTableEditingListener.js.map +1 -1
  48. package/dist/esm/packages/taco/src/components/Table3/useTable3.js +25 -8
  49. package/dist/esm/packages/taco/src/components/Table3/useTable3.js.map +1 -1
  50. package/dist/esm/packages/taco/src/components/Table3/util/editing.js +6 -24
  51. package/dist/esm/packages/taco/src/components/Table3/util/editing.js.map +1 -1
  52. package/dist/esm/packages/taco/src/primitives/Collection/components/Root.js +18 -2
  53. package/dist/esm/packages/taco/src/primitives/Collection/components/Root.js.map +1 -1
  54. package/dist/esm/packages/taco/src/primitives/Listbox2/components/Root.js +1 -0
  55. package/dist/esm/packages/taco/src/primitives/Listbox2/components/Root.js.map +1 -1
  56. package/dist/esm/packages/taco/src/primitives/Table/Core/Table.js +3 -4
  57. package/dist/esm/packages/taco/src/primitives/Table/Core/Table.js.map +1 -1
  58. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Cell/BuiltIns/GroupedCell.js +9 -3
  59. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Cell/BuiltIns/GroupedCell.js.map +1 -1
  60. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Internal/Actions.js +6 -3
  61. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Internal/Actions.js.map +1 -1
  62. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Footer/Footer.js +1 -1
  63. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Footer/Footer.js.map +1 -1
  64. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/BuiltIns/DisplayRow.js +1 -1
  65. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/BuiltIns/DisplayRow.js.map +1 -1
  66. package/dist/esm/packages/taco/src/primitives/Table/Core/features/useTableRenderer.js +23 -6
  67. package/dist/esm/packages/taco/src/primitives/Table/Core/features/useTableRenderer.js.map +1 -1
  68. package/dist/esm/packages/taco/src/primitives/Table/Core/useTable.js +2 -2
  69. package/dist/esm/packages/taco/src/primitives/Table/Core/useTable.js.map +1 -1
  70. package/dist/esm/packages/taco/src/primitives/Table/types.js.map +1 -1
  71. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/useTableManager.js +1 -1
  72. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/useTableManager.js.map +1 -1
  73. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/util/setup.js +11 -0
  74. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/util/setup.js.map +1 -1
  75. package/dist/esm/packages/taco/src/utils/dom.js +7 -4
  76. package/dist/esm/packages/taco/src/utils/dom.js.map +1 -1
  77. package/dist/index.css +6 -2
  78. package/dist/primitives/Collection/components/Root.d.ts +2 -0
  79. package/dist/primitives/Table/Core/Table.d.ts +1 -0
  80. package/dist/primitives/Table/Core/components/Columns/Internal/Actions.d.ts +3 -1
  81. package/dist/primitives/Table/Core/components/Footer/Footer.d.ts +2 -2
  82. package/dist/primitives/Table/Core/features/useTableRenderer.d.ts +2 -2
  83. package/dist/primitives/Table/Core/features/useTableStyle.d.ts +1 -1
  84. package/dist/primitives/Table/Core/types.d.ts +3 -0
  85. package/dist/primitives/Table/Core/useTable.d.ts +2 -2
  86. package/dist/primitives/Table/types.d.ts +1 -1
  87. package/dist/primitives/Table/useTableManager/useTableManager.d.ts +1 -1
  88. package/dist/taco.cjs.development.js +941 -628
  89. package/dist/taco.cjs.development.js.map +1 -1
  90. package/dist/taco.cjs.production.min.js +1 -1
  91. package/dist/taco.cjs.production.min.js.map +1 -1
  92. package/dist/utils/dom.d.ts +1 -0
  93. package/package.json +3 -5
  94. package/dist/components/Table3/components/Row/Editing/CreateRowButton.d.ts +0 -11
  95. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateRowButton.js +0 -90
  96. 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);
@@ -4205,7 +4206,7 @@ const getOverlaySelector = element => {
4205
4206
  return undefined;
4206
4207
  }
4207
4208
  };
4208
- function isElementInsideOrTriggeredFromContainer(element, container) {
4209
+ function isElementTriggeredFromContainer(element, container) {
4209
4210
  var _getOverlaySelector, _element$closest;
4210
4211
  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);
4211
4212
  if (selector) {
@@ -4215,11 +4216,14 @@ function isElementInsideOrTriggeredFromContainer(element, container) {
4215
4216
  const elementInDocument = document.querySelector(selector);
4216
4217
  // if the element does exist, see if it is itself connected to somethng that was triggered from the container
4217
4218
  if (elementInDocument) {
4218
- return isElementInsideOrTriggeredFromContainer(elementInDocument, container);
4219
+ return isElementTriggeredFromContainer(elementInDocument, container);
4219
4220
  }
4220
4221
  return false;
4221
4222
  }
4222
- return !!(container !== null && container !== void 0 && container.contains(element));
4223
+ return false;
4224
+ }
4225
+ function isElementInsideOrTriggeredFromContainer(element, container) {
4226
+ return isElementTriggeredFromContainer(element, container) || !!(container !== null && container !== void 0 && container.contains(element));
4223
4227
  }
4224
4228
  function isElementInsideOverlay(element) {
4225
4229
  return !!(element !== null && element !== void 0 && element.closest('[role=dialog],[role=menu]'));
@@ -4713,7 +4717,9 @@ const defaultLocalisationTexts = {
4713
4717
  tooltip: 'Edit table'
4714
4718
  },
4715
4719
  create: {
4716
- label: 'New'
4720
+ label: 'New',
4721
+ disabled: 'Existing new row must be saved',
4722
+ saving: 'Saving...'
4717
4723
  }
4718
4724
  },
4719
4725
  clearChangesConfirmationDialog: {
@@ -4735,8 +4741,8 @@ const defaultLocalisationTexts = {
4735
4741
  },
4736
4742
  validation: {
4737
4743
  alert: {
4738
- titleOne: '[COUNT] unsaved entry:',
4739
- titlePlural: '[COUNT] unsaved entries:',
4744
+ titleOne: '[COUNT] unsaved row:',
4745
+ titlePlural: '[COUNT] unsaved rows:',
4740
4746
  messageOne: "[COLUMN] [ROW] is incomplete and hasn't been saved.",
4741
4747
  messagePlural: "[COLUMN] [ROW] are incomplete and haven't been saved.",
4742
4748
  messageRow: 'Row',
@@ -7632,7 +7638,7 @@ const Switch = /*#__PURE__*/React.forwardRef(function Switch(props, ref) {
7632
7638
  onCheckedChange: onChange,
7633
7639
  ref: ref
7634
7640
  }), /*#__PURE__*/React.createElement(PrimitiveSwitch.Thumb, {
7635
- 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]"
7641
+ 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]"
7636
7642
  }));
7637
7643
  if (label) {
7638
7644
  const labelContainerClassName = cn('flex self-start cursor-pointer', {
@@ -8692,10 +8698,10 @@ const ModeSwitch = /*#__PURE__*/React.forwardRef(function ModeSwitch(props, ref)
8692
8698
  onCheckedChange: onChange,
8693
8699
  ref: ref
8694
8700
  }), /*#__PURE__*/React.createElement(PrimitiveSwitch.Thumb, {
8695
- 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%]"
8701
+ 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%]"
8696
8702
  }, /*#__PURE__*/React.createElement(Icon, {
8697
8703
  name: "edit-simple",
8698
- className: "!h-5 !w-5"
8704
+ className: "pointer-events-none !h-5 !w-5"
8699
8705
  })));
8700
8706
  });
8701
8707
  ModeSwitch.displayName = 'ModeSwitch';
@@ -10398,6 +10404,15 @@ function configureReactTableOptions(options, props, localization) {
10398
10404
  // We don't want to expose internal Tanstack Table row, so we need to wrap enableRowSelection callback into additional function,
10399
10405
  // which receives the React Table Row object and passes row.original to a callback.
10400
10406
  const reactTableEnableRowSelection = typeof options.enableRowSelection === 'function' ? row => options.enableRowSelection(row.original) : options.enableRowSelection;
10407
+ let getRowId;
10408
+ if (props.rowIdentityAccessor) {
10409
+ getRowId = (originalRow, index) => {
10410
+ if (originalRow) {
10411
+ return originalRow[props.rowIdentityAccessor];
10412
+ }
10413
+ return String(index);
10414
+ };
10415
+ }
10401
10416
  const tableOptions = {
10402
10417
  defaultColumn: {
10403
10418
  enableColumnFilter: options.enableFiltering || true,
@@ -10416,11 +10431,13 @@ function configureReactTableOptions(options, props, localization) {
10416
10431
  enableGrouping: true,
10417
10432
  enableHiding: (_options$enableColumn2 = options.enableColumnHiding) !== null && _options$enableColumn2 !== void 0 ? _options$enableColumn2 : false,
10418
10433
  enablePinning: (_options$enableColumn3 = options.enableColumnFreezing) !== null && _options$enableColumn3 !== void 0 ? _options$enableColumn3 : false,
10434
+ enableRowPinning: true,
10419
10435
  enableRowSelection: reactTableEnableRowSelection !== null && reactTableEnableRowSelection !== void 0 ? reactTableEnableRowSelection : false,
10420
10436
  enableSorting: (_options$enableSortin = options.enableSorting) !== null && _options$enableSortin !== void 0 ? _options$enableSortin : false,
10421
10437
  // models for default features
10422
10438
  getExpandedRowModel: reactTable.getExpandedRowModel(),
10423
10439
  getGroupedRowModel: reactTable.getGroupedRowModel(),
10440
+ getRowId,
10424
10441
  groupedColumnMode: false
10425
10442
  };
10426
10443
  if (tableOptions.enableColumnResizing) {
@@ -10964,13 +10981,13 @@ function useTableSearch(isEnabled = false, defaultEnableGlobalFilter = false) {
10964
10981
  }
10965
10982
 
10966
10983
  // A type of promise-like that resolves synchronously and supports only one observer
10967
- const _Pact = /*#__PURE__*/function () {
10984
+ var _Pact = /*#__PURE__*/function () {
10968
10985
  function _Pact() {}
10969
10986
  _Pact.prototype.then = function (onFulfilled, onRejected) {
10970
- const result = new _Pact();
10971
- const state = this.s;
10987
+ var result = new _Pact();
10988
+ var state = this.s;
10972
10989
  if (state) {
10973
- const callback = state & 1 ? onFulfilled : onRejected;
10990
+ var callback = state & 1 ? onFulfilled : onRejected;
10974
10991
  if (callback) {
10975
10992
  try {
10976
10993
  _settle(result, 1, callback(this.v));
@@ -10984,7 +11001,7 @@ const _Pact = /*#__PURE__*/function () {
10984
11001
  }
10985
11002
  this.o = function (_this) {
10986
11003
  try {
10987
- const value = _this.v;
11004
+ var value = _this.v;
10988
11005
  if (_this.s & 1) {
10989
11006
  _settle(result, 1, onFulfilled ? onFulfilled(value) : value);
10990
11007
  } else if (onRejected) {
@@ -11021,7 +11038,7 @@ function _settle(pact, state, value) {
11021
11038
  }
11022
11039
  pact.s = state;
11023
11040
  pact.v = value;
11024
- const observer = pact.o;
11041
+ var observer = pact.o;
11025
11042
  if (observer) {
11026
11043
  observer(pact);
11027
11044
  }
@@ -11061,17 +11078,13 @@ function _forTo(array, body, check) {
11061
11078
  _cycle();
11062
11079
  return pact;
11063
11080
  }
11064
- const _iteratorSymbol = /*#__PURE__*/typeof Symbol !== "undefined" ? Symbol.iterator || (Symbol.iterator = /*#__PURE__*/Symbol("Symbol.iterator")) : "@@iterator";
11081
+ var _iteratorSymbol = /*#__PURE__*/typeof Symbol !== "undefined" ? Symbol.iterator || (Symbol.iterator = /*#__PURE__*/Symbol("Symbol.iterator")) : "@@iterator";
11065
11082
 
11066
11083
  // Asynchronously iterate through an object's values
11067
11084
  // Uses for...of if the runtime supports it, otherwise iterates until length on a copy
11068
11085
  function _forOf(target, body, check) {
11069
11086
  if (typeof target[_iteratorSymbol] === "function") {
11070
- var iterator = target[_iteratorSymbol](),
11071
- step,
11072
- pact,
11073
- reject;
11074
- function _cycle(result) {
11087
+ var _cycle = function _cycle(result) {
11075
11088
  try {
11076
11089
  while (!(step = iterator.next()).done && (!check || !check())) {
11077
11090
  result = body(step.value);
@@ -11092,13 +11105,17 @@ function _forOf(target, body, check) {
11092
11105
  } catch (e) {
11093
11106
  _settle(pact || (pact = new _Pact()), 2, e);
11094
11107
  }
11095
- }
11108
+ };
11109
+ var iterator = target[_iteratorSymbol](),
11110
+ step,
11111
+ pact,
11112
+ reject;
11096
11113
  _cycle();
11097
- if (iterator.return) {
11098
- var _fixup = function (value) {
11114
+ if (iterator["return"]) {
11115
+ var _fixup = function _fixup(value) {
11099
11116
  try {
11100
11117
  if (!step.done) {
11101
- iterator.return();
11118
+ iterator["return"]();
11102
11119
  }
11103
11120
  } catch (e) {}
11104
11121
  return value;
@@ -11125,7 +11142,7 @@ function _forOf(target, body, check) {
11125
11142
  return body(values[i]);
11126
11143
  }, check);
11127
11144
  }
11128
- const _asyncIteratorSymbol = /*#__PURE__*/typeof Symbol !== "undefined" ? Symbol.asyncIterator || (Symbol.asyncIterator = /*#__PURE__*/Symbol("Symbol.asyncIterator")) : "@@asyncIterator";
11145
+ var _asyncIteratorSymbol = /*#__PURE__*/typeof Symbol !== "undefined" ? Symbol.asyncIterator || (Symbol.asyncIterator = /*#__PURE__*/Symbol("Symbol.asyncIterator")) : "@@asyncIterator";
11129
11146
 
11130
11147
  // Asynchronously call a function and send errors to recovery continuation
11131
11148
  function _catch(body, recover) {
@@ -11753,7 +11770,7 @@ function useTableManager(props, meta, internalColumns) {
11753
11770
  rowDrag,
11754
11771
  rowDrop: rowDrop,
11755
11772
  rowExpansion: rowExpansion,
11756
- rowIdentityColumnId: props.rowIdentityColumnId,
11773
+ rowIdentityAccessor: props.rowIdentityAccessor,
11757
11774
  rowGoto,
11758
11775
  rowGroups: rowGroups,
11759
11776
  rowHeight,
@@ -12118,11 +12135,30 @@ function Row(props) {
12118
12135
  })));
12119
12136
  }
12120
12137
 
12121
- function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex) {
12138
+ // scroll padding end is designed to always show half of the next row
12139
+ function getScrollPaddingEndOffset(table, options) {
12140
+ var _options$virtualiserP;
12141
+ const tableMeta = table.options.meta;
12142
+ let offset = 2 + ((_options$virtualiserP = options === null || options === void 0 ? void 0 : options.virtualiserPaddingEndOffset) !== null && _options$virtualiserP !== void 0 ? _options$virtualiserP : 0);
12143
+ if (tableMeta.footer.isEnabled) {
12144
+ offset += 1;
12145
+ }
12146
+ if (table.getHeaderGroups().length > 1) {
12147
+ offset += table.getHeaderGroups().length - 1;
12148
+ }
12149
+ let height = ROW_HEIGHT_ESTIMATES.medium * offset;
12150
+ const bottomRows = table.getBottomRows();
12151
+ if (bottomRows.length) {
12152
+ height += ROW_HEIGHT_ESTIMATES[tableMeta.rowHeight.height] * 1.4 * bottomRows.length;
12153
+ }
12154
+ return height;
12155
+ }
12156
+ function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex, options) {
12122
12157
  var _table$getState$group, _virtualItems$padding, _virtualItems$padding2, _virtualItems$padding3, _ref, _virtualItems;
12123
12158
  const tableMeta = table.options.meta;
12124
- const rows = table.getRowModel().rows;
12159
+ const rows = table.getCenterRows();
12125
12160
  const isTableRowGrouped = !!((_table$getState$group = table.getState().grouping) !== null && _table$getState$group !== void 0 && _table$getState$group.length);
12161
+ const bottomRows = table.getBottomRows();
12126
12162
  // expanded rows
12127
12163
  const {
12128
12164
  createRowMeasurer,
@@ -12132,9 +12168,6 @@ function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex) {
12132
12168
  const rangeExtractor = useRowGroupVirtualisation(table);
12133
12169
  // account for thead and tfoot in the scroll area - both are always medium row height
12134
12170
  const scrollPaddingStart = ROW_HEIGHT_ESTIMATES.medium;
12135
- // column groups offset the bottom padding :shrug:, multiplying by 1.5 ensures the bottom padding remains
12136
- // consistent when there are groups and when there aren't. 1.5 is relatively arbitrary, but it gives alignment
12137
- const scrollPaddingEnd = ROW_HEIGHT_ESTIMATES.medium * (table.getHeaderGroups().length > 1 ? 1.5 : 1);
12138
12171
  const virtualiser = reactVirtual.useVirtualizer({
12139
12172
  count: rows.length,
12140
12173
  estimateSize,
@@ -12143,7 +12176,8 @@ function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex) {
12143
12176
  rangeExtractor,
12144
12177
  // correctly sets the scroll padding offset, e.g. when keyboard navigating rows in the list
12145
12178
  scrollPaddingStart,
12146
- scrollPaddingEnd: tableMeta.footer.isEnabled ? scrollPaddingEnd * 2 : scrollPaddingEnd
12179
+ scrollPaddingEnd: getScrollPaddingEndOffset(table, options),
12180
+ paddingEnd: ROW_HEIGHT_ESTIMATES.medium * bottomRows.length
12147
12181
  });
12148
12182
  const totalSize = virtualiser.getTotalSize();
12149
12183
  const virtualItems = virtualiser.getVirtualItems();
@@ -12300,12 +12334,14 @@ function Actions$1(props) {
12300
12334
  actionsLength,
12301
12335
  data,
12302
12336
  isActiveRow,
12303
- rowId
12337
+ rowId,
12338
+ table
12304
12339
  } = props;
12305
12340
  const {
12306
12341
  texts
12307
12342
  } = useLocalization();
12308
- const visibleActions = actions.map(action => action(data, rowId)).filter(action => !!action);
12343
+ // we don't want to document passing table, so it isn't on the type
12344
+ const visibleActions = actions.map(action => action(data, rowId, table)).filter(action => !!action);
12309
12345
  const actionsOnRow = visibleActions.length === actionsLength ? visibleActions : visibleActions.slice(0, actionsLength - 1);
12310
12346
  const actionsInMenu = visibleActions.slice(visibleActions.length === actionsLength ? actionsLength : actionsLength - 1);
12311
12347
  const className = cn('flex justify-end text-right bg-[inherit] shadow-[-6px_0px_6px_var(--table-row-actions-shadow)] print:hidden');
@@ -12361,7 +12397,8 @@ const Cell = /*#__PURE__*/React__default.memo(function MemoedCell(context) {
12361
12397
  actionsLength: actionsLength,
12362
12398
  data: row.original,
12363
12399
  isActiveRow: isActiveRow,
12364
- rowId: row.id
12400
+ rowId: row.id,
12401
+ table: table
12365
12402
  });
12366
12403
  }
12367
12404
  return null;
@@ -12611,13 +12648,13 @@ const INTERNAL_RENDERERS = {
12611
12648
  rowExpansion: renderer$2,
12612
12649
  rowSelection: renderer$3
12613
12650
  };
12614
- function useTable(props, externalRef, renderers, meta) {
12651
+ function useTable(props, externalRef, renderers, meta, options) {
12615
12652
  // create a ref and merge with the consumer's ref
12616
12653
  const ref = useMergedRef(externalRef);
12617
12654
  // configure the table
12618
12655
  const manager = useTableManager(props, meta, INTERNAL_RENDERERS);
12619
12656
  // configure the virtualised renderer
12620
- const renderer = useTableRenderer(renderers, manager.instance, ref, props.defaultRowActiveIndex);
12657
+ const renderer = useTableRenderer(renderers, manager.instance, ref, props.defaultRowActiveIndex, options);
12621
12658
  // configure dynamic styling
12622
12659
  const {
12623
12660
  style,
@@ -12718,7 +12755,10 @@ function GroupedCell(props) {
12718
12755
  index,
12719
12756
  isHighlighted
12720
12757
  } = props;
12721
- const tableMeta = cell.getContext().table.options.meta;
12758
+ const {
12759
+ table
12760
+ } = cell.getContext();
12761
+ const tableMeta = table.options.meta;
12722
12762
  const columnMeta = cell.column.columnDef.meta;
12723
12763
  const attributes = getCellAttributes(cell, index, isHighlighted);
12724
12764
  const {
@@ -12736,7 +12776,8 @@ function GroupedCell(props) {
12736
12776
  colSpan: colSpan,
12737
12777
  rowActions: tableMeta.rowGroups.rowActionsForGroup,
12738
12778
  rowId: cell.row.id,
12739
- subRows: subRows
12779
+ subRows: subRows,
12780
+ table: table
12740
12781
  }), content);
12741
12782
  }
12742
12783
  const MemoedGroupedCell = /*#__PURE__*/React__default.memo(function MemoedGroupedCell(props) {
@@ -12748,6 +12789,7 @@ const MemoedGroupedCell = /*#__PURE__*/React__default.memo(function MemoedGroupe
12748
12789
  rowActions,
12749
12790
  rowId,
12750
12791
  subRows,
12792
+ table,
12751
12793
  ...attributes
12752
12794
  } = props;
12753
12795
  return /*#__PURE__*/React__default.createElement("td", Object.assign({}, attributes, {
@@ -12762,7 +12804,8 @@ const MemoedGroupedCell = /*#__PURE__*/React__default.memo(function MemoedGroupe
12762
12804
  actionsLength: 4,
12763
12805
  data: subRows,
12764
12806
  isActiveRow: true,
12765
- rowId: rowId
12807
+ rowId: rowId,
12808
+ table: table
12766
12809
  })) : null);
12767
12810
  });
12768
12811
 
@@ -12902,7 +12945,7 @@ const DisplayRow = /*#__PURE__*/React__default.memo(function DisplayRow(props) {
12902
12945
  const expansionRef = React__default.useRef(null);
12903
12946
  const isExpanded = !!attributes['data-row-expanded'];
12904
12947
  useSetVirtualisedRowHeight(measureRow, ref.current, expansionRef.current, isExpanded);
12905
- const className = cn('group/row', {
12948
+ const className = cn('group/row', otherAttributes.className, {
12906
12949
  'hover:cursor-grab': tableMeta.rowDrag.isEnabled && typeof attributes.onClick !== 'function',
12907
12950
  'hover:cursor-pointer': typeof attributes.onClick === 'function'
12908
12951
  });
@@ -13696,7 +13739,7 @@ function Summary(props) {
13696
13739
 
13697
13740
  function Foot(props) {
13698
13741
  const nonGroupedHeaders = props.table.getFooterGroups()[0].headers.filter(header => !header.column.getIsGrouped());
13699
- return /*#__PURE__*/React__default.createElement("tfoot", null, /*#__PURE__*/React__default.createElement("tr", null, nonGroupedHeaders.map((header, index) => (/*#__PURE__*/React__default.createElement(Footer$3, {
13742
+ return /*#__PURE__*/React__default.createElement("tfoot", null, props.children, /*#__PURE__*/React__default.createElement("tr", null, nonGroupedHeaders.map((header, index) => (/*#__PURE__*/React__default.createElement(Footer$3, {
13700
13743
  key: header.id,
13701
13744
  header: header,
13702
13745
  index: index
@@ -14386,6 +14429,7 @@ const getOptionsFromCollection = (collection, selector) => collection.querySelec
14386
14429
  const Root = /*#__PURE__*/React__default.forwardRef(function CollectionRoot(props, ref) {
14387
14430
  const {
14388
14431
  querySelector,
14432
+ resetOnChange,
14389
14433
  tabIndex = 0,
14390
14434
  ...otherProps
14391
14435
  } = props;
@@ -14416,6 +14460,21 @@ const Root = /*#__PURE__*/React__default.forwardRef(function CollectionRoot(prop
14416
14460
  internalRef.current.setActiveIndexByElement = setActiveIndexByElement;
14417
14461
  }
14418
14462
  }, [internalRef.current]);
14463
+ React__default.useEffect(() => {
14464
+ if (internalRef.current) {
14465
+ const selected = internalRef.current.querySelectorAll(`[aria-current="true"]`);
14466
+ const options = getOptionsFromCollection(internalRef.current, querySelector);
14467
+ if (options.length && selected.length === 1) {
14468
+ const firstSelected = internalRef.current.querySelector(`[aria-selected]`);
14469
+ if (firstSelected) {
14470
+ const selectedIndex = Array.from(options).indexOf(firstSelected);
14471
+ if (selectedIndex > -1) {
14472
+ setActiveOption(selectedIndex, internalRef.current, firstSelected);
14473
+ }
14474
+ }
14475
+ }
14476
+ }
14477
+ }, [resetOnChange]);
14419
14478
  React__default.useEffect(() => {
14420
14479
  if (internalRef.current) {
14421
14480
  const options = getOptionsFromCollection(internalRef.current, querySelector);
@@ -14427,8 +14486,8 @@ const Root = /*#__PURE__*/React__default.forwardRef(function CollectionRoot(prop
14427
14486
  }
14428
14487
  // if one item is selected, make sure it's current
14429
14488
  if (selected.length === 1) {
14430
- const firstSelected = internalRef.current.querySelector(`[aria-selected]`);
14431
- if (firstSelected) {
14489
+ if (options) {
14490
+ const firstSelected = selected.item(0);
14432
14491
  const selectedIndex = Array.from(options).indexOf(firstSelected);
14433
14492
  if (selectedIndex > -1) {
14434
14493
  setActiveOption(selectedIndex, internalRef.current, firstSelected);
@@ -14571,6 +14630,7 @@ const Root$1 = /*#__PURE__*/React__default.forwardRef(function Listbox2(props, r
14571
14630
  id: id,
14572
14631
  querySelector: customSelector ? `${DEFAULT_SELECTOR}, ${customSelector}` : DEFAULT_SELECTOR,
14573
14632
  ref: ref,
14633
+ resetOnChange: value,
14574
14634
  role: "listbox"
14575
14635
  }), children)));
14576
14636
  });
@@ -16755,6 +16815,7 @@ function TableGrid(props) {
16755
16815
  var _table$state$grouping;
16756
16816
  const {
16757
16817
  enableHorizontalArrowKeyNavigation,
16818
+ rowsForFooter,
16758
16819
  table,
16759
16820
  ...attributes
16760
16821
  } = props;
@@ -16762,8 +16823,6 @@ function TableGrid(props) {
16762
16823
  table.meta.rowActive.handleFocus(event, table.meta.length, table.renderer.scrollToIndex);
16763
16824
  } : undefined;
16764
16825
  const filterReason = getFilterReason(table);
16765
- const searchNotApplied = !table.state.globalFilter || table.state.globalFilter === '';
16766
- const filtersNotApplied = !table.state.columnFilters || table.state.columnFilters.length === 0;
16767
16826
  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, {
16768
16827
  id: table.id,
16769
16828
  "data-table-font-size": table.meta.fontSize.size,
@@ -16796,9 +16855,9 @@ function TableGrid(props) {
16796
16855
  ...table.renderer.style,
16797
16856
  height: table.renderer.style.height + ROW_HEIGHT_ESTIMATES[table.meta.rowHeight.height]
16798
16857
  } : table.renderer.style
16799
- }, table.renderer.rows, searchNotApplied && filtersNotApplied && props.children), table.meta.footer.isEnabled ? /*#__PURE__*/React__default.createElement(Foot, {
16858
+ }, table.renderer.rows, props.children), table.meta.footer.isEnabled ? /*#__PURE__*/React__default.createElement(Foot, {
16800
16859
  table: table.instance
16801
- }) : null)))));
16860
+ }, rowsForFooter) : null)))));
16802
16861
  }
16803
16862
 
16804
16863
  function Column$1(_) {
@@ -18301,33 +18360,16 @@ const useTableRowCreation = (data, tableRef) => {
18301
18360
 
18302
18361
  function useTableEditingListener(table, tableRef) {
18303
18362
  const tableMeta = table.options.meta;
18304
- const completedRowsCount = tableMeta.editing.getCompletedRowsCount();
18305
18363
  const localization = useLocalization();
18306
- const saveChanges = () => {
18307
- requestAnimationFrame(() => {
18308
- tableMeta.editing.saveChanges();
18309
- });
18310
- };
18311
18364
  // save when the row changes
18365
+ // store the last row active index, otherwise everytime tableMeta.editing.saveChanges changes the hook runs again
18366
+ const lastRowActiveIndexRef = React__default.useRef(tableMeta.rowActive.rowActiveIndex);
18312
18367
  useLazyEffect(() => {
18313
- if (tableMeta.editing.isEditing) {
18314
- saveChanges();
18315
- }
18316
- }, [tableMeta.rowActive.rowActiveIndex]);
18317
- useLazyEffect(() => {
18318
- if (tableMeta.editing.isEditing) {
18319
- if (tableMeta.rowActive.rowActiveIndex === undefined) {
18320
- tableMeta.rowActive.setRowActiveIndex(0);
18321
- }
18322
- } else {
18323
- // save
18324
- saveChanges();
18325
- // reset detailed mode
18326
- tableMeta.editing.toggleDetailedMode(false);
18327
- // reset the last index back to the first focusable element, when editing gets turned off
18328
- tableMeta.editing.setLastFocusedCellIndex(undefined);
18368
+ if (tableMeta.editing.isEditing && tableMeta.rowActive.rowActiveIndex !== lastRowActiveIndexRef.current) {
18369
+ lastRowActiveIndexRef.current = tableMeta.rowActive.rowActiveIndex;
18370
+ tableMeta.editing.saveChanges(table);
18329
18371
  }
18330
- }, [tableMeta.editing.isEditing]);
18372
+ }, [tableMeta.rowActive.rowActiveIndex, tableMeta.editing.saveChanges]);
18331
18373
  // show a warning if the user navigates away without triggering save, such as using the browser back/forward button
18332
18374
  const hasChanges = tableMeta.editing.hasChanges();
18333
18375
  React__default.useEffect(() => {
@@ -18343,25 +18385,46 @@ function useTableEditingListener(table, tableRef) {
18343
18385
  window.removeEventListener('beforeunload', showUnsavedChangesWarning);
18344
18386
  };
18345
18387
  }, [tableMeta.editing.isEditing, hasChanges]);
18346
- React__default.useEffect(() => {
18347
- if (completedRowsCount > 0) {
18388
+ const hasSavedChanges = tableMeta.editing.hasSaved();
18389
+ useLazyEffect(() => {
18390
+ if (hasSavedChanges) {
18348
18391
  resetHighlightedColumnIndexes(table.getState().globalFilter, table, localization);
18349
18392
  }
18350
- }, [completedRowsCount]);
18393
+ }, [hasSavedChanges]);
18351
18394
  React__default.useEffect(() => {
18352
18395
  const onClickOutside = event => {
18353
18396
  if (tableMeta.editing.isEditing) {
18354
- var _event$target$getAttr, _event$target;
18355
- 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 : '';
18356
- const insideTable = isElementInsideOrTriggeredFromContainer(event.target, tableRef.current) || element === 'backdrop';
18357
- if (!insideTable) {
18358
- saveChanges();
18397
+ const element = event.target;
18398
+ const insideTable = element.getAttribute('data-taco') === 'backdrop' || element.getAttribute('data-table') === 'editing-toggle' || isElementInsideOrTriggeredFromContainer(element, tableRef.current);
18399
+ // users can click the white space below rows which could be inside the table, but a valid scenario to save
18400
+ if (!insideTable || element.tagName === 'TABLE' || element.tagName === 'TBODY') {
18401
+ tableMeta.editing.saveChanges(table);
18359
18402
  }
18360
18403
  }
18361
18404
  };
18362
18405
  document.addEventListener('click', onClickOutside);
18363
18406
  return () => document.removeEventListener('click', onClickOutside);
18364
- }, [saveChanges, tableMeta.editing.isEditing]);
18407
+ }, [tableMeta.editing.isEditing, tableMeta.editing.saveChanges]);
18408
+ const rows = table.getRowModel().rows;
18409
+ // make sure pending changes are removed for rows that no longer exist
18410
+ useLazyEffect(() => {
18411
+ const pendingChanges = tableMeta.editing.getErrorsShownInAlert();
18412
+ pendingChanges.forEach(pendingChange => {
18413
+ try {
18414
+ table.getRow(pendingChange.rowId);
18415
+ } catch {
18416
+ tableMeta.editing.discardChanges(pendingChange.rowId, table);
18417
+ }
18418
+ });
18419
+ }, [rows.length]);
18420
+ useGlobalKeyDown(tableMeta.editing.isEditing ? {
18421
+ key: 's',
18422
+ meta: true,
18423
+ shift: false
18424
+ } : undefined, event => {
18425
+ event.preventDefault();
18426
+ tableMeta.editing.saveChanges(table);
18427
+ });
18365
18428
  }
18366
18429
 
18367
18430
  function willRowMove(cell, change, rowIndex, localization) {
@@ -18431,6 +18494,8 @@ function willRowMoveAfterSorting(cell, change, rowIndex) {
18431
18494
  const aUndefined = aValue === undefined;
18432
18495
  const bUndefined = bValue === undefined;
18433
18496
  if (aUndefined || bUndefined) {
18497
+ if (sortUndefined === 'first') return aUndefined ? -1 : 1;
18498
+ if (sortUndefined === 'last') return aUndefined ? 1 : -1;
18434
18499
  return aUndefined && bUndefined ? 0 : aUndefined ? sortUndefined : -sortUndefined;
18435
18500
  }
18436
18501
  }
@@ -18441,444 +18506,544 @@ function willRowMoveAfterSorting(cell, change, rowIndex) {
18441
18506
  }
18442
18507
  return ((_resortedRows$index = resortedRows[index]) === null || _resortedRows$index === void 0 ? void 0 : _resortedRows$index.id) !== cell.row.id;
18443
18508
  }
18444
- function animateCreateRow(id) {
18445
- const templateRow = document.querySelector(`[data-row-id="${id}"]`);
18446
- if (templateRow) {
18447
- const firstCell = templateRow.querySelector(':first-child');
18448
- const checkbox = firstCell === null || firstCell === void 0 ? void 0 : firstCell.querySelector('[data-taco="checkbox"]');
18449
- firstCell === null || firstCell === void 0 ? void 0 : firstCell.focus();
18450
- if (checkbox) {
18451
- setDataFocusAttribute(checkbox);
18452
- }
18453
- templateRow.scrollIntoView();
18454
- const keyframes = [{
18455
- background: '#b2c7ef'
18456
- }, {
18457
- background: '#ebebeb'
18458
- }];
18459
- for (const child of templateRow.children) {
18460
- child.animate(keyframes, {
18461
- duration: 1000,
18462
- easing: 'ease-out'
18463
- });
18464
- }
18465
- }
18509
+ const TEMPORARY_ROW_ID_PREFIX = 'temp-';
18510
+ function isTemporaryRow(rowId) {
18511
+ return rowId === null || rowId === void 0 ? void 0 : rowId.startsWith(TEMPORARY_ROW_ID_PREFIX);
18466
18512
  }
18467
18513
 
18468
- function useTableEditing(isEnabled = false, handleSave, handleChange, validator) {
18469
- // used to switch the table into editing mode
18470
- const [isEditing, toggleEditing] = React__default.useState(false);
18471
- // used to switch the editing between "detailed" mode
18472
- const [isDetailedMode, toggleDetailedMode] = React__default.useState(false);
18473
- // store the last focused cell, so that up/down arrow key navigation remains in the same column
18474
- const [lastFocusedCellIndex, setLastFocusedCellIndex] = useLastFocusedCellIndex();
18475
- // store pending changes for each row
18476
- // changes are saved as soon as the active row changes, so in most cases this will only contain the active row's changes
18477
- // but not always - if validation or server requests fail when saving, those rows remain until the failure is resolved
18478
- const pendingChangesFns = usePendingChanges(isEnabled, handleSave, handleChange, validator);
18479
- useGlobalKeyDown(isEnabled && isEditing ? {
18480
- key: 's',
18481
- meta: true,
18482
- shift: false
18483
- } : undefined, event => {
18484
- event.preventDefault();
18485
- pendingChangesFns.saveChanges();
18486
- });
18487
- return {
18488
- isEnabled,
18489
- isEditing,
18490
- isDetailedMode,
18491
- toggleDetailedMode: isEnabled ? toggleDetailedMode : () => undefined,
18492
- toggleEditing: isEnabled ? toggleEditing : () => undefined,
18493
- lastFocusedCellIndex,
18494
- setLastFocusedCellIndex,
18495
- ...pendingChangesFns
18496
- };
18514
+ const DELAY_BEFORE_REMOVING_SAVE_STATUS = 3000;
18515
+ function reducer$2(state, action) {
18516
+ const {
18517
+ type,
18518
+ rowId,
18519
+ payload
18520
+ } = action;
18521
+ switch (type) {
18522
+ case 'setCellValue':
18523
+ {
18524
+ const {
18525
+ columnId,
18526
+ row,
18527
+ value
18528
+ } = payload;
18529
+ return {
18530
+ ...state,
18531
+ changes: {
18532
+ ...state.changes,
18533
+ rows: setWith(state.changes.rows, `${rowId}.${columnId}`, value, Object),
18534
+ originals: setWith(state.changes.originals, rowId, row, Object)
18535
+ }
18536
+ };
18537
+ }
18538
+ case 'removeCellValue':
18539
+ {
18540
+ const {
18541
+ columnId,
18542
+ rowIdentityAccessor
18543
+ } = payload;
18544
+ const changes = omit(state.changes.rows, `${rowId}.${columnId}`);
18545
+ // if there are no changes left, remove the row
18546
+ if (!Object.keys(changes[rowId]).length) {
18547
+ return reducer$2(state, {
18548
+ type: 'removeRow',
18549
+ rowId,
18550
+ payload: {
18551
+ rowIdentityAccessor
18552
+ }
18553
+ });
18554
+ }
18555
+ return {
18556
+ ...state,
18557
+ changes: {
18558
+ ...state.changes,
18559
+ rows: omit(state.changes.rows, `${rowId}.${columnId}`),
18560
+ errors: omit(state.changes.errors, `${rowId}.cells.${columnId}`),
18561
+ moveReasons: omit(state.changes.moveReasons, `${rowId}.${columnId}`)
18562
+ }
18563
+ };
18564
+ }
18565
+ case 'updateRow':
18566
+ {
18567
+ const {
18568
+ cellErrors,
18569
+ moveReasons,
18570
+ original,
18571
+ value
18572
+ } = payload;
18573
+ return {
18574
+ ...state,
18575
+ changes: {
18576
+ ...state.changes,
18577
+ rows: setWith(state.changes.rows, rowId, value, Object),
18578
+ errors: setWith(state.changes.errors, `${rowId}.cells`, cellErrors !== null && cellErrors !== void 0 ? cellErrors : state.changes.errors.cells[rowId], Object),
18579
+ originals: setWith(state.changes.originals, rowId, original !== null && original !== void 0 ? original : state.changes.originals[rowId], Object),
18580
+ moveReasons: setWith(state.changes.moveReasons, rowId, moveReasons !== null && moveReasons !== void 0 ? moveReasons : state.changes.moveReasons[rowId], Object),
18581
+ // status can be undefined, so don't use ??
18582
+ status: setWith(state.changes.status, rowId, undefined, Object)
18583
+ }
18584
+ };
18585
+ }
18586
+ case 'removeRow':
18587
+ {
18588
+ const {
18589
+ rowIdentityAccessor
18590
+ } = payload;
18591
+ return {
18592
+ ...state,
18593
+ changes: {
18594
+ ...state.changes,
18595
+ rows: omit(state.changes.rows, rowId),
18596
+ errors: omit(state.changes.errors, rowId),
18597
+ moveReasons: omit(state.changes.moveReasons, rowId),
18598
+ originals: omit(state.changes.originals, rowId),
18599
+ status: omit(state.changes.status, rowId)
18600
+ },
18601
+ temporaryRows: state.temporaryRows.filter(row => row[rowIdentityAccessor] !== rowId)
18602
+ };
18603
+ }
18604
+ case 'setRowStatus':
18605
+ {
18606
+ const {
18607
+ status
18608
+ } = payload;
18609
+ return {
18610
+ ...state,
18611
+ changes: {
18612
+ ...state.changes,
18613
+ status: status ? setWith(state.changes.status, rowId, status, Object) : omit(state.changes.status, rowId)
18614
+ }
18615
+ };
18616
+ }
18617
+ case 'setRowErrors':
18618
+ {
18619
+ const {
18620
+ ...errors
18621
+ } = payload;
18622
+ return {
18623
+ ...state,
18624
+ changes: {
18625
+ ...state.changes,
18626
+ errors: setWith(state.changes.errors, rowId, errors, Object)
18627
+ }
18628
+ };
18629
+ }
18630
+ case 'createRow':
18631
+ {
18632
+ const {
18633
+ value
18634
+ } = payload;
18635
+ return {
18636
+ ...state,
18637
+ temporaryRows: state.temporaryRows.concat(value),
18638
+ changes: {
18639
+ ...state.changes,
18640
+ rows: setWith(state.changes.rows, rowId, value, Object),
18641
+ originals: setWith(state.changes.originals, rowId, value, Object)
18642
+ }
18643
+ };
18644
+ }
18645
+ default:
18646
+ return state;
18647
+ }
18497
18648
  }
18498
- function usePendingChanges(isEnabled, handleSave, handleChange, validator) {
18499
- const saveChanges = function (rowId = undefined) {
18649
+ function usePendingChangesState(handleSave, handleChange, rowIdentityAccessor, validator) {
18650
+ const saveChanges = function (table, rowId = undefined) {
18500
18651
  try {
18501
18652
  let _exit = false;
18502
18653
  if (!handleSave) {
18503
18654
  console.warn('Tried to save, but Table has no onEditingSave handler');
18504
- return Promise.resolve();
18655
+ return Promise.resolve(false);
18505
18656
  }
18506
- // we save back to pendingChanges, so make a copy of it's state when save was triggered
18507
- const changesToSave = rowId ? {
18508
- [rowId]: pendingChanges[rowId]
18509
- } : {
18510
- ...pendingChanges
18511
- };
18512
- const changes = Object.keys(changesToSave);
18513
- return Promise.resolve(function () {
18514
- if (changes.length) {
18515
- return _forOf(changes, function (rowId) {
18516
- const pendingChange = changesToSave[rowId];
18517
- const changeSet = getChangesetFromChanges(pendingChange);
18518
- return _catch(function () {
18519
- function _temp3(_result) {
18520
- return _exit ? _result : Promise.resolve(handleSave(changeSet)).then(function () {
18521
- // cleanup changes, we don't need them after saving
18522
- resetChanges(rowId);
18523
- setRowSaveStatus(rowId, 'complete');
18524
- });
18525
- }
18526
- if (getRowSaveStatus(rowId) === 'pending') {
18527
- _exit = true;
18528
- return;
18529
- }
18530
- // set saving = true
18531
- setRowSaveStatus(rowId, 'pending');
18532
- // re-run validation, maybe a cell is already invalid but has never been blurred
18533
- const _temp2 = function () {
18534
- if (validator) {
18535
- return Promise.resolve(validator(changeSet)).then(function (errors) {
18536
- if (errors && Object.keys(errors).length) {
18537
- throw errors;
18538
- }
18539
- });
18540
- }
18541
- }();
18542
- return _temp2 && _temp2.then ? _temp2.then(_temp3) : _temp3(_temp2); // send new data to the server
18543
- }, function (error) {
18544
- // the onEditingSave handler should throw errors when something fails, e.g. validation, network errors etc
18545
- // this code handles those errors and maps them either to row errors or cell specific errors
18546
- let rowError;
18547
- let cellErrors;
18548
- if (typeof error === 'string') {
18549
- rowError = error;
18550
- } else if (error instanceof Error) {
18551
- var _error$response;
18552
- rowError = error.message;
18553
- // most of our apis return error objects within this shape
18554
- if (typeof ((_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.data) === 'object') {
18555
- var _error$response2;
18556
- cellErrors = (_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.data;
18657
+ // sometimes we only want to save one row
18658
+ const changes = rowId ? {
18659
+ [rowId]: state.changes.rows[rowId]
18660
+ } : state.changes.rows;
18661
+ let completed = true;
18662
+ const _temp9 = _forOf(Object.keys(changes), function (rowId) {
18663
+ const status = getRowStatus(rowId);
18664
+ return _catch(function () {
18665
+ function _temp8(_result) {
18666
+ return _exit ? _result : Promise.resolve(handleSave(changeSet)).then(function () {
18667
+ // cleanup changes, we don't need them after saving
18668
+ discardChanges(rowId, table);
18669
+ // show the saved status, then remove it after a delay
18670
+ setRowStatus(rowId, 'saved');
18671
+ setTimeout(() => {
18672
+ setRowStatus(rowId, undefined);
18673
+ }, DELAY_BEFORE_REMOVING_SAVE_STATUS);
18674
+ });
18675
+ }
18676
+ // don't try to save if - already saving, or there are known errors
18677
+ if (status === 'saving' || status === 'errored') {
18678
+ return;
18679
+ }
18680
+ setRowStatus(rowId, 'saving');
18681
+ const changeSet = {
18682
+ ...state.changes.originals[rowId],
18683
+ ...changes[rowId]
18684
+ };
18685
+ // if we had to create a temporary id, delete it first - it's our data, not theirs
18686
+ if (isTemporaryRow(changeSet[rowIdentityAccessor])) {
18687
+ delete changeSet[rowIdentityAccessor];
18688
+ }
18689
+ // re-run validation, maybe a cell is already invalid but has never been blurred
18690
+ const _temp7 = function () {
18691
+ if (validator) {
18692
+ return Promise.resolve(validator(changeSet)).then(function (errors) {
18693
+ if (errors && Object.keys(errors).length) {
18694
+ throw errors;
18557
18695
  }
18558
- } else if (typeof error === 'object') {
18559
- cellErrors = error;
18560
- }
18561
- if (rowError || cellErrors) {
18562
- setPendingChanges(currentChanges => {
18563
- const nextChanges = {
18564
- ...currentChanges
18565
- };
18566
- nextChanges[rowId]._meta.errors = {
18567
- row: rowError,
18568
- cells: cellErrors,
18569
- shouldShowErrorAlert: true
18570
- };
18571
- return nextChanges;
18572
- });
18696
+ });
18697
+ }
18698
+ }();
18699
+ return _temp7 && _temp7.then ? _temp7.then(_temp8) : _temp8(_temp7); // send new data to the server
18700
+ }, function (error) {
18701
+ var _error$response;
18702
+ 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) {
18703
+ console.error(error);
18704
+ }
18705
+ // the onEditingSave handler should throw errors when something fails, e.g. validation, network errors etc
18706
+ // this code handles those errors and maps them either to row errors or cell specific errors
18707
+ let rowError;
18708
+ let cellErrors;
18709
+ if (typeof error === 'string') {
18710
+ rowError = error;
18711
+ } else if (error instanceof Error) {
18712
+ var _error$response2;
18713
+ rowError = error.message;
18714
+ // most of our apis return error objects within this shape
18715
+ if (typeof ((_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.data) === 'object') {
18716
+ var _error$response3;
18717
+ cellErrors = (_error$response3 = error.response) === null || _error$response3 === void 0 ? void 0 : _error$response3.data;
18718
+ }
18719
+ } else if (typeof error === 'object') {
18720
+ cellErrors = error;
18721
+ }
18722
+ if (rowError || cellErrors) {
18723
+ dispatch({
18724
+ type: 'setRowErrors',
18725
+ rowId,
18726
+ payload: {
18727
+ row: rowError,
18728
+ cells: cellErrors,
18729
+ shouldShowErrorAlert: true
18573
18730
  }
18574
- setRowSaveStatus(rowId, undefined);
18575
18731
  });
18576
- }, function () {
18577
- return _exit;
18578
- });
18579
- }
18580
- }());
18732
+ }
18733
+ setRowStatus(rowId, 'errored');
18734
+ completed = false;
18735
+ });
18736
+ }, function () {
18737
+ return _exit;
18738
+ });
18739
+ return Promise.resolve(_temp9 && _temp9.then ? _temp9.then(function (_result3) {
18740
+ return _exit ? _result3 : completed;
18741
+ }) : _exit ? _temp9 : completed);
18581
18742
  } catch (e) {
18582
18743
  return Promise.reject(e);
18583
18744
  }
18584
18745
  };
18585
- const validateCell = function (cell) {
18746
+ const onCellChanged = function (cell, rowIndex) {
18586
18747
  try {
18587
- if (!validator || !isEnabled) {
18588
- return Promise.resolve();
18589
- }
18590
- const changeSet = getChangesetFromChanges(pendingChanges[cell.row.id]);
18591
- // only validate if the cell being blurred actually has any changes
18592
- const _temp = function () {
18593
- if (cell.column.id in changeSet) {
18594
- return Promise.resolve(validator(changeSet)).then(function (errors) {
18595
- setPendingChanges(currentChanges => {
18596
- const nextChanges = {
18597
- ...currentChanges
18598
- };
18599
- nextChanges[cell.row.id]._meta = {
18600
- ...nextChanges[cell.row.id]._meta,
18601
- errors: {
18602
- ...nextChanges[cell.row.id]._meta.errors,
18603
- cells: errors,
18604
- shouldShowErrorAlert: !Object.keys(errors).length ? false : nextChanges[cell.row.id]._meta.errors.shouldShowErrorAlert
18748
+ function _temp6() {
18749
+ var _state$changes$errors8;
18750
+ function _temp4() {
18751
+ // only set errors and move reasons for the cells we're currently acting on
18752
+ // why? because the UX is not good if we set them for cells the user hasn't touched yet
18753
+ const cellsToActOn = [cell.column.id, ...Object.keys(updatesForOtherCells)];
18754
+ const allCells = cell.row._getAllCellsByColumnId();
18755
+ cellsToActOn.forEach(accessor => {
18756
+ if (validationErrors[accessor]) {
18757
+ nextCellErrors[accessor] = validationErrors[accessor];
18758
+ // don't show move indicator for cells with errors, they aren't valid and can't be saved
18759
+ delete nextMoveReasons[accessor];
18760
+ } else {
18761
+ var _allCells$accessor;
18762
+ // there isn't any error in this run, remove any error set in state
18763
+ delete nextCellErrors[accessor];
18764
+ if ((_allCells$accessor = allCells[accessor]) !== null && _allCells$accessor !== void 0 && _allCells$accessor.column.getIsSorted()) {
18765
+ // run row move determination
18766
+ const reason = willRowMove(cell, nextChanges[accessor], rowIndex, localization);
18767
+ // if the row will move based on this change save why, otherwise delete any existing state
18768
+ if (reason) {
18769
+ nextMoveReasons[accessor] = reason;
18770
+ } else {
18771
+ delete nextMoveReasons[accessor];
18605
18772
  }
18606
- };
18607
- return nextChanges;
18773
+ }
18774
+ }
18775
+ });
18776
+ dispatch({
18777
+ type: 'updateRow',
18778
+ rowId: cell.row.id,
18779
+ payload: {
18780
+ cellErrors: nextCellErrors,
18781
+ moveReasons: nextMoveReasons,
18782
+ value: nextChanges
18783
+ }
18784
+ });
18785
+ }
18786
+ // create a projection of the next state, so we can act against it
18787
+ const nextChanges = {
18788
+ ...state.changes.rows[cell.row.id],
18789
+ ...updatesForOtherCells
18790
+ };
18791
+ const nextMoveReasons = {
18792
+ ...state.changes.moveReasons[cell.row.id]
18793
+ };
18794
+ const nextCellErrors = {
18795
+ ...((_state$changes$errors8 = state.changes.errors[cell.row.id]) === null || _state$changes$errors8 === void 0 ? void 0 : _state$changes$errors8.cells)
18796
+ };
18797
+ // run validation
18798
+ let validationErrors = {};
18799
+ const _temp3 = function () {
18800
+ if (validator) {
18801
+ const nextRowValue = {
18802
+ ...state.changes.originals[cell.row.id],
18803
+ ...changes,
18804
+ ...updatesForOtherCells
18805
+ };
18806
+ return Promise.resolve(validator(nextRowValue)).then(function (_validator2) {
18807
+ validationErrors = _validator2 !== null && _validator2 !== void 0 ? _validator2 : {};
18608
18808
  });
18809
+ }
18810
+ }();
18811
+ return _temp3 && _temp3.then ? _temp3.then(_temp4) : _temp4(_temp3);
18812
+ }
18813
+ const changes = state.changes.rows[cell.row.id];
18814
+ if (!changes) {
18815
+ return Promise.resolve();
18816
+ }
18817
+ let updatesForOtherCells = {};
18818
+ // run the updater handler if there is one, to see if there are any other cells to update
18819
+ const _temp5 = function () {
18820
+ if (typeof handleChange === 'function') {
18821
+ const previousRowValue = {
18822
+ ...state.changes.originals[cell.row.id]
18823
+ };
18824
+ const nextRowValue = {
18825
+ ...state.changes.originals[cell.row.id],
18826
+ ...changes
18827
+ };
18828
+ return Promise.resolve(handleChange(cell.column.id, changes[cell.column.id], nextRowValue, previousRowValue)).then(function (_handleChange) {
18829
+ updatesForOtherCells = _handleChange !== null && _handleChange !== void 0 ? _handleChange : {};
18609
18830
  });
18610
18831
  }
18611
18832
  }();
18612
- return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
18833
+ return Promise.resolve(_temp5 && _temp5.then ? _temp5.then(_temp6) : _temp6(_temp5));
18613
18834
  } catch (e) {
18614
18835
  return Promise.reject(e);
18615
18836
  }
18616
- };
18617
- const setCellValue = function (cell, change, rowIndex) {
18837
+ }; // general
18838
+ const createRow = function (data) {
18618
18839
  try {
18619
- const changes = {
18620
- [cell.column.id]: change
18840
+ const newRowId = `${TEMPORARY_ROW_ID_PREFIX}${uuid.v4()}`;
18841
+ const value = {
18842
+ ...data,
18843
+ [rowIdentityAccessor]: newRowId
18621
18844
  };
18622
- setPendingChanges(currentChanges => {
18623
- const nextChanges = createPendingChangesSetter(currentChanges, cell.row, rowIndex, changes, localization);
18624
- pendingChangesUpdater.syncCellChanges(nextChanges);
18625
- return nextChanges;
18845
+ dispatch({
18846
+ type: 'createRow',
18847
+ rowId: newRowId,
18848
+ payload: {
18849
+ value
18850
+ }
18626
18851
  });
18627
- pendingChangesUpdater.runCellUpdates(changes, cell, rowIndex);
18628
- return Promise.resolve();
18852
+ return Promise.resolve(newRowId);
18629
18853
  } catch (e) {
18630
18854
  return Promise.reject(e);
18631
18855
  }
18632
- };
18633
- const addCreatedRowChangeset = function (row) {
18856
+ }; // cells
18857
+ // rows
18858
+ const setRowValue = function (rowId, original, value) {
18634
18859
  try {
18635
- const cells = row.getAllCells();
18636
- setPendingChanges(currentChanges => {
18637
- return cells.reduce((changes, cell) => {
18638
- if (cell.getValue()) {
18639
- var _currentChanges$cell$, _currentChanges$cell$2, _currentChanges$cell$3;
18640
- return {
18641
- ...changes,
18642
- [cell.row.id]: {
18643
- ...changes[cell.row.id],
18644
- [cell.column.id]: cell.getValue(),
18645
- _meta: {
18646
- ...((_currentChanges$cell$ = currentChanges[cell.row.id]) === null || _currentChanges$cell$ === void 0 ? void 0 : _currentChanges$cell$._meta),
18647
- original: cell.row.original,
18648
- moveReason: {
18649
- ...((_currentChanges$cell$2 = currentChanges[cell.row.id]) === null || _currentChanges$cell$2 === void 0 ? void 0 : _currentChanges$cell$2._meta.moveReason)
18650
- },
18651
- errors: {
18652
- ...((_currentChanges$cell$3 = currentChanges[cell.row.id]) === null || _currentChanges$cell$3 === void 0 ? void 0 : _currentChanges$cell$3._meta.errors)
18653
- }
18654
- }
18655
- }
18656
- };
18657
- } else {
18658
- return changes;
18860
+ function _temp2() {
18861
+ dispatch({
18862
+ type: 'updateRow',
18863
+ rowId,
18864
+ payload: {
18865
+ cellErrors,
18866
+ original,
18867
+ value
18659
18868
  }
18660
- }, currentChanges);
18661
- });
18662
- return Promise.resolve();
18869
+ });
18870
+ }
18871
+ let cellErrors;
18872
+ const _temp = function () {
18873
+ if (validator) {
18874
+ const row = {
18875
+ ...original,
18876
+ ...value
18877
+ };
18878
+ return Promise.resolve(validator(row)).then(function (_validator) {
18879
+ cellErrors = _validator !== null && _validator !== void 0 ? _validator : {};
18880
+ });
18881
+ }
18882
+ }();
18883
+ return Promise.resolve(_temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp));
18663
18884
  } catch (e) {
18664
18885
  return Promise.reject(e);
18665
18886
  }
18666
18887
  };
18667
18888
  const localization = useLocalization();
18668
- const [pendingChanges, setPendingChanges] = React__default.useState({});
18669
- // we maintain save status as separate state because 'complete' needs to briefly show after pendingChanges are deleted
18670
- const [saveStates, setSaveState] = React__default.useState({});
18671
- function getCellValue(cell) {
18672
- var _pendingChanges$cell$;
18673
- return (_pendingChanges$cell$ = pendingChanges[cell.row.id]) === null || _pendingChanges$cell$ === void 0 ? void 0 : _pendingChanges$cell$[cell.column.id];
18889
+ const [state, dispatch] = React__default.useReducer(reducer$2, {
18890
+ changes: {
18891
+ rows: {},
18892
+ errors: {},
18893
+ moveReasons: {},
18894
+ originals: {},
18895
+ status: {}
18896
+ },
18897
+ temporaryRows: []
18898
+ });
18899
+ function getRowValue(rowId) {
18900
+ var _state$changes$rows$r, _state$changes$rows;
18901
+ 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;
18674
18902
  }
18675
- function getCellError(cell) {
18676
- var _pendingChanges$cell$2, _pendingChanges$cell$3, _pendingChanges$cell$4;
18677
- 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];
18903
+ function getRowMoveReason(rowId) {
18904
+ var _Object$values$, _state$changes$moveRe, _state$changes$moveRe2;
18905
+ 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;
18678
18906
  }
18679
- const pendingChangesUpdater = usePendingChangesUpdater(handleChange, setPendingChanges);
18680
18907
  function hasRowErrors(rowId) {
18681
- var _pendingChanges$rowId, _pendingChanges$rowId2, _pendingChanges$rowId3, _pendingChanges$rowId4, _pendingChanges$rowId5;
18682
- if (!isEnabled) {
18683
- return false;
18684
- }
18685
- 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;
18908
+ var _state$changes$errors, _state$changes$errors2, _state$changes$errors3;
18909
+ 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;
18686
18910
  }
18687
- function hasRowErrorsSeen(rowId) {
18688
- var _pendingChanges$rowId6;
18689
- if (!isEnabled) {
18690
- return false;
18691
- }
18692
- return hasRowErrors(rowId) && !!((_pendingChanges$rowId6 = pendingChanges[rowId]._meta.errors) !== null && _pendingChanges$rowId6 !== void 0 && _pendingChanges$rowId6.shouldShowErrorAlert);
18693
- }
18694
- function getRowPendingChange(rowId) {
18695
- const rowPendingChanges = pendingChanges[rowId];
18696
- if (rowPendingChanges) {
18697
- const {
18698
- _meta,
18699
- ...pendingChange
18700
- } = rowPendingChanges;
18701
- return pendingChange;
18702
- }
18703
- return undefined;
18911
+ function hasRowErrorsShownInAlert(rowId) {
18912
+ var _state$changes$errors4;
18913
+ return hasRowErrors(rowId) && !!((_state$changes$errors4 = state.changes.errors[rowId]) !== null && _state$changes$errors4 !== void 0 && _state$changes$errors4.shouldShowErrorAlert);
18704
18914
  }
18705
- function getRowSaveStatus(rowId) {
18706
- if (!isEnabled) {
18707
- return false;
18708
- }
18709
- return saveStates[rowId];
18915
+ function getRowStatus(rowId) {
18916
+ return state.changes.status[rowId];
18710
18917
  }
18711
- function setRowSaveStatus(rowId, status) {
18712
- setSaveState(currentStates => {
18713
- const nextStates = {
18714
- ...currentStates
18715
- };
18716
- if (status) {
18717
- nextStates[rowId] = status;
18718
- } else {
18719
- delete nextStates[rowId];
18918
+ function setRowStatus(rowId, status) {
18919
+ dispatch({
18920
+ type: 'setRowStatus',
18921
+ rowId,
18922
+ payload: {
18923
+ status
18720
18924
  }
18721
- return nextStates;
18722
18925
  });
18723
18926
  }
18724
- function getRowMoveReason(rowId) {
18725
- var _pendingChanges$rowId7;
18726
- return (_pendingChanges$rowId7 = pendingChanges[rowId]) !== null && _pendingChanges$rowId7 !== void 0 && _pendingChanges$rowId7._meta.moveReason ? Object.values(pendingChanges[rowId]._meta.moveReason)[0] : undefined;
18727
- }
18728
- function hasChanges(rowId) {
18729
- if (!isEnabled) {
18730
- return false;
18927
+ function setCellValue(cell, value) {
18928
+ const rowId = cell.row.id;
18929
+ const columnId = cell.column.id;
18930
+ // update if the change is different to the original value
18931
+ if (value !== cell.row.original[columnId]) {
18932
+ dispatch({
18933
+ type: 'setCellValue',
18934
+ rowId,
18935
+ payload: {
18936
+ columnId,
18937
+ row: cell.row.original,
18938
+ value
18939
+ }
18940
+ });
18731
18941
  }
18732
- return rowId ? !!pendingChanges[rowId] : !!Object.keys(pendingChanges).length;
18733
- }
18734
- function hasAlertErrors() {
18735
- if (!isEnabled) {
18736
- return false;
18942
+ // otherwise remove any previous change - no point saving the same value
18943
+ else if (cell.row.id in state.changes.rows) {
18944
+ dispatch({
18945
+ type: 'removeCellValue',
18946
+ rowId,
18947
+ payload: {
18948
+ columnId,
18949
+ rowIdentityAccessor
18950
+ }
18951
+ });
18737
18952
  }
18738
- return !!getAlertErrors().length;
18739
18953
  }
18740
- function getAlertErrors() {
18741
- return Object.keys(pendingChanges).filter(hasRowErrorsSeen).map(rowId => ({
18954
+ function getCellValue(cell) {
18955
+ var _state$changes$rows2, _state$changes$rows2$;
18956
+ 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];
18957
+ }
18958
+ function getCellError(cell) {
18959
+ var _state$changes$errors5, _state$changes$errors6, _state$changes$errors7;
18960
+ return (_state$changes$errors5 = state.changes.errors) === null || _state$changes$errors5 === void 0 ? void 0 : (_state$changes$errors6 = _state$changes$errors5[cell.row.id]) === null || _state$changes$errors6 === void 0 ? void 0 : (_state$changes$errors7 = _state$changes$errors6.cells) === null || _state$changes$errors7 === void 0 ? void 0 : _state$changes$errors7[cell.column.id];
18961
+ }
18962
+ function getErrorsShownInAlert() {
18963
+ const rowsWithErrors = Object.keys(state.changes.errors);
18964
+ if (!rowsWithErrors.length) {
18965
+ return [];
18966
+ }
18967
+ return rowsWithErrors.filter(hasRowErrorsShownInAlert).map(rowId => ({
18742
18968
  rowId,
18743
- pendingChange: pendingChanges[rowId]
18969
+ changes: state.changes.rows[rowId],
18970
+ errors: state.changes.errors[rowId]
18744
18971
  }));
18745
18972
  }
18746
- function resetChanges(rowId) {
18747
- setPendingChanges(currentChanges => {
18748
- const nextChanges = {
18749
- ...currentChanges
18750
- };
18751
- delete nextChanges[rowId];
18752
- return nextChanges;
18753
- });
18973
+ function hasSaved() {
18974
+ return !!Object.values(state.changes.status).filter(value => value === 'saved').length;
18975
+ }
18976
+ function hasChanges(rowId) {
18977
+ return rowId ? !!state.changes.rows[rowId] : !!Object.keys(state.changes.rows).length;
18754
18978
  }
18755
- function getCompletedRowsCount() {
18756
- return Object.values(saveStates).filter(value => value === 'complete').length;
18979
+ function discardChanges(rowId, table) {
18980
+ // remove any new rows from pinned state before discarding them
18981
+ table.resetRowPinning(true);
18982
+ dispatch({
18983
+ type: 'removeRow',
18984
+ rowId,
18985
+ payload: {
18986
+ rowIdentityAccessor
18987
+ }
18988
+ });
18757
18989
  }
18758
18990
  return {
18991
+ // row
18992
+ setRowValue,
18993
+ getRowValue,
18994
+ getRowMoveReason,
18995
+ hasRowErrors,
18996
+ hasRowErrorsShownInAlert,
18997
+ getRowStatus,
18998
+ setRowStatus,
18999
+ // cells
19000
+ setCellValue,
18759
19001
  getCellValue,
18760
19002
  getCellError,
18761
- setCellValue,
18762
- validateCell,
18763
- addCreatedRowChangeset,
19003
+ onCellChanged,
19004
+ // general
19005
+ getErrorsShownInAlert,
18764
19006
  hasChanges,
18765
- hasAlertErrors,
18766
- getAlertErrors,
18767
19007
  saveChanges,
18768
- resetChanges,
18769
- hasRowErrors,
18770
- hasRowErrorsSeen,
18771
- getRowPendingChange,
18772
- getRowSaveStatus,
18773
- setRowSaveStatus,
18774
- getRowMoveReason,
18775
- getCompletedRowsCount
19008
+ discardChanges,
19009
+ hasSaved,
19010
+ // new rows
19011
+ createRow,
19012
+ temporaryRows: state.temporaryRows
18776
19013
  };
18777
19014
  }
18778
- function useLastFocusedCellIndex() {
19015
+
19016
+ function useTableEditing(isEnabled = false, handleSave, handleChange, rowIdentityAccessor, validator) {
19017
+ // used to switch the table into editing mode
19018
+ const [isEditing, setEditing] = React__default.useState(false);
19019
+ // used to switch the editing between "detailed" mode
19020
+ const [isDetailedMode, toggleDetailedMode] = React__default.useState(false);
19021
+ // used to contain ref to the create button
19022
+ const createRowButtonRef = React__default.useRef(null);
18779
19023
  // store the last focused cell, so that up/down arrow key navigation remains in the same column
18780
- const lastFocusedCellIndexRef = React__default.useRef(undefined);
18781
- const setLastFocusedCellIndex = React__default.useCallback(index => {
18782
- lastFocusedCellIndexRef.current = index;
18783
- }, []);
18784
- return [lastFocusedCellIndexRef.current, setLastFocusedCellIndex];
18785
- }
18786
- function usePendingChangesUpdater(handleChange, setPendingChanges) {
18787
- const localization = useLocalization();
18788
- const updatersRef = React__default.useRef({});
18789
- const runCellUpdates = React__default.useCallback(lodash.debounce(function (changes, cell, rowIndex) {
18790
- try {
18791
- const _temp4 = function () {
18792
- if (typeof handleChange === 'function') {
18793
- const previousValues = {
18794
- ...cell.row.original,
18795
- ...getChangesetFromChanges(updatersRef.current[cell.row.id])
18796
- };
18797
- const nextValues = {
18798
- ...previousValues,
18799
- ...changes
18800
- };
18801
- return Promise.resolve(handleChange(cell.column.id, changes[cell.column.id], nextValues, previousValues)).then(function (updates) {
18802
- if (updates && Object.keys(updates).length) {
18803
- setPendingChanges(currentChanges => createPendingChangesSetter(currentChanges, cell.row, rowIndex, updates, localization));
18804
- }
18805
- });
18806
- }
18807
- }();
18808
- return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(function () {}) : void 0);
18809
- } catch (e) {
18810
- return Promise.reject(e);
19024
+ const [lastFocusedCellIndex, setLastFocusedCellIndex] = React__default.useState(undefined);
19025
+ const pendingChangesFns = usePendingChangesState(handleSave, handleChange, rowIdentityAccessor, validator);
19026
+ function toggleEditing(enabled, table) {
19027
+ if (!enabled) {
19028
+ // save
19029
+ pendingChangesFns.saveChanges(table);
19030
+ // reset detailed mode
19031
+ toggleDetailedMode(false);
19032
+ // reset the last index back to the first focusable element, when editing gets turned off
19033
+ setLastFocusedCellIndex(undefined);
18811
19034
  }
18812
- }, 250), []);
18813
- function syncCellChanges(changes) {
18814
- updatersRef.current = changes;
19035
+ setEditing(enabled);
18815
19036
  }
18816
19037
  return {
18817
- syncCellChanges,
18818
- runCellUpdates
18819
- };
18820
- }
18821
- function createPendingChangesSetter(currentChanges, row, rowIndex, changes, localization) {
18822
- var _currentChanges$row$i, _currentChanges$row$i2, _currentChanges$row$i3;
18823
- // prepare
18824
- const nextChanges = {
18825
- ...currentChanges
18826
- };
18827
- const rowChanges = {
18828
- ...currentChanges[row.id],
18829
- _meta: {
18830
- ...((_currentChanges$row$i = currentChanges[row.id]) === null || _currentChanges$row$i === void 0 ? void 0 : _currentChanges$row$i._meta),
18831
- original: row.original,
18832
- moveReason: {
18833
- ...((_currentChanges$row$i2 = currentChanges[row.id]) === null || _currentChanges$row$i2 === void 0 ? void 0 : _currentChanges$row$i2._meta.moveReason)
18834
- },
18835
- errors: {
18836
- ...((_currentChanges$row$i3 = currentChanges[row.id]) === null || _currentChanges$row$i3 === void 0 ? void 0 : _currentChanges$row$i3._meta.errors)
18837
- }
18838
- }
18839
- };
18840
- // run changes
18841
- const cells = row._getAllCellsByColumnId();
18842
- for (const [accessor, change] of Object.entries(changes)) {
18843
- // update if the change is different to the original (saved) value,
18844
- // otherwise remove any change - no point saving the same value
18845
- if (change !== row.original[accessor]) {
18846
- rowChanges[accessor] = change;
18847
- // consumers sometimes include properties in onEditingChange that aren't rendered as columns, we need to guard against that.
18848
- // eslint-disable-next-line no-prototype-builtins
18849
- if (cells.hasOwnProperty(accessor)) {
18850
- // determine if the row will move position based on this change, and save why it will move
18851
- const reason = willRowMove(cells[accessor], change, rowIndex, localization);
18852
- if (reason) {
18853
- rowChanges._meta.moveReason[accessor] = reason;
18854
- } else {
18855
- delete rowChanges._meta.moveReason[accessor];
18856
- }
18857
- }
18858
- } else {
18859
- delete rowChanges[accessor];
18860
- delete rowChanges._meta.moveReason[accessor];
18861
- }
18862
- }
18863
- // set changes
18864
- // or delete if there are no changes left, so that we don't store changes with unchanged data
18865
- if (Object.keys(rowChanges).filter(k => k !== '_meta').length) {
18866
- nextChanges[row.id] = rowChanges;
18867
- } else {
18868
- delete nextChanges[row.id];
18869
- }
18870
- return nextChanges;
18871
- }
18872
- function getChangesetFromChanges(changes) {
18873
- // extract the original data from the row changes
18874
- const {
18875
- _meta,
18876
- ...changeset
18877
- } = changes !== null && changes !== void 0 ? changes : {};
18878
- // and mix them in with the changes, ready to send to the server
18879
- return {
18880
- ...(_meta === null || _meta === void 0 ? void 0 : _meta.original),
18881
- ...changeset
19038
+ isEnabled,
19039
+ isEditing,
19040
+ isDetailedMode,
19041
+ toggleDetailedMode: isEnabled ? toggleDetailedMode : () => undefined,
19042
+ toggleEditing: isEnabled ? toggleEditing : () => undefined,
19043
+ lastFocusedCellIndex,
19044
+ setLastFocusedCellIndex,
19045
+ createRowButtonRef,
19046
+ ...pendingChangesFns
18882
19047
  };
18883
19048
  }
18884
19049
 
@@ -19120,13 +19285,28 @@ function EditingControlCell(props) {
19120
19285
  const {
19121
19286
  rowIndex
19122
19287
  } = React__default.useContext(RowContext);
19123
- const tableMeta = cell.getContext().table.options.meta;
19288
+ const {
19289
+ table
19290
+ } = cell.getContext();
19291
+ const tableMeta = table.options.meta;
19124
19292
  const columnMeta = cell.column.columnDef.meta;
19125
19293
  const isActiveRow = tableMeta.rowActive.rowActiveIndex === rowIndex;
19294
+ const type = (_columnMeta$control = columnMeta.control) !== null && _columnMeta$control !== void 0 ? _columnMeta$control : 'input';
19126
19295
  const handleFocus = useEditingCellAutofocus(props);
19296
+ // some controls, like select2, should trigger cell changed (validation, updates) as the value changes
19297
+ const hasNonTextControl = React__default.useMemo(() => {
19298
+ var _cellRef$current;
19299
+ 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"]'));
19300
+ }, [cellRef.current]);
19301
+ const handleChange = value => {
19302
+ tableMeta.editing.setCellValue(cell, value);
19303
+ if (hasNonTextControl) {
19304
+ tableMeta.editing.onCellChanged(cell, rowIndex);
19305
+ }
19306
+ };
19127
19307
  const handleBlur = () => {
19128
19308
  tableMeta.editing.toggleDetailedMode(false);
19129
- tableMeta.editing.validateCell(cell);
19309
+ tableMeta.editing.onCellChanged(cell, rowIndex);
19130
19310
  };
19131
19311
  // ensure that blur runs when the cell gets unmounted (when vertically arrow key navigating)
19132
19312
  React__default.useEffect(() => {
@@ -19146,13 +19326,12 @@ function EditingControlCell(props) {
19146
19326
  isDetailedMode: tableMeta.editing.isDetailedMode,
19147
19327
  isTruncated: !!columnMeta.enableTruncate,
19148
19328
  onBlur: handleBlur,
19149
- onChange: value => tableMeta.editing.setCellValue(cell, value, rowIndex),
19329
+ onChange: handleChange,
19150
19330
  row: cell.row.original,
19151
- rowPendingChanges: tableMeta.editing.getRowPendingChange(cell.row.id),
19331
+ rowPendingChanges: tableMeta.editing.getRowValue(cell.row.id),
19152
19332
  tabIndex: isActiveRow ? 0 : -1,
19153
- toggleEditing: tableMeta.editing.toggleEditing,
19154
19333
  toggleDetailedMode: tableMeta.editing.toggleDetailedMode,
19155
- type: (_columnMeta$control = columnMeta.control) !== null && _columnMeta$control !== void 0 ? _columnMeta$control : 'input',
19334
+ type,
19156
19335
  value: cell.getValue()
19157
19336
  };
19158
19337
  const cellAttributes = {
@@ -19185,7 +19364,6 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19185
19364
  row,
19186
19365
  rowPendingChanges,
19187
19366
  tabIndex = -1,
19188
- toggleEditing,
19189
19367
  toggleDetailedMode,
19190
19368
  type = 'input',
19191
19369
  value
@@ -19244,8 +19422,8 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19244
19422
  }
19245
19423
  // reset the value, or exit edit mode when pressing escape
19246
19424
  if (event.key === 'Escape') {
19247
- event.preventDefault();
19248
19425
  if (isDetailedMode) {
19426
+ event.preventDefault();
19249
19427
  toggleDetailedMode(false);
19250
19428
  if (value !== currentValue) {
19251
19429
  props.onChange(currentValue);
@@ -19255,8 +19433,6 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19255
19433
  var _target$select2;
19256
19434
  return (_target$select2 = target.select) === null || _target$select2 === void 0 ? void 0 : _target$select2.call(target);
19257
19435
  });
19258
- } else {
19259
- toggleEditing(false);
19260
19436
  }
19261
19437
  return;
19262
19438
  }
@@ -19355,12 +19531,37 @@ function Cell$5(props) {
19355
19531
  return /*#__PURE__*/React__default.createElement(DisplayCell, Object.assign({}, props));
19356
19532
  }
19357
19533
 
19534
+ function DiscardChangesConfirmationDialog(props) {
19535
+ const {
19536
+ onDiscard: handleDiscard,
19537
+ ...dialogProps
19538
+ } = props;
19539
+ const {
19540
+ texts
19541
+ } = useLocalization();
19542
+ const handleClickInsideDialogContent = event => {
19543
+ // Prevents the click event from propagating to the table, ensuring the row isn't saved when a click occurs
19544
+ // inside the dialog
19545
+ event.stopPropagation();
19546
+ };
19547
+ return /*#__PURE__*/React__default.createElement(Dialog, Object.assign({}, dialogProps), /*#__PURE__*/React__default.createElement(Dialog.Content, {
19548
+ "aria-label": texts.table3.editing.clearChangesConfirmationDialog.title,
19549
+ onClick: handleClickInsideDialogContent
19550
+ }, /*#__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, {
19551
+ tabIndex: 0
19552
+ }, texts.table3.editing.clearChangesConfirmationDialog.cancel)), /*#__PURE__*/React__default.createElement(Dialog.Close, null, /*#__PURE__*/React__default.createElement(Button$1, {
19553
+ autoFocus: true,
19554
+ tabIndex: 0,
19555
+ appearance: "primary",
19556
+ onClick: handleDiscard
19557
+ }, texts.table3.editing.clearChangesConfirmationDialog.confirm))))));
19558
+ }
19559
+
19358
19560
  function EditingActionMenu(props) {
19359
19561
  const {
19360
19562
  hasChanges,
19361
19563
  hasErrors,
19362
- onClear: handleClear,
19363
- onExit: handleExit,
19564
+ onDiscard: handleDiscard,
19364
19565
  onEditingSave: handleSave,
19365
19566
  isLastRow
19366
19567
  } = props;
@@ -19382,7 +19583,6 @@ function EditingActionMenu(props) {
19382
19583
  return /*#__PURE__*/React__default.createElement(IconButton, {
19383
19584
  appearance: "transparent",
19384
19585
  "aria-label": texts.table3.editing.actions.tooltip,
19385
- className: "group-[[data-row-editing-status]]/row:hidden",
19386
19586
  icon: "more",
19387
19587
  onKeyDown: handleKeyDown,
19388
19588
  menu: menuProps => (/*#__PURE__*/React__default.createElement(Menu$1, Object.assign({}, menuProps), /*#__PURE__*/React__default.createElement(Menu$1.Content, {
@@ -19394,42 +19594,13 @@ function EditingActionMenu(props) {
19394
19594
  }, texts.table3.editing.actions.save), /*#__PURE__*/React__default.createElement(Menu$1.Item, {
19395
19595
  icon: "close",
19396
19596
  disabled: !hasChanges,
19397
- dialog: props => /*#__PURE__*/React__default.createElement(ConfirmClearChangesDialog, Object.assign({}, props, {
19398
- onClear: handleClear
19597
+ dialog: props => /*#__PURE__*/React__default.createElement(DiscardChangesConfirmationDialog, Object.assign({}, props, {
19598
+ onDiscard: handleDiscard
19399
19599
  }))
19400
- }, texts.table3.editing.actions.clear), /*#__PURE__*/React__default.createElement(Menu$1.Item, {
19401
- icon: "undo",
19402
- onClick: handleExit
19403
- }, texts.table3.editing.actions.exit))))
19600
+ }, texts.table3.editing.actions.clear))))
19404
19601
  });
19405
19602
  }
19406
- function ConfirmClearChangesDialog(props) {
19407
- const {
19408
- onClear: handleClear,
19409
- ...dialogProps
19410
- } = props;
19411
- const {
19412
- texts
19413
- } = useLocalization();
19414
- const handleClickInsideDialogContent = event => {
19415
- // Prevents the click event from propagating to the table, ensuring the row isn't saved when a click occurs
19416
- // inside the dialog
19417
- event.stopPropagation();
19418
- };
19419
- return /*#__PURE__*/React__default.createElement(Dialog, Object.assign({}, dialogProps), /*#__PURE__*/React__default.createElement(Dialog.Content, {
19420
- "aria-label": texts.table3.editing.clearChangesConfirmationDialog.title,
19421
- onClick: handleClickInsideDialogContent
19422
- }, /*#__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, {
19423
- tabIndex: 0
19424
- }, texts.table3.editing.clearChangesConfirmationDialog.cancel)), /*#__PURE__*/React__default.createElement(Dialog.Close, null, /*#__PURE__*/React__default.createElement(Button$1, {
19425
- autoFocus: true,
19426
- tabIndex: 0,
19427
- appearance: "primary",
19428
- onClick: handleClear
19429
- }, texts.table3.editing.clearChangesConfirmationDialog.confirm))))));
19430
- }
19431
19603
 
19432
- const COMPLETE_INDICATOR_DELAY = 3000;
19433
19604
  function SaveStatus(props) {
19434
19605
  const {
19435
19606
  rowId,
@@ -19439,18 +19610,7 @@ function SaveStatus(props) {
19439
19610
  texts
19440
19611
  } = useLocalization();
19441
19612
  const tableMeta = table.options.meta;
19442
- const status = tableMeta.editing.getRowSaveStatus(rowId);
19443
- React__default.useEffect(() => {
19444
- let timeout;
19445
- if (status === 'complete') {
19446
- timeout = setTimeout(() => {
19447
- tableMeta.editing.setRowSaveStatus(rowId, undefined);
19448
- }, COMPLETE_INDICATOR_DELAY);
19449
- }
19450
- return () => {
19451
- clearTimeout(timeout);
19452
- };
19453
- }, [status]);
19613
+ const status = tableMeta.editing.getRowStatus(rowId);
19454
19614
  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)]', {
19455
19615
  'mt-0.5': tableMeta.rowHeight.height === 'short',
19456
19616
  'mt-1': tableMeta.rowHeight.height === 'medium',
@@ -19461,7 +19621,7 @@ function SaveStatus(props) {
19461
19621
  className: "!contents"
19462
19622
  }, /*#__PURE__*/React__default.createElement("span", {
19463
19623
  className: className
19464
- }, status === 'pending' ? (/*#__PURE__*/React__default.createElement(Tooltip, {
19624
+ }, status === 'saving' ? (/*#__PURE__*/React__default.createElement(Tooltip, {
19465
19625
  title: texts.table3.editing.saving.progress
19466
19626
  }, /*#__PURE__*/React__default.createElement(Spinner, {
19467
19627
  delay: 0,
@@ -19499,15 +19659,46 @@ function Row$2(props) {
19499
19659
  }
19500
19660
  }
19501
19661
  }, [tableMeta.editing.isEditing, isActiveRow]);
19662
+ const rowStatus = tableMeta.editing.getRowStatus(row.id);
19663
+ // discard new row
19664
+ const [showDiscardDialog, setShowDiscardDialog] = React__default.useState(false);
19665
+ function handleDiscard() {
19666
+ tableMeta.editing.discardChanges(row.id, table);
19667
+ requestAnimationFrame(() => {
19668
+ if (isTemporaryRow(row.id)) {
19669
+ var _tableMeta$editing$cr;
19670
+ (_tableMeta$editing$cr = tableMeta.editing.createRowButtonRef.current) === null || _tableMeta$editing$cr === void 0 ? void 0 : _tableMeta$editing$cr.focus();
19671
+ } else {
19672
+ focusManager.focusFirst();
19673
+ }
19674
+ });
19675
+ }
19676
+ function handleKeyDown(event) {
19677
+ if (props.onKeyDown) {
19678
+ props.onKeyDown(event);
19679
+ }
19680
+ if (event.isDefaultPrevented() || event.isPropagationStopped()) {
19681
+ return;
19682
+ }
19683
+ if (event.key === 'Escape' && tableMeta.editing.hasChanges(row.id) && !isElementTriggeredFromContainer(event.target, event.currentTarget)) {
19684
+ event.preventDefault();
19685
+ setShowDiscardDialog(true);
19686
+ }
19687
+ }
19502
19688
  const attributes = {
19503
- 'data-row-editing-invalid': tableMeta.editing.isEnabled && tableMeta.editing.hasRowErrors(row.id) ? !tableMeta.editing.hasRowErrorsSeen(row.id) ? 'unseen' : true : undefined,
19504
- 'data-row-editing-status': tableMeta.editing.isEnabled && tableMeta.editing.getRowSaveStatus(row.id) ? tableMeta.editing.getRowSaveStatus(row.id) : undefined,
19505
- onFocus: handleFocus
19689
+ 'data-row-editing-invalid': tableMeta.editing.hasRowErrors(row.id) ? !tableMeta.editing.hasRowErrorsShownInAlert(row.id) ? 'unseen' : true : undefined,
19690
+ 'data-row-editing-status': rowStatus,
19691
+ onFocus: handleFocus,
19692
+ onKeyDown: handleKeyDown
19506
19693
  };
19507
- return /*#__PURE__*/React__default.createElement(DisplayRow, Object.assign({}, props, attributes), tableMeta.editing.getRowSaveStatus(row.id) ? /*#__PURE__*/React__default.createElement(SaveStatus, {
19694
+ 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, {
19508
19695
  rowId: row.id,
19509
19696
  table: table
19510
- }) : null);
19697
+ }) : null), /*#__PURE__*/React__default.createElement(DiscardChangesConfirmationDialog, {
19698
+ open: showDiscardDialog,
19699
+ onChange: setShowDiscardDialog,
19700
+ onDiscard: handleDiscard
19701
+ }));
19511
19702
  }
19512
19703
 
19513
19704
  const RENDERERS$1 = {
@@ -19515,29 +19706,46 @@ const RENDERERS$1 = {
19515
19706
  cell: Cell$5
19516
19707
  };
19517
19708
  function useTable3(props, ref) {
19518
- const editing = useTableEditing(props.enableEditing, props.onEditingSave, props.onEditingChange, props.validator);
19709
+ const editing = useTableEditing(props.enableEditing, props.onEditingSave, props.onEditingChange, props.rowIdentityAccessor, props.validator);
19519
19710
  const creationEnabled = editing.isEnabled && !!props.onEditingCreate;
19711
+ // this gives me the performance heeby jeebies, but can't think of a better way to internalise the state
19712
+ const data = React__default.useMemo(() => {
19713
+ if (editing.isEditing && editing.temporaryRows.length) {
19714
+ var _props$data;
19715
+ return editing.temporaryRows.concat((_props$data = props.data) !== null && _props$data !== void 0 ? _props$data : []);
19716
+ }
19717
+ return props.data;
19718
+ }, [JSON.stringify(props.data), editing.temporaryRows.length]);
19520
19719
  const extendedProps = {
19521
19720
  ...props,
19721
+ data,
19522
19722
  enableRowActions: editing.isEditing ? true : props.enableRowActions,
19523
- rowActions: editing.isEditing ? [(_, rowId) => (/*#__PURE__*/React__default.createElement(EditingActionMenu, {
19723
+ rowActions: editing.isEditing ? [(_, rowId, table) => (/*#__PURE__*/React__default.createElement(EditingActionMenu, {
19524
19724
  hasChanges: editing.hasChanges(rowId),
19525
19725
  hasErrors: editing.hasRowErrors(rowId),
19526
- onClear: () => editing.resetChanges(rowId),
19527
- onEditingSave: () => editing.saveChanges(rowId),
19528
- onExit: () => editing.toggleEditing(false),
19726
+ onDiscard: () => editing.discardChanges(rowId, table),
19727
+ onEditingSave: function () {
19728
+ try {
19729
+ return Promise.resolve(editing.saveChanges(table, rowId)).then(function () {});
19730
+ } catch (e) {
19731
+ return Promise.reject(e);
19732
+ }
19733
+ },
19529
19734
  isLastRow: !creationEnabled && table.meta.rowActive.rowActiveIndex === table.meta.length - 1
19530
19735
  }))] : props.rowActions
19531
19736
  };
19532
19737
  const meta = {
19533
19738
  editing
19534
19739
  };
19535
- const table = useTable(extendedProps, ref, RENDERERS$1, meta);
19740
+ const options = {
19741
+ virtualiserPaddingEndOffset: props.enableEditing && props.onEditingCreate ? 1 : 0
19742
+ };
19743
+ const table = useTable(extendedProps, ref, RENDERERS$1, meta, options);
19536
19744
  // listeners
19537
19745
  useTableEditingListener(table.instance, table.ref);
19538
19746
  React__default.useEffect(() => {
19539
19747
  if (table.ref.current) {
19540
- table.ref.current.instance.toggleEditing = enabled => table.meta.editing.toggleEditing(enabled !== null && enabled !== void 0 ? enabled : editing => !editing);
19748
+ table.ref.current.instance.toggleEditing = enabled => table.meta.editing.toggleEditing(enabled !== null && enabled !== void 0 ? enabled : editing => !editing, table.instance);
19541
19749
  }
19542
19750
  }, [table.ref.current]);
19543
19751
  return table;
@@ -19556,7 +19764,7 @@ function Alert$1(props) {
19556
19764
  const validationTexts = texts.table3.editing.validation;
19557
19765
  const tableMeta = table.options.meta;
19558
19766
  const [showFilterResetDialog, setShowFilterResetDialog] = React__default.useState(false);
19559
- const pendingChangesWithErrors = tableMeta.editing.getAlertErrors();
19767
+ const pendingChangesWithErrors = tableMeta.editing.getErrorsShownInAlert();
19560
19768
  function scrollToRow(rowIndex) {
19561
19769
  tableMeta.rowActive.setRowActiveIndex(rowIndex);
19562
19770
  scrollToIndex(rowIndex, {
@@ -19575,38 +19783,43 @@ function Alert$1(props) {
19575
19783
  const title = (pendingChangesWithErrors.length === 1 ? validationTexts.alert.titleOne : validationTexts.alert.titlePlural).replace('[COUNT]', String(pendingChangesWithErrors.length));
19576
19784
  // generate links to each invalid row, to go into the error message
19577
19785
  const links = [];
19578
- const rowIdentityColumn = tableMeta.rowIdentityColumnId ? table.getColumn(tableMeta.rowIdentityColumnId) : undefined;
19579
- pendingChangesWithErrors.forEach((error, index) => {
19786
+ const visibleColumns = table.getVisibleFlatColumns().map(c => c.id);
19787
+ const rowIdentityColumn = tableMeta.rowIdentityAccessor && visibleColumns.includes(String(tableMeta.rowIdentityAccessor)) ? table.getColumn(String(tableMeta.rowIdentityAccessor)) : undefined;
19788
+ pendingChangesWithErrors.forEach((pendingChangeWithError, index) => {
19580
19789
  // if appropriate, concatenate the item with the text "and"
19581
19790
  if (pendingChangesWithErrors.length > 1 && index === pendingChangesWithErrors.length - 1) {
19582
19791
  // Add space before and after `messageAnd` text
19583
19792
  links.push(` ${validationTexts.alert.messageAnd} `);
19584
19793
  }
19585
- const rowIndex = table.getRowModel().rows.findIndex(row => row.id === error.rowId);
19794
+ const rowIndex = table.getRowModel().rows.findIndex(row => row.id === pendingChangeWithError.rowId);
19586
19795
  const handleClick = () => {
19796
+ // if row is visible
19587
19797
  if (rowIndex > -1) {
19588
19798
  scrollToRow(rowIndex);
19589
- } else {
19590
- setShowFilterResetDialog(error.rowId);
19799
+ }
19800
+ // if row is filtered out
19801
+ else {
19802
+ setShowFilterResetDialog(pendingChangeWithError.rowId);
19591
19803
  }
19592
19804
  };
19593
19805
  let tooltip;
19594
- if (error.pendingChange._meta.errors.row) {
19595
- tooltip = error.pendingChange._meta.errors.row;
19806
+ if (pendingChangeWithError.errors.row) {
19807
+ tooltip = pendingChangeWithError.errors.row;
19596
19808
  } else {
19597
19809
  var _table$getAllColumns$, _table$getAllColumns$2;
19598
- const firstCellErrorColumnId = Object.keys(error.pendingChange._meta.errors.cells)[0];
19810
+ const firstCellErrorColumnId = Object.keys(pendingChangeWithError.errors.cells)[0];
19599
19811
  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;
19600
- tooltip = `${columnName}: ${error.pendingChange._meta.errors.cells[firstCellErrorColumnId]}`;
19812
+ tooltip = `${columnName}: ${pendingChangeWithError.errors.cells[firstCellErrorColumnId]}`;
19601
19813
  }
19814
+ const row = table.getRow(pendingChangeWithError.rowId).original;
19602
19815
  links.push(/*#__PURE__*/React__default.createElement(Tooltip, {
19603
- key: error.rowId,
19816
+ key: pendingChangeWithError.rowId,
19604
19817
  title: tooltip
19605
19818
  }, /*#__PURE__*/React__default.createElement("span", {
19606
19819
  className: "text-blue",
19607
19820
  onClick: handleClick,
19608
19821
  role: "button"
19609
- }, rowIdentityColumn ? error.pendingChange._meta.original[rowIdentityColumn.id] : rowIndex + 1)));
19822
+ }, rowIdentityColumn ? row[rowIdentityColumn.id] : rowIndex + 1)));
19610
19823
  // if appropriate, concatenate the item with the text ","
19611
19824
  if (pendingChangesWithErrors.length > 2 && index < pendingChangesWithErrors.length - 2) {
19612
19825
  links.push(', ');
@@ -19662,89 +19875,6 @@ function FilterResetDialog(props) {
19662
19875
  }, texts.table3.editing.validation.resetFiltersDialog.confirm)))));
19663
19876
  }
19664
19877
 
19665
- function CreateNewRowButton(props) {
19666
- const {
19667
- onEditingCreate,
19668
- scrollToIndex,
19669
- table,
19670
- tableMeta
19671
- } = props;
19672
- const {
19673
- texts
19674
- } = useLocalization();
19675
- const rows = table.getCoreRowModel().rows.filter(row => row.original !== undefined);
19676
- const [rowCreated, setRowCreated] = React__default.useState({
19677
- rowFinder: undefined
19678
- });
19679
- const handleKeyDown = event => {
19680
- if (!tableMeta.editing.hasChanges() && event.key === 'Tab') {
19681
- tableMeta.editing.saveChanges();
19682
- }
19683
- };
19684
- const handleCreate = function () {
19685
- try {
19686
- if (!onEditingCreate) {
19687
- return Promise.resolve();
19688
- }
19689
- const createdRow = rows.find(row => {
19690
- var _rowCreated$rowFinder;
19691
- 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);
19692
- });
19693
- const _temp = function () {
19694
- if (createdRow) {
19695
- return Promise.resolve(tableMeta.editing.saveChanges()).then(function () {
19696
- if (!tableMeta.editing.hasRowErrors(createdRow.id)) {
19697
- const rowFinder = onEditingCreate();
19698
- setRowCreated({
19699
- rowFinder
19700
- });
19701
- }
19702
- });
19703
- } else {
19704
- const rowFinder = onEditingCreate();
19705
- setRowCreated({
19706
- rowFinder
19707
- });
19708
- }
19709
- }();
19710
- return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
19711
- } catch (e) {
19712
- return Promise.reject(e);
19713
- }
19714
- };
19715
- React__default.useEffect(() => {
19716
- if (typeof (rowCreated === null || rowCreated === void 0 ? void 0 : rowCreated.rowFinder) === 'function') {
19717
- const createdRow = rows.find(row => {
19718
- var _rowCreated$rowFinder2;
19719
- 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);
19720
- });
19721
- if (createdRow) {
19722
- const rowInTable = table.getRowModel().rows.filter(row => row.original !== undefined).find(row => {
19723
- var _rowCreated$rowFinder3;
19724
- 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);
19725
- });
19726
- if (rowInTable) {
19727
- tableMeta.editing.toggleEditing(true);
19728
- tableMeta.rowActive.setRowActiveIndex(createdRow.index);
19729
- scrollToIndex(createdRow.index);
19730
- requestAnimationFrame(() => animateCreateRow(createdRow.id));
19731
- }
19732
- requestAnimationFrame(() => tableMeta.editing.addCreatedRowChangeset(createdRow));
19733
- }
19734
- }
19735
- }, [rowCreated]);
19736
- return /*#__PURE__*/React__default.createElement("tr", {
19737
- onClick: handleCreate,
19738
- className: "border-grey-300 hover:bg-grey-100 group !sticky bottom-10 left-0 z-[21] !block cursor-pointer border-t"
19739
- }, /*#__PURE__*/React__default.createElement("td", {
19740
- className: "!border-t-0 !bg-transparent"
19741
- }, /*#__PURE__*/React__default.createElement(Button$1, {
19742
- onKeyDown: handleKeyDown,
19743
- className: "group-hover:bg-grey-200 sticky left-0",
19744
- appearance: "transparent"
19745
- }, "+ ", texts.table3.editing.buttons.create.label)));
19746
- }
19747
-
19748
19878
  function Editing(props) {
19749
19879
  const {
19750
19880
  scrollToIndex,
@@ -19770,21 +19900,193 @@ function Editing(props) {
19770
19900
  (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.click();
19771
19901
  });
19772
19902
  const handleChange = enabled => {
19773
- tableMeta.editing.toggleEditing(enabled);
19903
+ if (enabled && tableMeta.rowActive.rowActiveIndex === undefined) {
19904
+ tableMeta.rowActive.setRowActiveIndex(0);
19905
+ }
19774
19906
  requestAnimationFrame(() => {
19775
19907
  var _tableMeta$rowActive$;
19776
- return scrollToIndex((_tableMeta$rowActive$ = tableMeta.rowActive.rowActiveIndex) !== null && _tableMeta$rowActive$ !== void 0 ? _tableMeta$rowActive$ : 0);
19908
+ // wait for an active row to be set so that we don't trigger save
19909
+ tableMeta.editing.toggleEditing(enabled, table);
19910
+ scrollToIndex((_tableMeta$rowActive$ = tableMeta.rowActive.rowActiveIndex) !== null && _tableMeta$rowActive$ !== void 0 ? _tableMeta$rowActive$ : 0);
19777
19911
  });
19778
19912
  };
19779
19913
  return /*#__PURE__*/React__default.createElement(Tooltip, {
19780
19914
  title: tooltip
19781
19915
  }, /*#__PURE__*/React__default.createElement(ModeSwitch, {
19916
+ "data-table": "editing-toggle",
19782
19917
  checked: tableMeta.editing.isEditing,
19783
19918
  onChange: handleChange,
19784
19919
  ref: ref
19785
19920
  }));
19786
19921
  }
19787
19922
 
19923
+ function CreateNewRow(props) {
19924
+ var _temporaryRows$0$tabl, _temporaryRows$, _table$getState$colum;
19925
+ const {
19926
+ buttonRef,
19927
+ onEditingCreate: handleEditingCreate,
19928
+ table,
19929
+ tableMeta
19930
+ } = props;
19931
+ const {
19932
+ texts
19933
+ } = useLocalization();
19934
+ const temporaryRows = tableMeta.editing.temporaryRows;
19935
+ 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 : '';
19936
+ 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);
19937
+ const isSaving = !!temporaryRowId && tableMeta.editing.getRowStatus(temporaryRowId) === 'saving';
19938
+ const handleCreate = function (event) {
19939
+ try {
19940
+ // prevent save being triggered by click outside - TODO: investigate why the button triggers clickoutside
19941
+ event === null || event === void 0 ? void 0 : event.stopPropagation();
19942
+ if (!handleEditingCreate || isDisabled) {
19943
+ return Promise.resolve();
19944
+ }
19945
+ return Promise.resolve(tableMeta.editing.saveChanges(table)).then(function (saved) {
19946
+ if (!saved) {
19947
+ return;
19948
+ }
19949
+ try {
19950
+ const changeset = handleEditingCreate();
19951
+ if (changeset) {
19952
+ // change the row before reating because it triggers a save
19953
+ // saving would trigger the validation flow and immediately make the row red
19954
+ tableMeta.rowActive.setRowActiveIndex(tableMeta.length);
19955
+ requestAnimationFrame(function () {
19956
+ try {
19957
+ tableMeta.editing.toggleEditing(true, table);
19958
+ return Promise.resolve(tableMeta.editing.createRow(changeset)).then(function (rowId) {
19959
+ tableMeta.editing.setLastFocusedCellIndex(0);
19960
+ try {
19961
+ const row = table.getRow(rowId);
19962
+ row.pin('bottom');
19963
+ } catch {
19964
+ //
19965
+ }
19966
+ });
19967
+ } catch (e) {
19968
+ return Promise.reject(e);
19969
+ }
19970
+ });
19971
+ }
19972
+ } catch (error) {
19973
+ console.error(error);
19974
+ }
19975
+ });
19976
+ } catch (e) {
19977
+ return Promise.reject(e);
19978
+ }
19979
+ };
19980
+ let tooltip;
19981
+ if (isSaving) {
19982
+ tooltip = texts.table3.editing.buttons.create.saving;
19983
+ } else if (isDisabled) {
19984
+ tooltip = texts.table3.editing.buttons.create.disabled;
19985
+ }
19986
+ return /*#__PURE__*/React__default.createElement("tr", {
19987
+ "data-row-create": true,
19988
+ className: "border-grey-300 group/row",
19989
+ tabIndex: -1
19990
+ }, /*#__PURE__*/React__default.createElement("td", {
19991
+ className: "!bg-grey-50 col-span-full !border-b-0 !px-1"
19992
+ }, /*#__PURE__*/React__default.createElement(Button$1, {
19993
+ appearance: "transparent",
19994
+ className: "group-hover:bg-grey-200 sticky left-[4px]",
19995
+ disabled: isDisabled,
19996
+ onClick: handleCreate,
19997
+ ref: buttonRef,
19998
+ tooltip: tooltip
19999
+ }, /*#__PURE__*/React__default.createElement(Icon, {
20000
+ name: "circle-plus"
20001
+ }), texts.table3.editing.buttons.create.label)));
20002
+ }
20003
+
20004
+ function TemporaryRow(props) {
20005
+ var _tableRef$current, _tableRef$current2;
20006
+ const {
20007
+ createRowButtonRef,
20008
+ table,
20009
+ tableMeta,
20010
+ tableRef
20011
+ } = props;
20012
+ const isScrolled = tableRef.current ? ((_tableRef$current = tableRef.current) === null || _tableRef$current === void 0 ? void 0 : _tableRef$current.scrollHeight) > ((_tableRef$current2 = tableRef.current) === null || _tableRef$current2 === void 0 ? void 0 : _tableRef$current2.clientHeight) : false;
20013
+ const handleKeyDown = function (event) {
20014
+ try {
20015
+ const _temp2 = function () {
20016
+ if (event.key === 'ArrowDown') {
20017
+ event.preventDefault();
20018
+ const _temp = function () {
20019
+ if (!isElementTriggeredFromContainer(event.target, event.currentTarget)) {
20020
+ return Promise.resolve(tableMeta.editing.saveChanges(table)).then(function (saved) {
20021
+ if (saved) {
20022
+ var _createRowButtonRef$c;
20023
+ (_createRowButtonRef$c = createRowButtonRef.current) === null || _createRowButtonRef$c === void 0 ? void 0 : _createRowButtonRef$c.focus();
20024
+ }
20025
+ });
20026
+ }
20027
+ }();
20028
+ if (_temp && _temp.then) return _temp.then(function () {});
20029
+ } else if (event.key === 'ArrowUp') {
20030
+ event.preventDefault();
20031
+ event.stopPropagation();
20032
+ if (tableRef.current) {
20033
+ var _tableRef$current$que, _tableRef$current$que2, _tableRef$current$que3;
20034
+ 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 : []);
20035
+ 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;
20036
+ const newRowHeight = event.currentTarget.getBoundingClientRect().height;
20037
+ const visibleHeight = tableRef.current.clientHeight - footerHeight - newRowHeight;
20038
+ const tableTopOffset = tableRef.current.getBoundingClientRect().top;
20039
+ let nextRowIndex;
20040
+ // iterate available rows in reverse order, since we're working at the bottom
20041
+ for (let index = availableRows.length - 1; index >= 0; index--) {
20042
+ const rowRect = availableRows[index].getBoundingClientRect();
20043
+ const topPlusHalfRow = rowRect.top + rowRect.height / 2;
20044
+ if (topPlusHalfRow - tableTopOffset <= visibleHeight) {
20045
+ nextRowIndex = index;
20046
+ break;
20047
+ }
20048
+ }
20049
+ if (nextRowIndex) {
20050
+ tableMeta.rowActive.setRowActiveIndex(Number(availableRows[nextRowIndex < 0 ? 0 : nextRowIndex].getAttribute('data-row-index')));
20051
+ }
20052
+ }
20053
+ }
20054
+ }();
20055
+ return Promise.resolve(_temp2 && _temp2.then ? _temp2.then(function () {}) : void 0);
20056
+ } catch (e) {
20057
+ return Promise.reject(e);
20058
+ }
20059
+ };
20060
+ const handleKeyDownCapture = event => {
20061
+ if (event.key === 'ArrowLeft' && tableMeta.editing.lastFocusedCellIndex === 0) {
20062
+ event.preventDefault();
20063
+ event.stopPropagation();
20064
+ } else if (event.key === 'ArrowRight' && tableMeta.editing.lastFocusedCellIndex) {
20065
+ if (tableMeta.editing.lastFocusedCellIndex === table.getVisibleFlatColumns().length - 1) {
20066
+ event.preventDefault();
20067
+ event.stopPropagation();
20068
+ }
20069
+ }
20070
+ };
20071
+ const className = cn('group/row border-grey-300 !sticky z-[21]', {
20072
+ 'bottom-20': tableMeta.footer.isEnabled,
20073
+ 'bottom-10': !tableMeta.footer.isEnabled,
20074
+ 'border-b border-t shadow-[0px_-5px_20px_0px_rgba(0,0,0,0.1)] border-t-grey-500/[0.75]': isScrolled
20075
+ });
20076
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, table.getBottomRows().map(row => (/*#__PURE__*/React__default.createElement(Row, {
20077
+ key: row.id,
20078
+ cellRenderer: RENDERERS$1.cell,
20079
+ index: tableMeta.length,
20080
+ measureRow: () => null,
20081
+ renderer: RENDERERS$1.row,
20082
+ row: row,
20083
+ table: table,
20084
+ className: className,
20085
+ onKeyDown: handleKeyDown,
20086
+ onKeyDownCapture: handleKeyDownCapture
20087
+ }))));
20088
+ }
20089
+
19788
20090
  function Column$3(_) {
19789
20091
  return null;
19790
20092
  }
@@ -19800,8 +20102,18 @@ const BaseTable3 = /*#__PURE__*/fixedForwardRef(function BaseTable3(props, ref)
19800
20102
  '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,
19801
20103
  enableHorizontalArrowKeyNavigation: table3.meta.editing.isEditing
19802
20104
  };
19803
- const hasAlertErrors = table3.meta.editing.hasAlertErrors();
19804
- const showCreateRowButton = table3.meta.editing.isEnabled && props.onEditingCreate;
20105
+ const hasAlertErrors = table3.meta.editing.isEditing && table3.meta.editing.getErrorsShownInAlert().length;
20106
+ const hasCreateWorkflow = table3.meta.editing.isEnabled && props.onEditingCreate;
20107
+ let footerRows;
20108
+ if (hasCreateWorkflow) {
20109
+ footerRows = /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(CreateNewRow, {
20110
+ buttonRef: table3.meta.editing.createRowButtonRef,
20111
+ onEditingCreate: props.onEditingCreate,
20112
+ table: table3.instance,
20113
+ tableMeta: table3.meta,
20114
+ tableRef: table3.ref
20115
+ }));
20116
+ }
19805
20117
  return /*#__PURE__*/React__default.createElement(Table, null, /*#__PURE__*/React__default.createElement(Table.Toolbar, {
19806
20118
  table: table3
19807
20119
  }, table3.meta.editing.isEnabled ? (/*#__PURE__*/React__default.createElement(Editing, {
@@ -19814,13 +20126,14 @@ const BaseTable3 = /*#__PURE__*/fixedForwardRef(function BaseTable3(props, ref)
19814
20126
  tableRef: table3.ref
19815
20127
  })) : null, /*#__PURE__*/React__default.createElement(Table.Grid, Object.assign({}, gridAttributes, {
19816
20128
  "data-taco": "table3",
20129
+ rowsForFooter: footerRows,
19817
20130
  table: table3
19818
- }), showCreateRowButton && (/*#__PURE__*/React__default.createElement(CreateNewRowButton, {
20131
+ }), hasCreateWorkflow ? (/*#__PURE__*/React__default.createElement(TemporaryRow, {
20132
+ createRowButtonRef: table3.meta.editing.createRowButtonRef,
19819
20133
  table: table3.instance,
19820
20134
  tableMeta: table3.meta,
19821
- onEditingCreate: props.onEditingCreate,
19822
- scrollToIndex: table3.renderer.scrollToIndex
19823
- }))));
20135
+ tableRef: table3.ref
20136
+ })) : null));
19824
20137
  });
19825
20138
  const Table3 = /*#__PURE__*/fixedForwardRef(function Table3(props, ref) {
19826
20139
  const stringifiedChildren = String(props.children);