@economic/taco 2.45.4 → 2.46.0

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