@economic/taco 2.44.3 → 2.44.5-create.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. package/dist/components/Provider/Localization.d.ts +2 -0
  2. package/dist/components/Report/Report.d.ts +1 -1
  3. package/dist/components/Table3/Table3.d.ts +2 -14
  4. package/dist/components/Table3/components/Columns/Internal/EditingActionsMenu.d.ts +1 -2
  5. package/dist/components/Table3/components/Editing/DiscardChangesConfirmationDialog.d.ts +7 -0
  6. package/dist/components/Table3/components/Row/Editing/CreateNewRow.d.ts +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 -0
  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/Option.js +0 -1
  55. package/dist/esm/packages/taco/src/primitives/Listbox2/components/Option.js.map +1 -1
  56. package/dist/esm/packages/taco/src/primitives/Listbox2/components/Root.js +1 -0
  57. package/dist/esm/packages/taco/src/primitives/Listbox2/components/Root.js.map +1 -1
  58. package/dist/esm/packages/taco/src/primitives/Table/Core/Table.js +3 -4
  59. package/dist/esm/packages/taco/src/primitives/Table/Core/Table.js.map +1 -1
  60. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Cell/BuiltIns/GroupedCell.js +9 -3
  61. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Cell/BuiltIns/GroupedCell.js.map +1 -1
  62. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Internal/Actions.js +6 -3
  63. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Internal/Actions.js.map +1 -1
  64. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Footer/Footer.js +1 -1
  65. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Footer/Footer.js.map +1 -1
  66. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/BuiltIns/DisplayRow.js +1 -1
  67. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/BuiltIns/DisplayRow.js.map +1 -1
  68. package/dist/esm/packages/taco/src/primitives/Table/Core/features/useTableRenderer.js +23 -6
  69. package/dist/esm/packages/taco/src/primitives/Table/Core/features/useTableRenderer.js.map +1 -1
  70. package/dist/esm/packages/taco/src/primitives/Table/Core/useTable.js +2 -2
  71. package/dist/esm/packages/taco/src/primitives/Table/Core/useTable.js.map +1 -1
  72. package/dist/esm/packages/taco/src/primitives/Table/types.js.map +1 -1
  73. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/useTableManager.js +1 -1
  74. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/useTableManager.js.map +1 -1
  75. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/util/setup.js +11 -0
  76. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/util/setup.js.map +1 -1
  77. package/dist/esm/packages/taco/src/utils/dom.js +7 -4
  78. package/dist/esm/packages/taco/src/utils/dom.js.map +1 -1
  79. package/dist/index.css +6 -2
  80. package/dist/primitives/Collection/components/Root.d.ts +2 -0
  81. package/dist/primitives/Table/Core/Table.d.ts +1 -0
  82. package/dist/primitives/Table/Core/components/Columns/Internal/Actions.d.ts +3 -1
  83. package/dist/primitives/Table/Core/components/Footer/Footer.d.ts +2 -2
  84. package/dist/primitives/Table/Core/features/useTableRenderer.d.ts +2 -2
  85. package/dist/primitives/Table/Core/features/useTableStyle.d.ts +1 -1
  86. package/dist/primitives/Table/Core/types.d.ts +3 -0
  87. package/dist/primitives/Table/Core/useTable.d.ts +2 -2
  88. package/dist/primitives/Table/types.d.ts +1 -1
  89. package/dist/primitives/Table/useTableManager/useTableManager.d.ts +1 -1
  90. package/dist/taco.cjs.development.js +941 -627
  91. package/dist/taco.cjs.development.js.map +1 -1
  92. package/dist/taco.cjs.production.min.js +1 -1
  93. package/dist/taco.cjs.production.min.js.map +1 -1
  94. package/dist/utils/dom.d.ts +1 -0
  95. package/package.json +3 -5
  96. package/dist/components/Table3/components/Row/Editing/CreateRowButton.d.ts +0 -11
  97. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateRowButton.js +0 -90
  98. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateRowButton.js.map +0 -1
@@ -43,7 +43,8 @@ var set = _interopDefault(require('lodash/set'));
43
43
  var unset = _interopDefault(require('lodash/unset'));
44
44
  var compact = _interopDefault(require('lodash/compact'));
45
45
  var pullAt = _interopDefault(require('lodash/pullAt'));
46
- var lodash = require('lodash');
46
+ var omit = _interopDefault(require('lodash/omit'));
47
+ var setWith = _interopDefault(require('lodash/setWith'));
47
48
  var TabsPrimitive = require('@radix-ui/react-tabs');
48
49
  var Joyride = require('react-joyride');
49
50
  var Joyride__default = _interopDefault(Joyride);
@@ -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,14 +14460,31 @@ 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);
14422
14481
  if (options.length) {
14423
14482
  let selected = internalRef.current.querySelectorAll(`[aria-current="true"]`);
14483
+ // if nothing is current (keyboard visible), look for selected items
14424
14484
  if (selected.length === 0) {
14425
14485
  selected = internalRef.current.querySelectorAll(`[aria-selected]`);
14426
14486
  }
14487
+ // if one item is selected, make sure it's current
14427
14488
  if (selected.length === 1) {
14428
14489
  if (options) {
14429
14490
  const firstSelected = selected.item(0);
@@ -14569,6 +14630,7 @@ const Root$1 = /*#__PURE__*/React__default.forwardRef(function Listbox2(props, r
14569
14630
  id: id,
14570
14631
  querySelector: customSelector ? `${DEFAULT_SELECTOR}, ${customSelector}` : DEFAULT_SELECTOR,
14571
14632
  ref: ref,
14633
+ resetOnChange: value,
14572
14634
  role: "listbox"
14573
14635
  }), children)));
14574
14636
  });
@@ -14641,7 +14703,6 @@ const Option = /*#__PURE__*/React__default.forwardRef(function Listbox2Option(pr
14641
14703
  return /*#__PURE__*/React__default.createElement("div", Object.assign({}, otherProps, {
14642
14704
  "aria-disabled": listboxDisabled || disabled ? 'true' : undefined,
14643
14705
  "aria-selected": selected ? 'true' : undefined,
14644
- key: `${value}_${String(selected)}`,
14645
14706
  id: id,
14646
14707
  onClick: handleClick,
14647
14708
  onKeyDown: handleKeyDown,
@@ -16754,6 +16815,7 @@ function TableGrid(props) {
16754
16815
  var _table$state$grouping;
16755
16816
  const {
16756
16817
  enableHorizontalArrowKeyNavigation,
16818
+ rowsForFooter,
16757
16819
  table,
16758
16820
  ...attributes
16759
16821
  } = props;
@@ -16761,8 +16823,6 @@ function TableGrid(props) {
16761
16823
  table.meta.rowActive.handleFocus(event, table.meta.length, table.renderer.scrollToIndex);
16762
16824
  } : undefined;
16763
16825
  const filterReason = getFilterReason(table);
16764
- const searchNotApplied = !table.state.globalFilter || table.state.globalFilter === '';
16765
- const filtersNotApplied = !table.state.columnFilters || table.state.columnFilters.length === 0;
16766
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, {
16767
16827
  id: table.id,
16768
16828
  "data-table-font-size": table.meta.fontSize.size,
@@ -16795,9 +16855,9 @@ function TableGrid(props) {
16795
16855
  ...table.renderer.style,
16796
16856
  height: table.renderer.style.height + ROW_HEIGHT_ESTIMATES[table.meta.rowHeight.height]
16797
16857
  } : table.renderer.style
16798
- }, 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, {
16799
16859
  table: table.instance
16800
- }) : null)))));
16860
+ }, rowsForFooter) : null)))));
16801
16861
  }
16802
16862
 
16803
16863
  function Column$1(_) {
@@ -18300,33 +18360,16 @@ const useTableRowCreation = (data, tableRef) => {
18300
18360
 
18301
18361
  function useTableEditingListener(table, tableRef) {
18302
18362
  const tableMeta = table.options.meta;
18303
- const completedRowsCount = tableMeta.editing.getCompletedRowsCount();
18304
18363
  const localization = useLocalization();
18305
- const saveChanges = () => {
18306
- requestAnimationFrame(() => {
18307
- tableMeta.editing.saveChanges();
18308
- });
18309
- };
18310
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);
18311
18367
  useLazyEffect(() => {
18312
- if (tableMeta.editing.isEditing) {
18313
- saveChanges();
18314
- }
18315
- }, [tableMeta.rowActive.rowActiveIndex]);
18316
- useLazyEffect(() => {
18317
- if (tableMeta.editing.isEditing) {
18318
- if (tableMeta.rowActive.rowActiveIndex === undefined) {
18319
- tableMeta.rowActive.setRowActiveIndex(0);
18320
- }
18321
- } else {
18322
- // save
18323
- saveChanges();
18324
- // reset detailed mode
18325
- tableMeta.editing.toggleDetailedMode(false);
18326
- // reset the last index back to the first focusable element, when editing gets turned off
18327
- 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);
18328
18371
  }
18329
- }, [tableMeta.editing.isEditing]);
18372
+ }, [tableMeta.rowActive.rowActiveIndex, tableMeta.editing.saveChanges]);
18330
18373
  // show a warning if the user navigates away without triggering save, such as using the browser back/forward button
18331
18374
  const hasChanges = tableMeta.editing.hasChanges();
18332
18375
  React__default.useEffect(() => {
@@ -18342,25 +18385,46 @@ function useTableEditingListener(table, tableRef) {
18342
18385
  window.removeEventListener('beforeunload', showUnsavedChangesWarning);
18343
18386
  };
18344
18387
  }, [tableMeta.editing.isEditing, hasChanges]);
18345
- React__default.useEffect(() => {
18346
- if (completedRowsCount > 0) {
18388
+ const hasSavedChanges = tableMeta.editing.hasSaved();
18389
+ useLazyEffect(() => {
18390
+ if (hasSavedChanges) {
18347
18391
  resetHighlightedColumnIndexes(table.getState().globalFilter, table, localization);
18348
18392
  }
18349
- }, [completedRowsCount]);
18393
+ }, [hasSavedChanges]);
18350
18394
  React__default.useEffect(() => {
18351
18395
  const onClickOutside = event => {
18352
18396
  if (tableMeta.editing.isEditing) {
18353
- var _event$target$getAttr, _event$target;
18354
- 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 : '';
18355
- const insideTable = isElementInsideOrTriggeredFromContainer(event.target, tableRef.current) || element === 'backdrop';
18356
- if (!insideTable) {
18357
- 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);
18358
18402
  }
18359
18403
  }
18360
18404
  };
18361
18405
  document.addEventListener('click', onClickOutside);
18362
18406
  return () => document.removeEventListener('click', onClickOutside);
18363
- }, [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
+ });
18364
18428
  }
18365
18429
 
18366
18430
  function willRowMove(cell, change, rowIndex, localization) {
@@ -18430,6 +18494,8 @@ function willRowMoveAfterSorting(cell, change, rowIndex) {
18430
18494
  const aUndefined = aValue === undefined;
18431
18495
  const bUndefined = bValue === undefined;
18432
18496
  if (aUndefined || bUndefined) {
18497
+ if (sortUndefined === 'first') return aUndefined ? -1 : 1;
18498
+ if (sortUndefined === 'last') return aUndefined ? 1 : -1;
18433
18499
  return aUndefined && bUndefined ? 0 : aUndefined ? sortUndefined : -sortUndefined;
18434
18500
  }
18435
18501
  }
@@ -18440,444 +18506,544 @@ function willRowMoveAfterSorting(cell, change, rowIndex) {
18440
18506
  }
18441
18507
  return ((_resortedRows$index = resortedRows[index]) === null || _resortedRows$index === void 0 ? void 0 : _resortedRows$index.id) !== cell.row.id;
18442
18508
  }
18443
- function animateCreateRow(id) {
18444
- const templateRow = document.querySelector(`[data-row-id="${id}"]`);
18445
- if (templateRow) {
18446
- const firstCell = templateRow.querySelector(':first-child');
18447
- const checkbox = firstCell === null || firstCell === void 0 ? void 0 : firstCell.querySelector('[data-taco="checkbox"]');
18448
- firstCell === null || firstCell === void 0 ? void 0 : firstCell.focus();
18449
- if (checkbox) {
18450
- setDataFocusAttribute(checkbox);
18451
- }
18452
- templateRow.scrollIntoView();
18453
- const keyframes = [{
18454
- background: '#b2c7ef'
18455
- }, {
18456
- background: '#ebebeb'
18457
- }];
18458
- for (const child of templateRow.children) {
18459
- child.animate(keyframes, {
18460
- duration: 1000,
18461
- easing: 'ease-out'
18462
- });
18463
- }
18464
- }
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);
18465
18512
  }
18466
18513
 
18467
- function useTableEditing(isEnabled = false, handleSave, handleChange, validator) {
18468
- // used to switch the table into editing mode
18469
- const [isEditing, toggleEditing] = React__default.useState(false);
18470
- // used to switch the editing between "detailed" mode
18471
- const [isDetailedMode, toggleDetailedMode] = React__default.useState(false);
18472
- // store the last focused cell, so that up/down arrow key navigation remains in the same column
18473
- const [lastFocusedCellIndex, setLastFocusedCellIndex] = useLastFocusedCellIndex();
18474
- // store pending changes for each row
18475
- // changes are saved as soon as the active row changes, so in most cases this will only contain the active row's changes
18476
- // but not always - if validation or server requests fail when saving, those rows remain until the failure is resolved
18477
- const pendingChangesFns = usePendingChanges(isEnabled, handleSave, handleChange, validator);
18478
- useGlobalKeyDown(isEnabled && isEditing ? {
18479
- key: 's',
18480
- meta: true,
18481
- shift: false
18482
- } : undefined, event => {
18483
- event.preventDefault();
18484
- pendingChangesFns.saveChanges();
18485
- });
18486
- return {
18487
- isEnabled,
18488
- isEditing,
18489
- isDetailedMode,
18490
- toggleDetailedMode: isEnabled ? toggleDetailedMode : () => undefined,
18491
- toggleEditing: isEnabled ? toggleEditing : () => undefined,
18492
- lastFocusedCellIndex,
18493
- setLastFocusedCellIndex,
18494
- ...pendingChangesFns
18495
- };
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
+ }
18496
18648
  }
18497
- function usePendingChanges(isEnabled, handleSave, handleChange, validator) {
18498
- const saveChanges = function (rowId = undefined) {
18649
+ function usePendingChangesState(handleSave, handleChange, rowIdentityAccessor, validator) {
18650
+ const saveChanges = function (table, rowId = undefined) {
18499
18651
  try {
18500
18652
  let _exit = false;
18501
18653
  if (!handleSave) {
18502
18654
  console.warn('Tried to save, but Table has no onEditingSave handler');
18503
- return Promise.resolve();
18655
+ return Promise.resolve(false);
18504
18656
  }
18505
- // we save back to pendingChanges, so make a copy of it's state when save was triggered
18506
- const changesToSave = rowId ? {
18507
- [rowId]: pendingChanges[rowId]
18508
- } : {
18509
- ...pendingChanges
18510
- };
18511
- const changes = Object.keys(changesToSave);
18512
- return Promise.resolve(function () {
18513
- if (changes.length) {
18514
- return _forOf(changes, function (rowId) {
18515
- const pendingChange = changesToSave[rowId];
18516
- const changeSet = getChangesetFromChanges(pendingChange);
18517
- return _catch(function () {
18518
- function _temp3(_result) {
18519
- return _exit ? _result : Promise.resolve(handleSave(changeSet)).then(function () {
18520
- // cleanup changes, we don't need them after saving
18521
- resetChanges(rowId);
18522
- setRowSaveStatus(rowId, 'complete');
18523
- });
18524
- }
18525
- if (getRowSaveStatus(rowId) === 'pending') {
18526
- _exit = true;
18527
- return;
18528
- }
18529
- // set saving = true
18530
- setRowSaveStatus(rowId, 'pending');
18531
- // re-run validation, maybe a cell is already invalid but has never been blurred
18532
- const _temp2 = function () {
18533
- if (validator) {
18534
- return Promise.resolve(validator(changeSet)).then(function (errors) {
18535
- if (errors && Object.keys(errors).length) {
18536
- throw errors;
18537
- }
18538
- });
18539
- }
18540
- }();
18541
- return _temp2 && _temp2.then ? _temp2.then(_temp3) : _temp3(_temp2); // send new data to the server
18542
- }, function (error) {
18543
- // the onEditingSave handler should throw errors when something fails, e.g. validation, network errors etc
18544
- // this code handles those errors and maps them either to row errors or cell specific errors
18545
- let rowError;
18546
- let cellErrors;
18547
- if (typeof error === 'string') {
18548
- rowError = error;
18549
- } else if (error instanceof Error) {
18550
- var _error$response;
18551
- rowError = error.message;
18552
- // most of our apis return error objects within this shape
18553
- if (typeof ((_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.data) === 'object') {
18554
- var _error$response2;
18555
- 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;
18556
18695
  }
18557
- } else if (typeof error === 'object') {
18558
- cellErrors = error;
18559
- }
18560
- if (rowError || cellErrors) {
18561
- setPendingChanges(currentChanges => {
18562
- const nextChanges = {
18563
- ...currentChanges
18564
- };
18565
- nextChanges[rowId]._meta.errors = {
18566
- row: rowError,
18567
- cells: cellErrors,
18568
- shouldShowErrorAlert: true
18569
- };
18570
- return nextChanges;
18571
- });
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
18572
18730
  }
18573
- setRowSaveStatus(rowId, undefined);
18574
18731
  });
18575
- }, function () {
18576
- return _exit;
18577
- });
18578
- }
18579
- }());
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);
18580
18742
  } catch (e) {
18581
18743
  return Promise.reject(e);
18582
18744
  }
18583
18745
  };
18584
- const validateCell = function (cell) {
18746
+ const onCellChanged = function (cell, rowIndex) {
18585
18747
  try {
18586
- if (!validator || !isEnabled) {
18587
- return Promise.resolve();
18588
- }
18589
- const changeSet = getChangesetFromChanges(pendingChanges[cell.row.id]);
18590
- // only validate if the cell being blurred actually has any changes
18591
- const _temp = function () {
18592
- if (cell.column.id in changeSet) {
18593
- return Promise.resolve(validator(changeSet)).then(function (errors) {
18594
- setPendingChanges(currentChanges => {
18595
- const nextChanges = {
18596
- ...currentChanges
18597
- };
18598
- nextChanges[cell.row.id]._meta = {
18599
- ...nextChanges[cell.row.id]._meta,
18600
- errors: {
18601
- ...nextChanges[cell.row.id]._meta.errors,
18602
- cells: errors,
18603
- 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];
18604
18772
  }
18605
- };
18606
- 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 : {};
18607
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 : {};
18608
18830
  });
18609
18831
  }
18610
18832
  }();
18611
- return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
18833
+ return Promise.resolve(_temp5 && _temp5.then ? _temp5.then(_temp6) : _temp6(_temp5));
18612
18834
  } catch (e) {
18613
18835
  return Promise.reject(e);
18614
18836
  }
18615
- };
18616
- const setCellValue = function (cell, change, rowIndex) {
18837
+ }; // general
18838
+ const createRow = function (data) {
18617
18839
  try {
18618
- const changes = {
18619
- [cell.column.id]: change
18840
+ const newRowId = `${TEMPORARY_ROW_ID_PREFIX}${uuid.v4()}`;
18841
+ const value = {
18842
+ ...data,
18843
+ [rowIdentityAccessor]: newRowId
18620
18844
  };
18621
- setPendingChanges(currentChanges => {
18622
- const nextChanges = createPendingChangesSetter(currentChanges, cell.row, rowIndex, changes, localization);
18623
- pendingChangesUpdater.syncCellChanges(nextChanges);
18624
- return nextChanges;
18845
+ dispatch({
18846
+ type: 'createRow',
18847
+ rowId: newRowId,
18848
+ payload: {
18849
+ value
18850
+ }
18625
18851
  });
18626
- pendingChangesUpdater.runCellUpdates(changes, cell, rowIndex);
18627
- return Promise.resolve();
18852
+ return Promise.resolve(newRowId);
18628
18853
  } catch (e) {
18629
18854
  return Promise.reject(e);
18630
18855
  }
18631
- };
18632
- const addCreatedRowChangeset = function (row) {
18856
+ }; // cells
18857
+ // rows
18858
+ const setRowValue = function (rowId, original, value) {
18633
18859
  try {
18634
- const cells = row.getAllCells();
18635
- setPendingChanges(currentChanges => {
18636
- return cells.reduce((changes, cell) => {
18637
- if (cell.getValue()) {
18638
- var _currentChanges$cell$, _currentChanges$cell$2, _currentChanges$cell$3;
18639
- return {
18640
- ...changes,
18641
- [cell.row.id]: {
18642
- ...changes[cell.row.id],
18643
- [cell.column.id]: cell.getValue(),
18644
- _meta: {
18645
- ...((_currentChanges$cell$ = currentChanges[cell.row.id]) === null || _currentChanges$cell$ === void 0 ? void 0 : _currentChanges$cell$._meta),
18646
- original: cell.row.original,
18647
- moveReason: {
18648
- ...((_currentChanges$cell$2 = currentChanges[cell.row.id]) === null || _currentChanges$cell$2 === void 0 ? void 0 : _currentChanges$cell$2._meta.moveReason)
18649
- },
18650
- errors: {
18651
- ...((_currentChanges$cell$3 = currentChanges[cell.row.id]) === null || _currentChanges$cell$3 === void 0 ? void 0 : _currentChanges$cell$3._meta.errors)
18652
- }
18653
- }
18654
- }
18655
- };
18656
- } else {
18657
- return changes;
18860
+ function _temp2() {
18861
+ dispatch({
18862
+ type: 'updateRow',
18863
+ rowId,
18864
+ payload: {
18865
+ cellErrors,
18866
+ original,
18867
+ value
18658
18868
  }
18659
- }, currentChanges);
18660
- });
18661
- 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));
18662
18884
  } catch (e) {
18663
18885
  return Promise.reject(e);
18664
18886
  }
18665
18887
  };
18666
18888
  const localization = useLocalization();
18667
- const [pendingChanges, setPendingChanges] = React__default.useState({});
18668
- // we maintain save status as separate state because 'complete' needs to briefly show after pendingChanges are deleted
18669
- const [saveStates, setSaveState] = React__default.useState({});
18670
- function getCellValue(cell) {
18671
- var _pendingChanges$cell$;
18672
- 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;
18673
18902
  }
18674
- function getCellError(cell) {
18675
- var _pendingChanges$cell$2, _pendingChanges$cell$3, _pendingChanges$cell$4;
18676
- 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;
18677
18906
  }
18678
- const pendingChangesUpdater = usePendingChangesUpdater(handleChange, setPendingChanges);
18679
18907
  function hasRowErrors(rowId) {
18680
- var _pendingChanges$rowId, _pendingChanges$rowId2, _pendingChanges$rowId3, _pendingChanges$rowId4, _pendingChanges$rowId5;
18681
- if (!isEnabled) {
18682
- return false;
18683
- }
18684
- 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;
18685
18910
  }
18686
- function hasRowErrorsSeen(rowId) {
18687
- var _pendingChanges$rowId6;
18688
- if (!isEnabled) {
18689
- return false;
18690
- }
18691
- return hasRowErrors(rowId) && !!((_pendingChanges$rowId6 = pendingChanges[rowId]._meta.errors) !== null && _pendingChanges$rowId6 !== void 0 && _pendingChanges$rowId6.shouldShowErrorAlert);
18692
- }
18693
- function getRowPendingChange(rowId) {
18694
- const rowPendingChanges = pendingChanges[rowId];
18695
- if (rowPendingChanges) {
18696
- const {
18697
- _meta,
18698
- ...pendingChange
18699
- } = rowPendingChanges;
18700
- return pendingChange;
18701
- }
18702
- 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);
18703
18914
  }
18704
- function getRowSaveStatus(rowId) {
18705
- if (!isEnabled) {
18706
- return false;
18707
- }
18708
- return saveStates[rowId];
18915
+ function getRowStatus(rowId) {
18916
+ return state.changes.status[rowId];
18709
18917
  }
18710
- function setRowSaveStatus(rowId, status) {
18711
- setSaveState(currentStates => {
18712
- const nextStates = {
18713
- ...currentStates
18714
- };
18715
- if (status) {
18716
- nextStates[rowId] = status;
18717
- } else {
18718
- delete nextStates[rowId];
18918
+ function setRowStatus(rowId, status) {
18919
+ dispatch({
18920
+ type: 'setRowStatus',
18921
+ rowId,
18922
+ payload: {
18923
+ status
18719
18924
  }
18720
- return nextStates;
18721
18925
  });
18722
18926
  }
18723
- function getRowMoveReason(rowId) {
18724
- var _pendingChanges$rowId7;
18725
- return (_pendingChanges$rowId7 = pendingChanges[rowId]) !== null && _pendingChanges$rowId7 !== void 0 && _pendingChanges$rowId7._meta.moveReason ? Object.values(pendingChanges[rowId]._meta.moveReason)[0] : undefined;
18726
- }
18727
- function hasChanges(rowId) {
18728
- if (!isEnabled) {
18729
- 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
+ });
18730
18941
  }
18731
- return rowId ? !!pendingChanges[rowId] : !!Object.keys(pendingChanges).length;
18732
- }
18733
- function hasAlertErrors() {
18734
- if (!isEnabled) {
18735
- 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
+ });
18736
18952
  }
18737
- return !!getAlertErrors().length;
18738
18953
  }
18739
- function getAlertErrors() {
18740
- 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 => ({
18741
18968
  rowId,
18742
- pendingChange: pendingChanges[rowId]
18969
+ changes: state.changes.rows[rowId],
18970
+ errors: state.changes.errors[rowId]
18743
18971
  }));
18744
18972
  }
18745
- function resetChanges(rowId) {
18746
- setPendingChanges(currentChanges => {
18747
- const nextChanges = {
18748
- ...currentChanges
18749
- };
18750
- delete nextChanges[rowId];
18751
- return nextChanges;
18752
- });
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;
18753
18978
  }
18754
- function getCompletedRowsCount() {
18755
- 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
+ });
18756
18989
  }
18757
18990
  return {
18991
+ // row
18992
+ setRowValue,
18993
+ getRowValue,
18994
+ getRowMoveReason,
18995
+ hasRowErrors,
18996
+ hasRowErrorsShownInAlert,
18997
+ getRowStatus,
18998
+ setRowStatus,
18999
+ // cells
19000
+ setCellValue,
18758
19001
  getCellValue,
18759
19002
  getCellError,
18760
- setCellValue,
18761
- validateCell,
18762
- addCreatedRowChangeset,
19003
+ onCellChanged,
19004
+ // general
19005
+ getErrorsShownInAlert,
18763
19006
  hasChanges,
18764
- hasAlertErrors,
18765
- getAlertErrors,
18766
19007
  saveChanges,
18767
- resetChanges,
18768
- hasRowErrors,
18769
- hasRowErrorsSeen,
18770
- getRowPendingChange,
18771
- getRowSaveStatus,
18772
- setRowSaveStatus,
18773
- getRowMoveReason,
18774
- getCompletedRowsCount
19008
+ discardChanges,
19009
+ hasSaved,
19010
+ // new rows
19011
+ createRow,
19012
+ temporaryRows: state.temporaryRows
18775
19013
  };
18776
19014
  }
18777
- 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);
18778
19023
  // store the last focused cell, so that up/down arrow key navigation remains in the same column
18779
- const lastFocusedCellIndexRef = React__default.useRef(undefined);
18780
- const setLastFocusedCellIndex = React__default.useCallback(index => {
18781
- lastFocusedCellIndexRef.current = index;
18782
- }, []);
18783
- return [lastFocusedCellIndexRef.current, setLastFocusedCellIndex];
18784
- }
18785
- function usePendingChangesUpdater(handleChange, setPendingChanges) {
18786
- const localization = useLocalization();
18787
- const updatersRef = React__default.useRef({});
18788
- const runCellUpdates = React__default.useCallback(lodash.debounce(function (changes, cell, rowIndex) {
18789
- try {
18790
- const _temp4 = function () {
18791
- if (typeof handleChange === 'function') {
18792
- const previousValues = {
18793
- ...cell.row.original,
18794
- ...getChangesetFromChanges(updatersRef.current[cell.row.id])
18795
- };
18796
- const nextValues = {
18797
- ...previousValues,
18798
- ...changes
18799
- };
18800
- return Promise.resolve(handleChange(cell.column.id, changes[cell.column.id], nextValues, previousValues)).then(function (updates) {
18801
- if (updates && Object.keys(updates).length) {
18802
- setPendingChanges(currentChanges => createPendingChangesSetter(currentChanges, cell.row, rowIndex, updates, localization));
18803
- }
18804
- });
18805
- }
18806
- }();
18807
- return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(function () {}) : void 0);
18808
- } catch (e) {
18809
- 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);
18810
19034
  }
18811
- }, 250), []);
18812
- function syncCellChanges(changes) {
18813
- updatersRef.current = changes;
19035
+ setEditing(enabled);
18814
19036
  }
18815
19037
  return {
18816
- syncCellChanges,
18817
- runCellUpdates
18818
- };
18819
- }
18820
- function createPendingChangesSetter(currentChanges, row, rowIndex, changes, localization) {
18821
- var _currentChanges$row$i, _currentChanges$row$i2, _currentChanges$row$i3;
18822
- // prepare
18823
- const nextChanges = {
18824
- ...currentChanges
18825
- };
18826
- const rowChanges = {
18827
- ...currentChanges[row.id],
18828
- _meta: {
18829
- ...((_currentChanges$row$i = currentChanges[row.id]) === null || _currentChanges$row$i === void 0 ? void 0 : _currentChanges$row$i._meta),
18830
- original: row.original,
18831
- moveReason: {
18832
- ...((_currentChanges$row$i2 = currentChanges[row.id]) === null || _currentChanges$row$i2 === void 0 ? void 0 : _currentChanges$row$i2._meta.moveReason)
18833
- },
18834
- errors: {
18835
- ...((_currentChanges$row$i3 = currentChanges[row.id]) === null || _currentChanges$row$i3 === void 0 ? void 0 : _currentChanges$row$i3._meta.errors)
18836
- }
18837
- }
18838
- };
18839
- // run changes
18840
- const cells = row._getAllCellsByColumnId();
18841
- for (const [accessor, change] of Object.entries(changes)) {
18842
- // update if the change is different to the original (saved) value,
18843
- // otherwise remove any change - no point saving the same value
18844
- if (change !== row.original[accessor]) {
18845
- rowChanges[accessor] = change;
18846
- // consumers sometimes include properties in onEditingChange that aren't rendered as columns, we need to guard against that.
18847
- // eslint-disable-next-line no-prototype-builtins
18848
- if (cells.hasOwnProperty(accessor)) {
18849
- // determine if the row will move position based on this change, and save why it will move
18850
- const reason = willRowMove(cells[accessor], change, rowIndex, localization);
18851
- if (reason) {
18852
- rowChanges._meta.moveReason[accessor] = reason;
18853
- } else {
18854
- delete rowChanges._meta.moveReason[accessor];
18855
- }
18856
- }
18857
- } else {
18858
- delete rowChanges[accessor];
18859
- delete rowChanges._meta.moveReason[accessor];
18860
- }
18861
- }
18862
- // set changes
18863
- // or delete if there are no changes left, so that we don't store changes with unchanged data
18864
- if (Object.keys(rowChanges).filter(k => k !== '_meta').length) {
18865
- nextChanges[row.id] = rowChanges;
18866
- } else {
18867
- delete nextChanges[row.id];
18868
- }
18869
- return nextChanges;
18870
- }
18871
- function getChangesetFromChanges(changes) {
18872
- // extract the original data from the row changes
18873
- const {
18874
- _meta,
18875
- ...changeset
18876
- } = changes !== null && changes !== void 0 ? changes : {};
18877
- // and mix them in with the changes, ready to send to the server
18878
- return {
18879
- ...(_meta === null || _meta === void 0 ? void 0 : _meta.original),
18880
- ...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
18881
19047
  };
18882
19048
  }
18883
19049
 
@@ -19119,13 +19285,28 @@ function EditingControlCell(props) {
19119
19285
  const {
19120
19286
  rowIndex
19121
19287
  } = React__default.useContext(RowContext);
19122
- const tableMeta = cell.getContext().table.options.meta;
19288
+ const {
19289
+ table
19290
+ } = cell.getContext();
19291
+ const tableMeta = table.options.meta;
19123
19292
  const columnMeta = cell.column.columnDef.meta;
19124
19293
  const isActiveRow = tableMeta.rowActive.rowActiveIndex === rowIndex;
19294
+ const type = (_columnMeta$control = columnMeta.control) !== null && _columnMeta$control !== void 0 ? _columnMeta$control : 'input';
19125
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
+ };
19126
19307
  const handleBlur = () => {
19127
19308
  tableMeta.editing.toggleDetailedMode(false);
19128
- tableMeta.editing.validateCell(cell);
19309
+ tableMeta.editing.onCellChanged(cell, rowIndex);
19129
19310
  };
19130
19311
  // ensure that blur runs when the cell gets unmounted (when vertically arrow key navigating)
19131
19312
  React__default.useEffect(() => {
@@ -19145,13 +19326,12 @@ function EditingControlCell(props) {
19145
19326
  isDetailedMode: tableMeta.editing.isDetailedMode,
19146
19327
  isTruncated: !!columnMeta.enableTruncate,
19147
19328
  onBlur: handleBlur,
19148
- onChange: value => tableMeta.editing.setCellValue(cell, value, rowIndex),
19329
+ onChange: handleChange,
19149
19330
  row: cell.row.original,
19150
- rowPendingChanges: tableMeta.editing.getRowPendingChange(cell.row.id),
19331
+ rowPendingChanges: tableMeta.editing.getRowValue(cell.row.id),
19151
19332
  tabIndex: isActiveRow ? 0 : -1,
19152
- toggleEditing: tableMeta.editing.toggleEditing,
19153
19333
  toggleDetailedMode: tableMeta.editing.toggleDetailedMode,
19154
- type: (_columnMeta$control = columnMeta.control) !== null && _columnMeta$control !== void 0 ? _columnMeta$control : 'input',
19334
+ type,
19155
19335
  value: cell.getValue()
19156
19336
  };
19157
19337
  const cellAttributes = {
@@ -19184,7 +19364,6 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19184
19364
  row,
19185
19365
  rowPendingChanges,
19186
19366
  tabIndex = -1,
19187
- toggleEditing,
19188
19367
  toggleDetailedMode,
19189
19368
  type = 'input',
19190
19369
  value
@@ -19243,8 +19422,8 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19243
19422
  }
19244
19423
  // reset the value, or exit edit mode when pressing escape
19245
19424
  if (event.key === 'Escape') {
19246
- event.preventDefault();
19247
19425
  if (isDetailedMode) {
19426
+ event.preventDefault();
19248
19427
  toggleDetailedMode(false);
19249
19428
  if (value !== currentValue) {
19250
19429
  props.onChange(currentValue);
@@ -19254,8 +19433,6 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19254
19433
  var _target$select2;
19255
19434
  return (_target$select2 = target.select) === null || _target$select2 === void 0 ? void 0 : _target$select2.call(target);
19256
19435
  });
19257
- } else {
19258
- toggleEditing(false);
19259
19436
  }
19260
19437
  return;
19261
19438
  }
@@ -19354,12 +19531,37 @@ function Cell$5(props) {
19354
19531
  return /*#__PURE__*/React__default.createElement(DisplayCell, Object.assign({}, props));
19355
19532
  }
19356
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
+
19357
19560
  function EditingActionMenu(props) {
19358
19561
  const {
19359
19562
  hasChanges,
19360
19563
  hasErrors,
19361
- onClear: handleClear,
19362
- onExit: handleExit,
19564
+ onDiscard: handleDiscard,
19363
19565
  onEditingSave: handleSave,
19364
19566
  isLastRow
19365
19567
  } = props;
@@ -19381,7 +19583,6 @@ function EditingActionMenu(props) {
19381
19583
  return /*#__PURE__*/React__default.createElement(IconButton, {
19382
19584
  appearance: "transparent",
19383
19585
  "aria-label": texts.table3.editing.actions.tooltip,
19384
- className: "group-[[data-row-editing-status]]/row:hidden",
19385
19586
  icon: "more",
19386
19587
  onKeyDown: handleKeyDown,
19387
19588
  menu: menuProps => (/*#__PURE__*/React__default.createElement(Menu$1, Object.assign({}, menuProps), /*#__PURE__*/React__default.createElement(Menu$1.Content, {
@@ -19393,42 +19594,13 @@ function EditingActionMenu(props) {
19393
19594
  }, texts.table3.editing.actions.save), /*#__PURE__*/React__default.createElement(Menu$1.Item, {
19394
19595
  icon: "close",
19395
19596
  disabled: !hasChanges,
19396
- dialog: props => /*#__PURE__*/React__default.createElement(ConfirmClearChangesDialog, Object.assign({}, props, {
19397
- onClear: handleClear
19597
+ dialog: props => /*#__PURE__*/React__default.createElement(DiscardChangesConfirmationDialog, Object.assign({}, props, {
19598
+ onDiscard: handleDiscard
19398
19599
  }))
19399
- }, texts.table3.editing.actions.clear), /*#__PURE__*/React__default.createElement(Menu$1.Item, {
19400
- icon: "undo",
19401
- onClick: handleExit
19402
- }, texts.table3.editing.actions.exit))))
19600
+ }, texts.table3.editing.actions.clear))))
19403
19601
  });
19404
19602
  }
19405
- function ConfirmClearChangesDialog(props) {
19406
- const {
19407
- onClear: handleClear,
19408
- ...dialogProps
19409
- } = props;
19410
- const {
19411
- texts
19412
- } = useLocalization();
19413
- const handleClickInsideDialogContent = event => {
19414
- // Prevents the click event from propagating to the table, ensuring the row isn't saved when a click occurs
19415
- // inside the dialog
19416
- event.stopPropagation();
19417
- };
19418
- return /*#__PURE__*/React__default.createElement(Dialog, Object.assign({}, dialogProps), /*#__PURE__*/React__default.createElement(Dialog.Content, {
19419
- "aria-label": texts.table3.editing.clearChangesConfirmationDialog.title,
19420
- onClick: handleClickInsideDialogContent
19421
- }, /*#__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, {
19422
- tabIndex: 0
19423
- }, texts.table3.editing.clearChangesConfirmationDialog.cancel)), /*#__PURE__*/React__default.createElement(Dialog.Close, null, /*#__PURE__*/React__default.createElement(Button$1, {
19424
- autoFocus: true,
19425
- tabIndex: 0,
19426
- appearance: "primary",
19427
- onClick: handleClear
19428
- }, texts.table3.editing.clearChangesConfirmationDialog.confirm))))));
19429
- }
19430
19603
 
19431
- const COMPLETE_INDICATOR_DELAY = 3000;
19432
19604
  function SaveStatus(props) {
19433
19605
  const {
19434
19606
  rowId,
@@ -19438,18 +19610,7 @@ function SaveStatus(props) {
19438
19610
  texts
19439
19611
  } = useLocalization();
19440
19612
  const tableMeta = table.options.meta;
19441
- const status = tableMeta.editing.getRowSaveStatus(rowId);
19442
- React__default.useEffect(() => {
19443
- let timeout;
19444
- if (status === 'complete') {
19445
- timeout = setTimeout(() => {
19446
- tableMeta.editing.setRowSaveStatus(rowId, undefined);
19447
- }, COMPLETE_INDICATOR_DELAY);
19448
- }
19449
- return () => {
19450
- clearTimeout(timeout);
19451
- };
19452
- }, [status]);
19613
+ const status = tableMeta.editing.getRowStatus(rowId);
19453
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)]', {
19454
19615
  'mt-0.5': tableMeta.rowHeight.height === 'short',
19455
19616
  'mt-1': tableMeta.rowHeight.height === 'medium',
@@ -19460,7 +19621,7 @@ function SaveStatus(props) {
19460
19621
  className: "!contents"
19461
19622
  }, /*#__PURE__*/React__default.createElement("span", {
19462
19623
  className: className
19463
- }, status === 'pending' ? (/*#__PURE__*/React__default.createElement(Tooltip, {
19624
+ }, status === 'saving' ? (/*#__PURE__*/React__default.createElement(Tooltip, {
19464
19625
  title: texts.table3.editing.saving.progress
19465
19626
  }, /*#__PURE__*/React__default.createElement(Spinner, {
19466
19627
  delay: 0,
@@ -19498,15 +19659,46 @@ function Row$2(props) {
19498
19659
  }
19499
19660
  }
19500
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
+ }
19501
19688
  const attributes = {
19502
- 'data-row-editing-invalid': tableMeta.editing.isEnabled && tableMeta.editing.hasRowErrors(row.id) ? !tableMeta.editing.hasRowErrorsSeen(row.id) ? 'unseen' : true : undefined,
19503
- 'data-row-editing-status': tableMeta.editing.isEnabled && tableMeta.editing.getRowSaveStatus(row.id) ? tableMeta.editing.getRowSaveStatus(row.id) : undefined,
19504
- 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
19505
19693
  };
19506
- 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, {
19507
19695
  rowId: row.id,
19508
19696
  table: table
19509
- }) : null);
19697
+ }) : null), /*#__PURE__*/React__default.createElement(DiscardChangesConfirmationDialog, {
19698
+ open: showDiscardDialog,
19699
+ onChange: setShowDiscardDialog,
19700
+ onDiscard: handleDiscard
19701
+ }));
19510
19702
  }
19511
19703
 
19512
19704
  const RENDERERS$1 = {
@@ -19514,29 +19706,46 @@ const RENDERERS$1 = {
19514
19706
  cell: Cell$5
19515
19707
  };
19516
19708
  function useTable3(props, ref) {
19517
- 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);
19518
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]);
19519
19719
  const extendedProps = {
19520
19720
  ...props,
19721
+ data,
19521
19722
  enableRowActions: editing.isEditing ? true : props.enableRowActions,
19522
- rowActions: editing.isEditing ? [(_, rowId) => (/*#__PURE__*/React__default.createElement(EditingActionMenu, {
19723
+ rowActions: editing.isEditing ? [(_, rowId, table) => (/*#__PURE__*/React__default.createElement(EditingActionMenu, {
19523
19724
  hasChanges: editing.hasChanges(rowId),
19524
19725
  hasErrors: editing.hasRowErrors(rowId),
19525
- onClear: () => editing.resetChanges(rowId),
19526
- onEditingSave: () => editing.saveChanges(rowId),
19527
- 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
+ },
19528
19734
  isLastRow: !creationEnabled && table.meta.rowActive.rowActiveIndex === table.meta.length - 1
19529
19735
  }))] : props.rowActions
19530
19736
  };
19531
19737
  const meta = {
19532
19738
  editing
19533
19739
  };
19534
- 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);
19535
19744
  // listeners
19536
19745
  useTableEditingListener(table.instance, table.ref);
19537
19746
  React__default.useEffect(() => {
19538
19747
  if (table.ref.current) {
19539
- 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);
19540
19749
  }
19541
19750
  }, [table.ref.current]);
19542
19751
  return table;
@@ -19555,7 +19764,7 @@ function Alert$1(props) {
19555
19764
  const validationTexts = texts.table3.editing.validation;
19556
19765
  const tableMeta = table.options.meta;
19557
19766
  const [showFilterResetDialog, setShowFilterResetDialog] = React__default.useState(false);
19558
- const pendingChangesWithErrors = tableMeta.editing.getAlertErrors();
19767
+ const pendingChangesWithErrors = tableMeta.editing.getErrorsShownInAlert();
19559
19768
  function scrollToRow(rowIndex) {
19560
19769
  tableMeta.rowActive.setRowActiveIndex(rowIndex);
19561
19770
  scrollToIndex(rowIndex, {
@@ -19574,38 +19783,43 @@ function Alert$1(props) {
19574
19783
  const title = (pendingChangesWithErrors.length === 1 ? validationTexts.alert.titleOne : validationTexts.alert.titlePlural).replace('[COUNT]', String(pendingChangesWithErrors.length));
19575
19784
  // generate links to each invalid row, to go into the error message
19576
19785
  const links = [];
19577
- const rowIdentityColumn = tableMeta.rowIdentityColumnId ? table.getColumn(tableMeta.rowIdentityColumnId) : undefined;
19578
- 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) => {
19579
19789
  // if appropriate, concatenate the item with the text "and"
19580
19790
  if (pendingChangesWithErrors.length > 1 && index === pendingChangesWithErrors.length - 1) {
19581
19791
  // Add space before and after `messageAnd` text
19582
19792
  links.push(` ${validationTexts.alert.messageAnd} `);
19583
19793
  }
19584
- const rowIndex = table.getRowModel().rows.findIndex(row => row.id === error.rowId);
19794
+ const rowIndex = table.getRowModel().rows.findIndex(row => row.id === pendingChangeWithError.rowId);
19585
19795
  const handleClick = () => {
19796
+ // if row is visible
19586
19797
  if (rowIndex > -1) {
19587
19798
  scrollToRow(rowIndex);
19588
- } else {
19589
- setShowFilterResetDialog(error.rowId);
19799
+ }
19800
+ // if row is filtered out
19801
+ else {
19802
+ setShowFilterResetDialog(pendingChangeWithError.rowId);
19590
19803
  }
19591
19804
  };
19592
19805
  let tooltip;
19593
- if (error.pendingChange._meta.errors.row) {
19594
- tooltip = error.pendingChange._meta.errors.row;
19806
+ if (pendingChangeWithError.errors.row) {
19807
+ tooltip = pendingChangeWithError.errors.row;
19595
19808
  } else {
19596
19809
  var _table$getAllColumns$, _table$getAllColumns$2;
19597
- const firstCellErrorColumnId = Object.keys(error.pendingChange._meta.errors.cells)[0];
19810
+ const firstCellErrorColumnId = Object.keys(pendingChangeWithError.errors.cells)[0];
19598
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;
19599
- tooltip = `${columnName}: ${error.pendingChange._meta.errors.cells[firstCellErrorColumnId]}`;
19812
+ tooltip = `${columnName}: ${pendingChangeWithError.errors.cells[firstCellErrorColumnId]}`;
19600
19813
  }
19814
+ const row = table.getRow(pendingChangeWithError.rowId).original;
19601
19815
  links.push(/*#__PURE__*/React__default.createElement(Tooltip, {
19602
- key: error.rowId,
19816
+ key: pendingChangeWithError.rowId,
19603
19817
  title: tooltip
19604
19818
  }, /*#__PURE__*/React__default.createElement("span", {
19605
19819
  className: "text-blue",
19606
19820
  onClick: handleClick,
19607
19821
  role: "button"
19608
- }, rowIdentityColumn ? error.pendingChange._meta.original[rowIdentityColumn.id] : rowIndex + 1)));
19822
+ }, rowIdentityColumn ? row[rowIdentityColumn.id] : rowIndex + 1)));
19609
19823
  // if appropriate, concatenate the item with the text ","
19610
19824
  if (pendingChangesWithErrors.length > 2 && index < pendingChangesWithErrors.length - 2) {
19611
19825
  links.push(', ');
@@ -19661,89 +19875,6 @@ function FilterResetDialog(props) {
19661
19875
  }, texts.table3.editing.validation.resetFiltersDialog.confirm)))));
19662
19876
  }
19663
19877
 
19664
- function CreateNewRowButton(props) {
19665
- const {
19666
- onEditingCreate,
19667
- scrollToIndex,
19668
- table,
19669
- tableMeta
19670
- } = props;
19671
- const {
19672
- texts
19673
- } = useLocalization();
19674
- const rows = table.getCoreRowModel().rows.filter(row => row.original !== undefined);
19675
- const [rowCreated, setRowCreated] = React__default.useState({
19676
- rowFinder: undefined
19677
- });
19678
- const handleKeyDown = event => {
19679
- if (!tableMeta.editing.hasChanges() && event.key === 'Tab') {
19680
- tableMeta.editing.saveChanges();
19681
- }
19682
- };
19683
- const handleCreate = function () {
19684
- try {
19685
- if (!onEditingCreate) {
19686
- return Promise.resolve();
19687
- }
19688
- const createdRow = rows.find(row => {
19689
- var _rowCreated$rowFinder;
19690
- 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);
19691
- });
19692
- const _temp = function () {
19693
- if (createdRow) {
19694
- return Promise.resolve(tableMeta.editing.saveChanges()).then(function () {
19695
- if (!tableMeta.editing.hasRowErrors(createdRow.id)) {
19696
- const rowFinder = onEditingCreate();
19697
- setRowCreated({
19698
- rowFinder
19699
- });
19700
- }
19701
- });
19702
- } else {
19703
- const rowFinder = onEditingCreate();
19704
- setRowCreated({
19705
- rowFinder
19706
- });
19707
- }
19708
- }();
19709
- return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
19710
- } catch (e) {
19711
- return Promise.reject(e);
19712
- }
19713
- };
19714
- React__default.useEffect(() => {
19715
- if (typeof (rowCreated === null || rowCreated === void 0 ? void 0 : rowCreated.rowFinder) === 'function') {
19716
- const createdRow = rows.find(row => {
19717
- var _rowCreated$rowFinder2;
19718
- 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);
19719
- });
19720
- if (createdRow) {
19721
- const rowInTable = table.getRowModel().rows.filter(row => row.original !== undefined).find(row => {
19722
- var _rowCreated$rowFinder3;
19723
- 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);
19724
- });
19725
- if (rowInTable) {
19726
- tableMeta.editing.toggleEditing(true);
19727
- tableMeta.rowActive.setRowActiveIndex(createdRow.index);
19728
- scrollToIndex(createdRow.index);
19729
- requestAnimationFrame(() => animateCreateRow(createdRow.id));
19730
- }
19731
- requestAnimationFrame(() => tableMeta.editing.addCreatedRowChangeset(createdRow));
19732
- }
19733
- }
19734
- }, [rowCreated]);
19735
- return /*#__PURE__*/React__default.createElement("tr", {
19736
- onClick: handleCreate,
19737
- className: "border-grey-300 hover:bg-grey-100 group !sticky bottom-10 left-0 z-[21] !block cursor-pointer border-t"
19738
- }, /*#__PURE__*/React__default.createElement("td", {
19739
- className: "!border-t-0 !bg-transparent"
19740
- }, /*#__PURE__*/React__default.createElement(Button$1, {
19741
- onKeyDown: handleKeyDown,
19742
- className: "group-hover:bg-grey-200 sticky left-0",
19743
- appearance: "transparent"
19744
- }, "+ ", texts.table3.editing.buttons.create.label)));
19745
- }
19746
-
19747
19878
  function Editing(props) {
19748
19879
  const {
19749
19880
  scrollToIndex,
@@ -19769,21 +19900,193 @@ function Editing(props) {
19769
19900
  (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.click();
19770
19901
  });
19771
19902
  const handleChange = enabled => {
19772
- tableMeta.editing.toggleEditing(enabled);
19903
+ if (enabled && tableMeta.rowActive.rowActiveIndex === undefined) {
19904
+ tableMeta.rowActive.setRowActiveIndex(0);
19905
+ }
19773
19906
  requestAnimationFrame(() => {
19774
19907
  var _tableMeta$rowActive$;
19775
- 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);
19776
19911
  });
19777
19912
  };
19778
19913
  return /*#__PURE__*/React__default.createElement(Tooltip, {
19779
19914
  title: tooltip
19780
19915
  }, /*#__PURE__*/React__default.createElement(ModeSwitch, {
19916
+ "data-table": "editing-toggle",
19781
19917
  checked: tableMeta.editing.isEditing,
19782
19918
  onChange: handleChange,
19783
19919
  ref: ref
19784
19920
  }));
19785
19921
  }
19786
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
+
19787
20090
  function Column$3(_) {
19788
20091
  return null;
19789
20092
  }
@@ -19799,8 +20102,18 @@ const BaseTable3 = /*#__PURE__*/fixedForwardRef(function BaseTable3(props, ref)
19799
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,
19800
20103
  enableHorizontalArrowKeyNavigation: table3.meta.editing.isEditing
19801
20104
  };
19802
- const hasAlertErrors = table3.meta.editing.hasAlertErrors();
19803
- 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
+ }
19804
20117
  return /*#__PURE__*/React__default.createElement(Table, null, /*#__PURE__*/React__default.createElement(Table.Toolbar, {
19805
20118
  table: table3
19806
20119
  }, table3.meta.editing.isEnabled ? (/*#__PURE__*/React__default.createElement(Editing, {
@@ -19813,13 +20126,14 @@ const BaseTable3 = /*#__PURE__*/fixedForwardRef(function BaseTable3(props, ref)
19813
20126
  tableRef: table3.ref
19814
20127
  })) : null, /*#__PURE__*/React__default.createElement(Table.Grid, Object.assign({}, gridAttributes, {
19815
20128
  "data-taco": "table3",
20129
+ rowsForFooter: footerRows,
19816
20130
  table: table3
19817
- }), showCreateRowButton && (/*#__PURE__*/React__default.createElement(CreateNewRowButton, {
20131
+ }), hasCreateWorkflow ? (/*#__PURE__*/React__default.createElement(TemporaryRow, {
20132
+ createRowButtonRef: table3.meta.editing.createRowButtonRef,
19818
20133
  table: table3.instance,
19819
20134
  tableMeta: table3.meta,
19820
- onEditingCreate: props.onEditingCreate,
19821
- scrollToIndex: table3.renderer.scrollToIndex
19822
- }))));
20135
+ tableRef: table3.ref
20136
+ })) : null));
19823
20137
  });
19824
20138
  const Table3 = /*#__PURE__*/fixedForwardRef(function Table3(props, ref) {
19825
20139
  const stringifiedChildren = String(props.children);