@economic/taco 2.45.4 → 2.46.1

Sign up to get free protection for your applications and to get access to all the features.
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 +34 -13
  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 +987 -660
  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,50 @@ 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, {
19549
- hasChanges: editing.hasChanges(rowId),
19550
- hasErrors: editing.hasRowErrors(rowId),
19551
- onClear: () => editing.resetChanges(rowId),
19552
- onEditingSave: () => editing.saveChanges(rowId),
19553
- onExit: () => editing.toggleEditing(false),
19554
- isLastRow: !creationEnabled && table.meta.rowActive.rowActiveIndex === table.meta.length - 1
19555
- }))] : props.rowActions
19766
+ // Display EditingActionMenu instead of row actions while editing
19767
+ rowActions: editing.isEditing ? [(_, rowId, table) => {
19768
+ const tableMeta = table.options.meta;
19769
+ return /*#__PURE__*/React__default.createElement(EditingActionMenu, {
19770
+ hasChanges: editing.hasChanges(rowId),
19771
+ hasErrors: editing.hasRowErrors(rowId),
19772
+ onDiscard: () => editing.discardChanges(rowId, table),
19773
+ onEditingSave: function () {
19774
+ try {
19775
+ return Promise.resolve(editing.saveChanges(table, rowId)).then(function () {});
19776
+ } catch (e) {
19777
+ return Promise.reject(e);
19778
+ }
19779
+ },
19780
+ isLastRow: !creationEnabled && tableMeta.rowActive.rowActiveIndex === tableMeta.length - 1
19781
+ });
19782
+ }] : props.rowActions
19556
19783
  };
19557
19784
  const meta = {
19558
19785
  editing
19559
19786
  };
19560
- const table = useTable(extendedProps, ref, RENDERERS$1, meta);
19787
+ const options = {
19788
+ virtualiserPaddingEndOffset: props.enableEditing && props.onEditingCreate ? editing.hasTemporaryRowErrors() ? 1.4 : 1 : 0
19789
+ };
19790
+ const table = useTable(extendedProps, ref, RENDERERS$1, meta, options);
19561
19791
  // listeners
19562
- useTableEditingListener(table.instance, table.ref);
19792
+ useTableEditingListener(table.instance, table.ref, table.renderer.scrollToIndex);
19563
19793
  React__default.useEffect(() => {
19564
19794
  if (table.ref.current) {
19565
- table.ref.current.instance.toggleEditing = enabled => table.meta.editing.toggleEditing(enabled !== null && enabled !== void 0 ? enabled : editing => !editing);
19795
+ table.ref.current.instance.toggleEditing = enabled => table.meta.editing.toggleEditing(enabled !== null && enabled !== void 0 ? enabled : editing => !editing, table.instance, table.renderer.scrollToIndex);
19566
19796
  }
19567
19797
  }, [table.ref.current]);
19568
19798
  return table;
@@ -19581,7 +19811,7 @@ function Alert$1(props) {
19581
19811
  const validationTexts = texts.table3.editing.validation;
19582
19812
  const tableMeta = table.options.meta;
19583
19813
  const [showFilterResetDialog, setShowFilterResetDialog] = React__default.useState(false);
19584
- const pendingChangesWithErrors = tableMeta.editing.getAlertErrors();
19814
+ const pendingChangesWithErrors = tableMeta.editing.getErrorsShownInAlert();
19585
19815
  function scrollToRow(rowIndex) {
19586
19816
  tableMeta.rowActive.setRowActiveIndex(rowIndex);
19587
19817
  scrollToIndex(rowIndex, {
@@ -19600,38 +19830,43 @@ function Alert$1(props) {
19600
19830
  const title = (pendingChangesWithErrors.length === 1 ? validationTexts.alert.titleOne : validationTexts.alert.titlePlural).replace('[COUNT]', String(pendingChangesWithErrors.length));
19601
19831
  // generate links to each invalid row, to go into the error message
19602
19832
  const links = [];
19603
- const rowIdentityColumn = tableMeta.rowIdentityColumnId ? table.getColumn(tableMeta.rowIdentityColumnId) : undefined;
19604
- pendingChangesWithErrors.forEach((error, index) => {
19833
+ const visibleColumns = table.getVisibleFlatColumns().map(c => c.id);
19834
+ const rowIdentityColumn = tableMeta.rowIdentityAccessor && visibleColumns.includes(String(tableMeta.rowIdentityAccessor)) ? table.getColumn(String(tableMeta.rowIdentityAccessor)) : undefined;
19835
+ pendingChangesWithErrors.forEach((pendingChangeWithError, index) => {
19605
19836
  // if appropriate, concatenate the item with the text "and"
19606
19837
  if (pendingChangesWithErrors.length > 1 && index === pendingChangesWithErrors.length - 1) {
19607
19838
  // Add space before and after `messageAnd` text
19608
19839
  links.push(` ${validationTexts.alert.messageAnd} `);
19609
19840
  }
19610
- const rowIndex = table.getRowModel().rows.findIndex(row => row.id === error.rowId);
19841
+ const rowIndex = table.getRowModel().rows.findIndex(row => row.id === pendingChangeWithError.rowId);
19611
19842
  const handleClick = () => {
19843
+ // if row is visible
19612
19844
  if (rowIndex > -1) {
19613
19845
  scrollToRow(rowIndex);
19614
- } else {
19615
- setShowFilterResetDialog(error.rowId);
19846
+ }
19847
+ // if row is filtered out
19848
+ else {
19849
+ setShowFilterResetDialog(pendingChangeWithError.rowId);
19616
19850
  }
19617
19851
  };
19618
19852
  let tooltip;
19619
- if (error.pendingChange._meta.errors.row) {
19620
- tooltip = error.pendingChange._meta.errors.row;
19853
+ if (pendingChangeWithError.errors.row) {
19854
+ tooltip = pendingChangeWithError.errors.row;
19621
19855
  } else {
19622
19856
  var _table$getAllColumns$, _table$getAllColumns$2;
19623
- const firstCellErrorColumnId = Object.keys(error.pendingChange._meta.errors.cells)[0];
19857
+ const firstCellErrorColumnId = Object.keys(pendingChangeWithError.errors.cells)[0];
19624
19858
  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]}`;
19859
+ tooltip = `${columnName}: ${pendingChangeWithError.errors.cells[firstCellErrorColumnId]}`;
19626
19860
  }
19861
+ const row = table.getRow(pendingChangeWithError.rowId).original;
19627
19862
  links.push(/*#__PURE__*/React__default.createElement(Tooltip, {
19628
- key: error.rowId,
19863
+ key: pendingChangeWithError.rowId,
19629
19864
  title: tooltip
19630
19865
  }, /*#__PURE__*/React__default.createElement("span", {
19631
19866
  className: "text-blue",
19632
19867
  onClick: handleClick,
19633
19868
  role: "button"
19634
- }, rowIdentityColumn ? error.pendingChange._meta.original[rowIdentityColumn.id] : rowIndex + 1)));
19869
+ }, rowIdentityColumn ? row[rowIdentityColumn.id] : rowIndex + 1)));
19635
19870
  // if appropriate, concatenate the item with the text ","
19636
19871
  if (pendingChangesWithErrors.length > 2 && index < pendingChangesWithErrors.length - 2) {
19637
19872
  links.push(', ');
@@ -19687,127 +19922,212 @@ function FilterResetDialog(props) {
19687
19922
  }, texts.table3.editing.validation.resetFiltersDialog.confirm)))));
19688
19923
  }
19689
19924
 
19690
- function CreateNewRowButton(props) {
19925
+ function Editing(props) {
19691
19926
  const {
19692
- onEditingCreate,
19693
19927
  scrollToIndex,
19694
- table,
19695
- tableMeta
19928
+ table
19696
19929
  } = props;
19697
19930
  const {
19698
19931
  texts
19699
19932
  } = 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
- }
19933
+ const ref = React__default.useRef(null);
19934
+ const tableMeta = table.options.meta;
19935
+ const handleChange = enabled => {
19936
+ tableMeta.editing.toggleEditing(enabled, table, scrollToIndex);
19708
19937
  };
19709
- const handleCreate = function () {
19938
+ const tooltip = /*#__PURE__*/React__default.createElement(React__default.Fragment, null, texts.table3.editing.buttons.edit.tooltip, /*#__PURE__*/React__default.createElement(Shortcut, {
19939
+ className: "ml-2",
19940
+ keys: shortcut
19941
+ }));
19942
+ return /*#__PURE__*/React__default.createElement(Tooltip, {
19943
+ title: tooltip
19944
+ }, /*#__PURE__*/React__default.createElement(ModeSwitch, {
19945
+ "data-table": "editing-toggle",
19946
+ checked: tableMeta.editing.isEditing,
19947
+ onChange: handleChange,
19948
+ ref: ref
19949
+ }));
19950
+ }
19951
+
19952
+ function CreateNewRow(props) {
19953
+ var _temporaryRows$0$tabl, _temporaryRows$, _table$getState$colum;
19954
+ const {
19955
+ buttonRef,
19956
+ onEditingCreate: handleEditingCreate,
19957
+ scrollToIndex,
19958
+ table,
19959
+ tableMeta,
19960
+ tableRef
19961
+ } = props;
19962
+ const {
19963
+ texts
19964
+ } = useLocalization();
19965
+ const temporaryRows = tableMeta.editing.temporaryRows;
19966
+ 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 : '';
19967
+ 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);
19968
+ const isSaving = !!temporaryRowId && tableMeta.editing.getRowStatus(temporaryRowId) === 'saving';
19969
+ const createRow = function (row) {
19710
19970
  try {
19711
- if (!onEditingCreate) {
19971
+ if (!handleEditingCreate || isDisabled) {
19712
19972
  return Promise.resolve();
19713
19973
  }
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
- });
19974
+ return Promise.resolve(tableMeta.editing.saveChanges(table)).then(function (saved) {
19975
+ if (!saved) {
19976
+ return;
19733
19977
  }
19734
- }();
19735
- return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
19978
+ const changeset = row !== null && row !== void 0 ? row : handleEditingCreate();
19979
+ try {
19980
+ if (changeset) {
19981
+ const rowId = tableMeta.editing.createRow(changeset);
19982
+ table.getRow(rowId).pin('bottom');
19983
+ // set the active row to the new row before toggling editing on
19984
+ const nextRowIndex = temporaryRows.length ? tableMeta.length + 1 : tableMeta.length;
19985
+ tableMeta.rowActive.setRowActiveIndex(nextRowIndex);
19986
+ tableMeta.editing.toggleEditing(true, table, scrollToIndex);
19987
+ tableMeta.editing.setLastFocusedCellIndex(0);
19988
+ }
19989
+ } catch (error) {
19990
+ console.error(error);
19991
+ }
19992
+ });
19736
19993
  } catch (e) {
19737
19994
  return Promise.reject(e);
19738
19995
  }
19739
19996
  };
19997
+ // allow programmatic access to creating rows from outside the table
19740
19998
  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
- }
19999
+ if (tableRef.current) {
20000
+ tableRef.current.instance.createRow = createRow;
19759
20001
  }
19760
- }, [rowCreated]);
20002
+ }, [tableRef.current, createRow]);
20003
+ const handleCreate = function () {
20004
+ return createRow();
20005
+ };
20006
+ const shortcut = {
20007
+ key: 'Enter',
20008
+ shift: true
20009
+ };
20010
+ let tooltip;
20011
+ if (isSaving) {
20012
+ tooltip = texts.table3.editing.buttons.create.saving;
20013
+ } else if (isDisabled) {
20014
+ tooltip = texts.table3.editing.buttons.create.disabled;
20015
+ } else {
20016
+ tooltip = /*#__PURE__*/React__default.createElement(Shortcut, {
20017
+ keys: shortcut
20018
+ });
20019
+ }
20020
+ const isScrolled = tableRef.current ? tableRef.current.scrollHeight > tableRef.current.clientHeight : false;
20021
+ const className = cn('group/row border-grey-300 !sticky z-[21]', {
20022
+ 'bottom-10': tableMeta.footer.isEnabled,
20023
+ 'bottom-0': !tableMeta.footer.isEnabled,
20024
+ 'border-t-2': isScrolled,
20025
+ 'border-b': !isScrolled
20026
+ });
19761
20027
  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"
20028
+ "data-row-create": true,
20029
+ className: className,
20030
+ tabIndex: -1
19764
20031
  }, /*#__PURE__*/React__default.createElement("td", {
19765
- className: "!border-t-0 !bg-transparent"
20032
+ className: "!bg-grey-50 col-span-full !border-b-0 !px-1"
19766
20033
  }, /*#__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)));
20034
+ appearance: "transparent",
20035
+ className: "group-hover:bg-grey-200 sticky left-[4px]",
20036
+ disabled: isDisabled,
20037
+ onClick: handleCreate,
20038
+ ref: buttonRef,
20039
+ shortcut: shortcut,
20040
+ tooltip: tooltip
20041
+ }, /*#__PURE__*/React__default.createElement(Icon, {
20042
+ name: "circle-plus"
20043
+ }), texts.table3.editing.buttons.create.label)));
19771
20044
  }
19772
20045
 
19773
- function Editing(props) {
20046
+ function TemporaryRow(props) {
19774
20047
  const {
19775
- scrollToIndex,
19776
- table
20048
+ createRowButtonRef,
20049
+ table,
20050
+ tableMeta,
20051
+ tableRef
19777
20052
  } = 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
20053
+ const handleKeyDown = function (event) {
20054
+ try {
20055
+ const _temp2 = function () {
20056
+ if (event.key === 'ArrowDown') {
20057
+ event.preventDefault();
20058
+ const _temp = function () {
20059
+ if (!isElementTriggeredFromContainer(event.target, event.currentTarget)) {
20060
+ return Promise.resolve(tableMeta.editing.saveChanges(table)).then(function (saved) {
20061
+ if (saved) {
20062
+ var _createRowButtonRef$c;
20063
+ (_createRowButtonRef$c = createRowButtonRef.current) === null || _createRowButtonRef$c === void 0 ? void 0 : _createRowButtonRef$c.focus();
20064
+ }
20065
+ });
20066
+ }
20067
+ }();
20068
+ if (_temp && _temp.then) return _temp.then(function () {});
20069
+ } else if (event.key === 'ArrowUp') {
20070
+ event.preventDefault();
20071
+ event.stopPropagation();
20072
+ if (tableRef.current) {
20073
+ var _tableRef$current$que, _tableRef$current$que2, _tableRef$current$que3;
20074
+ 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 : []);
20075
+ 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;
20076
+ const newRowHeight = event.currentTarget.getBoundingClientRect().height;
20077
+ const visibleHeight = tableRef.current.clientHeight - footerHeight - newRowHeight;
20078
+ const tableTopOffset = tableRef.current.getBoundingClientRect().top;
20079
+ let nextRowIndex;
20080
+ // iterate available rows in reverse order, since we're working at the bottom
20081
+ for (let index = availableRows.length - 1; index >= 0; index--) {
20082
+ const rowRect = availableRows[index].getBoundingClientRect();
20083
+ const topPlusHalfRow = rowRect.top + rowRect.height / 2;
20084
+ if (topPlusHalfRow - tableTopOffset <= visibleHeight) {
20085
+ nextRowIndex = index;
20086
+ break;
20087
+ }
20088
+ }
20089
+ if (nextRowIndex) {
20090
+ tableMeta.rowActive.setRowActiveIndex(Number(availableRows[nextRowIndex < 0 ? 0 : nextRowIndex].getAttribute('data-row-index')));
20091
+ }
20092
+ }
20093
+ }
20094
+ }();
20095
+ return Promise.resolve(_temp2 && _temp2.then ? _temp2.then(function () {}) : void 0);
20096
+ } catch (e) {
20097
+ return Promise.reject(e);
20098
+ }
19787
20099
  };
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
- });
20100
+ const handleKeyDownCapture = event => {
20101
+ if (event.key === 'ArrowLeft' && tableMeta.editing.lastFocusedCellIndex === 0) {
20102
+ event.preventDefault();
20103
+ event.stopPropagation();
20104
+ } else if (event.key === 'ArrowRight' && tableMeta.editing.lastFocusedCellIndex) {
20105
+ if (tableMeta.editing.lastFocusedCellIndex === table.getVisibleFlatColumns().length - 1) {
20106
+ event.preventDefault();
20107
+ event.stopPropagation();
20108
+ }
20109
+ }
19803
20110
  };
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
- }));
20111
+ const isScrolled = tableRef.current ? tableRef.current.scrollHeight > tableRef.current.clientHeight : false;
20112
+ const className = cn('group/row border-grey-300 !sticky z-[22]', {
20113
+ 'bottom-[calc(5rem_+_3px)] data-[row-editing-move]:bottom-[calc(5rem_+_2px)]': tableMeta.footer.isEnabled,
20114
+ 'bottom-[calc(2.5rem_+_3px)] data-[row-editing-move]:bottom-[calc(2.5rem_+_2px)]': !tableMeta.footer.isEnabled,
20115
+ 'border-t-2 shadow-[0px_-5px_20px_0px_rgba(0,0,0,0.1)] [&>td]:!border-b-0': isScrolled
20116
+ });
20117
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, table.getBottomRows().map(row => (/*#__PURE__*/React__default.createElement(Row, {
20118
+ key: row.id,
20119
+ cellRenderer: RENDERERS$1.cell,
20120
+ index: tableMeta.length,
20121
+ measureRow: () => null,
20122
+ renderer: RENDERERS$1.row,
20123
+ row: row,
20124
+ table: table,
20125
+ className: className,
20126
+ onKeyDown: handleKeyDown,
20127
+ onKeyDownCapture: handleKeyDownCapture,
20128
+ // Row actions should only be hidden on temporary rows when editing is turned off
20129
+ hideRowActions: !tableMeta.editing.isEditing
20130
+ }))));
19811
20131
  }
19812
20132
 
19813
20133
  function Column$3(_) {
@@ -19825,8 +20145,8 @@ const BaseTable3 = /*#__PURE__*/fixedForwardRef(function BaseTable3(props, ref)
19825
20145
  '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
20146
  enableHorizontalArrowKeyNavigation: table3.meta.editing.isEditing
19827
20147
  };
19828
- const hasAlertErrors = table3.meta.editing.hasAlertErrors();
19829
- const showCreateRowButton = table3.meta.editing.isEnabled && props.onEditingCreate;
20148
+ const hasAlertErrors = table3.meta.editing.getErrorsShownInAlert().length;
20149
+ const hasCreateWorkflow = table3.meta.editing.isEnabled && props.onEditingCreate;
19830
20150
  return /*#__PURE__*/React__default.createElement(Table, null, /*#__PURE__*/React__default.createElement(Table.Toolbar, {
19831
20151
  table: table3
19832
20152
  }, table3.meta.editing.isEnabled ? (/*#__PURE__*/React__default.createElement(Editing, {
@@ -19840,12 +20160,19 @@ const BaseTable3 = /*#__PURE__*/fixedForwardRef(function BaseTable3(props, ref)
19840
20160
  })) : null, /*#__PURE__*/React__default.createElement(Table.Grid, Object.assign({}, gridAttributes, {
19841
20161
  "data-taco": "table3",
19842
20162
  table: table3
19843
- }), showCreateRowButton && (/*#__PURE__*/React__default.createElement(CreateNewRowButton, {
20163
+ }), hasCreateWorkflow ? (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(TemporaryRow, {
20164
+ createRowButtonRef: table3.meta.editing.createRowButtonRef,
19844
20165
  table: table3.instance,
19845
20166
  tableMeta: table3.meta,
20167
+ tableRef: table3.ref
20168
+ }), /*#__PURE__*/React__default.createElement(CreateNewRow, {
20169
+ buttonRef: table3.meta.editing.createRowButtonRef,
19846
20170
  onEditingCreate: props.onEditingCreate,
19847
- scrollToIndex: table3.renderer.scrollToIndex
19848
- }))));
20171
+ scrollToIndex: table3.renderer.scrollToIndex,
20172
+ table: table3.instance,
20173
+ tableMeta: table3.meta,
20174
+ tableRef: table3.ref
20175
+ }))) : null));
19849
20176
  });
19850
20177
  const Table3 = /*#__PURE__*/fixedForwardRef(function Table3(props, ref) {
19851
20178
  const stringifiedChildren = String(props.children);