@economic/taco 2.44.5-create.6 → 2.44.5-create.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. package/dist/components/Provider/Localization.d.ts +0 -2
  2. package/dist/components/Report/Report.d.ts +1 -1
  3. package/dist/components/Table3/Table3.d.ts +14 -2
  4. package/dist/components/Table3/components/Columns/Internal/EditingActionsMenu.d.ts +2 -1
  5. package/dist/components/Table3/components/Row/Editing/CreateRowButton.d.ts +11 -0
  6. package/dist/components/Table3/features/useTableEditing.d.ts +36 -25
  7. package/dist/components/Table3/types.d.ts +8 -23
  8. package/dist/components/Table3/useTable3.d.ts +0 -6
  9. package/dist/components/Table3/util/editing.d.ts +1 -2
  10. package/dist/esm/index.css +4 -16
  11. package/dist/esm/packages/taco/src/components/ModeSwitch/ModeSwitch.js +2 -2
  12. package/dist/esm/packages/taco/src/components/ModeSwitch/ModeSwitch.js.map +1 -1
  13. package/dist/esm/packages/taco/src/components/Provider/Localization.js +3 -5
  14. package/dist/esm/packages/taco/src/components/Provider/Localization.js.map +1 -1
  15. package/dist/esm/packages/taco/src/components/Switch/Switch.js +1 -1
  16. package/dist/esm/packages/taco/src/components/Switch/Switch.js.map +1 -1
  17. package/dist/esm/packages/taco/src/components/Table3/Table3.js +7 -19
  18. package/dist/esm/packages/taco/src/components/Table3/Table3.js.map +1 -1
  19. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Cell/EditingControlCell.js +22 -21
  20. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Cell/EditingControlCell.js.map +1 -1
  21. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Internal/EditingActionsMenu.js +37 -5
  22. package/dist/esm/packages/taco/src/components/Table3/components/Columns/Internal/EditingActionsMenu.js.map +1 -1
  23. package/dist/esm/packages/taco/src/components/Table3/components/Editing/Alert.js +12 -17
  24. package/dist/esm/packages/taco/src/components/Table3/components/Editing/Alert.js.map +1 -1
  25. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateRowButton.js +90 -0
  26. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateRowButton.js.map +1 -0
  27. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/SaveStatus.js +14 -2
  28. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/SaveStatus.js.map +1 -1
  29. package/dist/esm/packages/taco/src/components/Table3/components/Row/Row.js +6 -39
  30. package/dist/esm/packages/taco/src/components/Table3/components/Row/Row.js.map +1 -1
  31. package/dist/esm/packages/taco/src/components/Table3/components/Toolbar/Editing/Editing.js +2 -7
  32. package/dist/esm/packages/taco/src/components/Table3/components/Toolbar/Editing/Editing.js.map +1 -1
  33. package/dist/esm/packages/taco/src/components/Table3/features/useTableEditing.js +406 -19
  34. package/dist/esm/packages/taco/src/components/Table3/features/useTableEditing.js.map +1 -1
  35. package/dist/esm/packages/taco/src/components/Table3/listeners/useTableEditingListener.js +32 -37
  36. package/dist/esm/packages/taco/src/components/Table3/listeners/useTableEditingListener.js.map +1 -1
  37. package/dist/esm/packages/taco/src/components/Table3/useTable3.js +8 -25
  38. package/dist/esm/packages/taco/src/components/Table3/useTable3.js.map +1 -1
  39. package/dist/esm/packages/taco/src/components/Table3/util/editing.js +24 -4
  40. package/dist/esm/packages/taco/src/components/Table3/util/editing.js.map +1 -1
  41. package/dist/esm/packages/taco/src/primitives/Table/Core/Table.js +4 -3
  42. package/dist/esm/packages/taco/src/primitives/Table/Core/Table.js.map +1 -1
  43. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Cell/BuiltIns/GroupedCell.js +3 -9
  44. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Cell/BuiltIns/GroupedCell.js.map +1 -1
  45. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Internal/Actions.js +3 -6
  46. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Columns/Internal/Actions.js.map +1 -1
  47. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Footer/Footer.js +1 -1
  48. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Footer/Footer.js.map +1 -1
  49. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/BuiltIns/DisplayRow.js +1 -1
  50. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Row/BuiltIns/DisplayRow.js.map +1 -1
  51. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Toolbar/components/Filters/components/FilterValue.js +8 -1
  52. package/dist/esm/packages/taco/src/primitives/Table/Core/components/Toolbar/components/Filters/components/FilterValue.js.map +1 -1
  53. package/dist/esm/packages/taco/src/primitives/Table/Core/features/useTableRenderer.js +6 -23
  54. package/dist/esm/packages/taco/src/primitives/Table/Core/features/useTableRenderer.js.map +1 -1
  55. package/dist/esm/packages/taco/src/primitives/Table/Core/useTable.js +2 -2
  56. package/dist/esm/packages/taco/src/primitives/Table/Core/useTable.js.map +1 -1
  57. package/dist/esm/packages/taco/src/primitives/Table/types.js.map +1 -1
  58. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/useTableManager.js +1 -1
  59. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/useTableManager.js.map +1 -1
  60. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/util/setup.js +0 -11
  61. package/dist/esm/packages/taco/src/primitives/Table/useTableManager/util/setup.js.map +1 -1
  62. package/dist/esm/packages/taco/src/utils/dom.js +4 -7
  63. package/dist/esm/packages/taco/src/utils/dom.js.map +1 -1
  64. package/dist/index.css +4 -16
  65. package/dist/primitives/Table/Core/Table.d.ts +0 -1
  66. package/dist/primitives/Table/Core/components/Columns/Internal/Actions.d.ts +1 -3
  67. package/dist/primitives/Table/Core/components/Footer/Footer.d.ts +2 -2
  68. package/dist/primitives/Table/Core/features/useTableRenderer.d.ts +2 -2
  69. package/dist/primitives/Table/Core/features/useTableStyle.d.ts +1 -1
  70. package/dist/primitives/Table/Core/types.d.ts +0 -3
  71. package/dist/primitives/Table/Core/useTable.d.ts +2 -2
  72. package/dist/primitives/Table/types.d.ts +2 -2
  73. package/dist/primitives/Table/useTableManager/useTableManager.d.ts +1 -1
  74. package/dist/taco.cjs.development.js +627 -904
  75. package/dist/taco.cjs.development.js.map +1 -1
  76. package/dist/taco.cjs.production.min.js +1 -1
  77. package/dist/taco.cjs.production.min.js.map +1 -1
  78. package/dist/utils/dom.d.ts +0 -1
  79. package/package.json +1 -1
  80. package/dist/components/Table3/components/Editing/DiscardChangesConfirmationDialog.d.ts +0 -7
  81. package/dist/components/Table3/components/Row/Editing/CreateNewRow.d.ts +0 -13
  82. package/dist/components/Table3/components/Row/Editing/TemporaryRow.d.ts +0 -11
  83. package/dist/components/Table3/features/useEditingState.d.ts +0 -28
  84. package/dist/esm/packages/taco/src/components/Table3/components/Editing/DiscardChangesConfirmationDialog.js +0 -34
  85. package/dist/esm/packages/taco/src/components/Table3/components/Editing/DiscardChangesConfirmationDialog.js.map +0 -1
  86. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateNewRow.js +0 -88
  87. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/CreateNewRow.js.map +0 -1
  88. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/TemporaryRow.js +0 -95
  89. package/dist/esm/packages/taco/src/components/Table3/components/Row/Editing/TemporaryRow.js.map +0 -1
  90. package/dist/esm/packages/taco/src/components/Table3/features/useEditingState.js +0 -512
  91. package/dist/esm/packages/taco/src/components/Table3/features/useEditingState.js.map +0 -1
@@ -43,8 +43,7 @@ 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 omit = _interopDefault(require('lodash/omit'));
47
- var setWith = _interopDefault(require('lodash/setWith'));
46
+ var lodash = require('lodash');
48
47
  var TabsPrimitive = require('@radix-ui/react-tabs');
49
48
  var Joyride = require('react-joyride');
50
49
  var Joyride__default = _interopDefault(Joyride);
@@ -4206,7 +4205,7 @@ const getOverlaySelector = element => {
4206
4205
  return undefined;
4207
4206
  }
4208
4207
  };
4209
- function isElementTriggeredFromContainer(element, container) {
4208
+ function isElementInsideOrTriggeredFromContainer(element, container) {
4210
4209
  var _getOverlaySelector, _element$closest;
4211
4210
  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);
4212
4211
  if (selector) {
@@ -4216,14 +4215,11 @@ function isElementTriggeredFromContainer(element, container) {
4216
4215
  const elementInDocument = document.querySelector(selector);
4217
4216
  // if the element does exist, see if it is itself connected to somethng that was triggered from the container
4218
4217
  if (elementInDocument) {
4219
- return isElementTriggeredFromContainer(elementInDocument, container);
4218
+ return isElementInsideOrTriggeredFromContainer(elementInDocument, container);
4220
4219
  }
4221
4220
  return false;
4222
4221
  }
4223
- return false;
4224
- }
4225
- function isElementInsideOrTriggeredFromContainer(element, container) {
4226
- return isElementTriggeredFromContainer(element, container) || !!(container !== null && container !== void 0 && container.contains(element));
4222
+ return !!(container !== null && container !== void 0 && container.contains(element));
4227
4223
  }
4228
4224
  function isElementInsideOverlay(element) {
4229
4225
  return !!(element !== null && element !== void 0 && element.closest('[role=dialog],[role=menu]'));
@@ -4717,9 +4713,7 @@ const defaultLocalisationTexts = {
4717
4713
  tooltip: 'Edit table'
4718
4714
  },
4719
4715
  create: {
4720
- label: 'New',
4721
- disabled: 'Existing new row must be saved',
4722
- saving: 'Saving...'
4716
+ label: 'New'
4723
4717
  }
4724
4718
  },
4725
4719
  clearChangesConfirmationDialog: {
@@ -4741,8 +4735,8 @@ const defaultLocalisationTexts = {
4741
4735
  },
4742
4736
  validation: {
4743
4737
  alert: {
4744
- titleOne: '[COUNT] unsaved row:',
4745
- titlePlural: '[COUNT] unsaved rows:',
4738
+ titleOne: '[COUNT] unsaved entry:',
4739
+ titlePlural: '[COUNT] unsaved entries:',
4746
4740
  messageOne: "[COLUMN] [ROW] is incomplete and hasn't been saved.",
4747
4741
  messagePlural: "[COLUMN] [ROW] are incomplete and haven't been saved.",
4748
4742
  messageRow: 'Row',
@@ -7638,7 +7632,7 @@ const Switch = /*#__PURE__*/React.forwardRef(function Switch(props, ref) {
7638
7632
  onCheckedChange: onChange,
7639
7633
  ref: ref
7640
7634
  }), /*#__PURE__*/React.createElement(PrimitiveSwitch.Thumb, {
7641
- className: "pointer-events-none mt-0.5 h-4 w-4 translate-x-[0.15rem] rounded-full bg-white transition-transform will-change-transform group-disabled:opacity-50 group-aria-checked:translate-x-[1.1rem]"
7635
+ className: "'will-change-transform mt-0.5 h-4 w-4 translate-x-[0.15rem] rounded-full bg-white transition-transform group-disabled:opacity-50 group-aria-checked:translate-x-[1.1rem]"
7642
7636
  }));
7643
7637
  if (label) {
7644
7638
  const labelContainerClassName = cn('flex self-start cursor-pointer', {
@@ -8698,10 +8692,10 @@ const ModeSwitch = /*#__PURE__*/React.forwardRef(function ModeSwitch(props, ref)
8698
8692
  onCheckedChange: onChange,
8699
8693
  ref: ref
8700
8694
  }), /*#__PURE__*/React.createElement(PrimitiveSwitch.Thumb, {
8701
- className: "pointer-events-none flex h-6 w-6 items-center justify-center rounded-full bg-white transition-transform will-change-transform group-disabled:opacity-50 group-aria-checked:translate-x-[100%]"
8695
+ className: "'will-change-transform flex h-6 w-6 items-center justify-center rounded-full bg-white transition-transform group-disabled:opacity-50 group-aria-checked:translate-x-[100%]"
8702
8696
  }, /*#__PURE__*/React.createElement(Icon, {
8703
8697
  name: "edit-simple",
8704
- className: "pointer-events-none !h-5 !w-5"
8698
+ className: "!h-5 !w-5"
8705
8699
  })));
8706
8700
  });
8707
8701
  ModeSwitch.displayName = 'ModeSwitch';
@@ -10404,15 +10398,6 @@ function configureReactTableOptions(options, props, localization) {
10404
10398
  // We don't want to expose internal Tanstack Table row, so we need to wrap enableRowSelection callback into additional function,
10405
10399
  // which receives the React Table Row object and passes row.original to a callback.
10406
10400
  const reactTableEnableRowSelection = typeof options.enableRowSelection === 'function' ? row => options.enableRowSelection(row.original) : options.enableRowSelection;
10407
- let getRowId;
10408
- if (props.rowIdentityAccessor) {
10409
- getRowId = (originalRow, index) => {
10410
- if (originalRow) {
10411
- return originalRow[props.rowIdentityAccessor];
10412
- }
10413
- return String(index);
10414
- };
10415
- }
10416
10401
  const tableOptions = {
10417
10402
  defaultColumn: {
10418
10403
  enableColumnFilter: options.enableFiltering || true,
@@ -10431,13 +10416,11 @@ function configureReactTableOptions(options, props, localization) {
10431
10416
  enableGrouping: true,
10432
10417
  enableHiding: (_options$enableColumn2 = options.enableColumnHiding) !== null && _options$enableColumn2 !== void 0 ? _options$enableColumn2 : false,
10433
10418
  enablePinning: (_options$enableColumn3 = options.enableColumnFreezing) !== null && _options$enableColumn3 !== void 0 ? _options$enableColumn3 : false,
10434
- enableRowPinning: true,
10435
10419
  enableRowSelection: reactTableEnableRowSelection !== null && reactTableEnableRowSelection !== void 0 ? reactTableEnableRowSelection : false,
10436
10420
  enableSorting: (_options$enableSortin = options.enableSorting) !== null && _options$enableSortin !== void 0 ? _options$enableSortin : false,
10437
10421
  // models for default features
10438
10422
  getExpandedRowModel: reactTable.getExpandedRowModel(),
10439
10423
  getGroupedRowModel: reactTable.getGroupedRowModel(),
10440
- getRowId,
10441
10424
  groupedColumnMode: false
10442
10425
  };
10443
10426
  if (tableOptions.enableColumnResizing) {
@@ -11770,7 +11753,7 @@ function useTableManager(props, meta, internalColumns) {
11770
11753
  rowDrag,
11771
11754
  rowDrop: rowDrop,
11772
11755
  rowExpansion: rowExpansion,
11773
- rowIdentityAccessor: props.rowIdentityAccessor,
11756
+ rowIdentityColumnId: props.rowIdentityColumnId,
11774
11757
  rowGoto,
11775
11758
  rowGroups: rowGroups,
11776
11759
  rowHeight,
@@ -12135,30 +12118,11 @@ function Row(props) {
12135
12118
  })));
12136
12119
  }
12137
12120
 
12138
- // scroll padding end is designed to always show half of the next row
12139
- function getScrollPaddingEndOffset(table, options) {
12140
- var _options$virtualiserP;
12141
- const tableMeta = table.options.meta;
12142
- let offset = 2 + ((_options$virtualiserP = options === null || options === void 0 ? void 0 : options.virtualiserPaddingEndOffset) !== null && _options$virtualiserP !== void 0 ? _options$virtualiserP : 0);
12143
- if (tableMeta.footer.isEnabled) {
12144
- offset += 1;
12145
- }
12146
- if (table.getHeaderGroups().length > 1) {
12147
- offset += table.getHeaderGroups().length - 1;
12148
- }
12149
- let height = ROW_HEIGHT_ESTIMATES.medium * offset;
12150
- const bottomRows = table.getBottomRows();
12151
- if (bottomRows.length) {
12152
- height += ROW_HEIGHT_ESTIMATES[tableMeta.rowHeight.height] * 1.4 * bottomRows.length;
12153
- }
12154
- return height;
12155
- }
12156
- function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex, options) {
12121
+ function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex) {
12157
12122
  var _table$getState$group, _virtualItems$padding, _virtualItems$padding2, _virtualItems$padding3, _ref, _virtualItems;
12158
12123
  const tableMeta = table.options.meta;
12159
- const rows = table.getCenterRows();
12124
+ const rows = table.getRowModel().rows;
12160
12125
  const isTableRowGrouped = !!((_table$getState$group = table.getState().grouping) !== null && _table$getState$group !== void 0 && _table$getState$group.length);
12161
- const bottomRows = table.getBottomRows();
12162
12126
  // expanded rows
12163
12127
  const {
12164
12128
  createRowMeasurer,
@@ -12168,6 +12132,9 @@ function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex, opt
12168
12132
  const rangeExtractor = useRowGroupVirtualisation(table);
12169
12133
  // account for thead and tfoot in the scroll area - both are always medium row height
12170
12134
  const scrollPaddingStart = ROW_HEIGHT_ESTIMATES.medium;
12135
+ // column groups offset the bottom padding :shrug:, multiplying by 1.5 ensures the bottom padding remains
12136
+ // consistent when there are groups and when there aren't. 1.5 is relatively arbitrary, but it gives alignment
12137
+ const scrollPaddingEnd = ROW_HEIGHT_ESTIMATES.medium * (table.getHeaderGroups().length > 1 ? 1.5 : 1);
12171
12138
  const virtualiser = reactVirtual.useVirtualizer({
12172
12139
  count: rows.length,
12173
12140
  estimateSize,
@@ -12176,8 +12143,7 @@ function useTableRenderer(renderers, table, tableRef, defaultRowActiveIndex, opt
12176
12143
  rangeExtractor,
12177
12144
  // correctly sets the scroll padding offset, e.g. when keyboard navigating rows in the list
12178
12145
  scrollPaddingStart,
12179
- scrollPaddingEnd: getScrollPaddingEndOffset(table, options),
12180
- paddingEnd: ROW_HEIGHT_ESTIMATES.medium * bottomRows.length
12146
+ scrollPaddingEnd: tableMeta.footer.isEnabled ? scrollPaddingEnd * 2 : scrollPaddingEnd
12181
12147
  });
12182
12148
  const totalSize = virtualiser.getTotalSize();
12183
12149
  const virtualItems = virtualiser.getVirtualItems();
@@ -12334,14 +12300,12 @@ function Actions$1(props) {
12334
12300
  actionsLength,
12335
12301
  data,
12336
12302
  isActiveRow,
12337
- rowId,
12338
- table
12303
+ rowId
12339
12304
  } = props;
12340
12305
  const {
12341
12306
  texts
12342
12307
  } = useLocalization();
12343
- // we don't want to document passing table, so it isn't on the type
12344
- const visibleActions = actions.map(action => action(data, rowId, table)).filter(action => !!action);
12308
+ const visibleActions = actions.map(action => action(data, rowId)).filter(action => !!action);
12345
12309
  const actionsOnRow = visibleActions.length === actionsLength ? visibleActions : visibleActions.slice(0, actionsLength - 1);
12346
12310
  const actionsInMenu = visibleActions.slice(visibleActions.length === actionsLength ? actionsLength : actionsLength - 1);
12347
12311
  const className = cn('flex justify-end text-right bg-[inherit] shadow-[-6px_0px_6px_var(--table-row-actions-shadow)] print:hidden');
@@ -12397,8 +12361,7 @@ const Cell = /*#__PURE__*/React__default.memo(function MemoedCell(context) {
12397
12361
  actionsLength: actionsLength,
12398
12362
  data: row.original,
12399
12363
  isActiveRow: isActiveRow,
12400
- rowId: row.id,
12401
- table: table
12364
+ rowId: row.id
12402
12365
  });
12403
12366
  }
12404
12367
  return null;
@@ -12648,13 +12611,13 @@ const INTERNAL_RENDERERS = {
12648
12611
  rowExpansion: renderer$2,
12649
12612
  rowSelection: renderer$3
12650
12613
  };
12651
- function useTable(props, externalRef, renderers, meta, options) {
12614
+ function useTable(props, externalRef, renderers, meta) {
12652
12615
  // create a ref and merge with the consumer's ref
12653
12616
  const ref = useMergedRef(externalRef);
12654
12617
  // configure the table
12655
12618
  const manager = useTableManager(props, meta, INTERNAL_RENDERERS);
12656
12619
  // configure the virtualised renderer
12657
- const renderer = useTableRenderer(renderers, manager.instance, ref, props.defaultRowActiveIndex, options);
12620
+ const renderer = useTableRenderer(renderers, manager.instance, ref, props.defaultRowActiveIndex);
12658
12621
  // configure dynamic styling
12659
12622
  const {
12660
12623
  style,
@@ -12755,10 +12718,7 @@ function GroupedCell(props) {
12755
12718
  index,
12756
12719
  isHighlighted
12757
12720
  } = props;
12758
- const {
12759
- table
12760
- } = cell.getContext();
12761
- const tableMeta = table.options.meta;
12721
+ const tableMeta = cell.getContext().table.options.meta;
12762
12722
  const columnMeta = cell.column.columnDef.meta;
12763
12723
  const attributes = getCellAttributes(cell, index, isHighlighted);
12764
12724
  const {
@@ -12776,8 +12736,7 @@ function GroupedCell(props) {
12776
12736
  colSpan: colSpan,
12777
12737
  rowActions: tableMeta.rowGroups.rowActionsForGroup,
12778
12738
  rowId: cell.row.id,
12779
- subRows: subRows,
12780
- table: table
12739
+ subRows: subRows
12781
12740
  }), content);
12782
12741
  }
12783
12742
  const MemoedGroupedCell = /*#__PURE__*/React__default.memo(function MemoedGroupedCell(props) {
@@ -12789,7 +12748,6 @@ const MemoedGroupedCell = /*#__PURE__*/React__default.memo(function MemoedGroupe
12789
12748
  rowActions,
12790
12749
  rowId,
12791
12750
  subRows,
12792
- table,
12793
12751
  ...attributes
12794
12752
  } = props;
12795
12753
  return /*#__PURE__*/React__default.createElement("td", Object.assign({}, attributes, {
@@ -12804,8 +12762,7 @@ const MemoedGroupedCell = /*#__PURE__*/React__default.memo(function MemoedGroupe
12804
12762
  actionsLength: 4,
12805
12763
  data: subRows,
12806
12764
  isActiveRow: true,
12807
- rowId: rowId,
12808
- table: table
12765
+ rowId: rowId
12809
12766
  })) : null);
12810
12767
  });
12811
12768
 
@@ -12945,7 +12902,7 @@ const DisplayRow = /*#__PURE__*/React__default.memo(function DisplayRow(props) {
12945
12902
  const expansionRef = React__default.useRef(null);
12946
12903
  const isExpanded = !!attributes['data-row-expanded'];
12947
12904
  useSetVirtualisedRowHeight(measureRow, ref.current, expansionRef.current, isExpanded);
12948
- const className = cn('group/row', otherAttributes.className, {
12905
+ const className = cn('group/row', {
12949
12906
  'hover:cursor-grab': tableMeta.rowDrag.isEnabled && typeof attributes.onClick !== 'function',
12950
12907
  'hover:cursor-pointer': typeof attributes.onClick === 'function'
12951
12908
  });
@@ -13739,7 +13696,7 @@ function Summary(props) {
13739
13696
 
13740
13697
  function Foot(props) {
13741
13698
  const nonGroupedHeaders = props.table.getFooterGroups()[0].headers.filter(header => !header.column.getIsGrouped());
13742
- return /*#__PURE__*/React__default.createElement("tfoot", null, props.children, /*#__PURE__*/React__default.createElement("tr", null, nonGroupedHeaders.map((header, index) => (/*#__PURE__*/React__default.createElement(Footer$3, {
13699
+ return /*#__PURE__*/React__default.createElement("tfoot", null, /*#__PURE__*/React__default.createElement("tr", null, nonGroupedHeaders.map((header, index) => (/*#__PURE__*/React__default.createElement(Footer$3, {
13743
13700
  key: header.id,
13744
13701
  header: header,
13745
13702
  index: index
@@ -16439,7 +16396,7 @@ function Control(props) {
16439
16396
  const dataType = column === null || column === void 0 ? void 0 : (_column$columnDef$met3 = column.columnDef.meta) === null || _column$columnDef$met3 === void 0 ? void 0 : _column$columnDef$met3.dataType;
16440
16397
  React.useEffect(() => {
16441
16398
  // Set value to false only after first render of the control (when it's undefined) after setting the FilterColumn value, because we don't want to change then the value every time filter is opened
16442
- if (controlRenderer === 'switch' && value === undefined) {
16399
+ if ((controlRenderer === 'switch' || controlRenderer === 'checkbox') && value === undefined) {
16443
16400
  onChange(false);
16444
16401
  }
16445
16402
  }, [controlRenderer]);
@@ -16463,6 +16420,12 @@ function Control(props) {
16463
16420
  checked: Boolean(value),
16464
16421
  onChange: onChange
16465
16422
  }));
16423
+ } else if (controlRenderer === 'checkbox') {
16424
+ return /*#__PURE__*/React__default.createElement(Checkbox, Object.assign({}, attributes, {
16425
+ className: "!m-1.5",
16426
+ checked: Boolean(value),
16427
+ onChange: onChange
16428
+ }));
16466
16429
  } else if ((controlRenderer === 'input' || controlRenderer === undefined) && dataType === 'number') {
16467
16430
  return /*#__PURE__*/React__default.createElement(Input, Object.assign({}, attributes, {
16468
16431
  className: "flex-grow",
@@ -16815,7 +16778,6 @@ function TableGrid(props) {
16815
16778
  var _table$state$grouping;
16816
16779
  const {
16817
16780
  enableHorizontalArrowKeyNavigation,
16818
- rowsForFooter,
16819
16781
  table,
16820
16782
  ...attributes
16821
16783
  } = props;
@@ -16823,6 +16785,8 @@ function TableGrid(props) {
16823
16785
  table.meta.rowActive.handleFocus(event, table.meta.length, table.renderer.scrollToIndex);
16824
16786
  } : undefined;
16825
16787
  const filterReason = getFilterReason(table);
16788
+ const searchNotApplied = !table.state.globalFilter || table.state.globalFilter === '';
16789
+ const filtersNotApplied = !table.state.columnFilters || table.state.columnFilters.length === 0;
16826
16790
  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, {
16827
16791
  id: table.id,
16828
16792
  "data-table-font-size": table.meta.fontSize.size,
@@ -16855,9 +16819,9 @@ function TableGrid(props) {
16855
16819
  ...table.renderer.style,
16856
16820
  height: table.renderer.style.height + ROW_HEIGHT_ESTIMATES[table.meta.rowHeight.height]
16857
16821
  } : table.renderer.style
16858
- }, table.renderer.rows, props.children), table.meta.footer.isEnabled ? /*#__PURE__*/React__default.createElement(Foot, {
16822
+ }, table.renderer.rows, searchNotApplied && filtersNotApplied && props.children), table.meta.footer.isEnabled ? /*#__PURE__*/React__default.createElement(Foot, {
16859
16823
  table: table.instance
16860
- }, rowsForFooter) : null)))));
16824
+ }) : null)))));
16861
16825
  }
16862
16826
 
16863
16827
  function Column$1(_) {
@@ -18360,16 +18324,33 @@ const useTableRowCreation = (data, tableRef) => {
18360
18324
 
18361
18325
  function useTableEditingListener(table, tableRef) {
18362
18326
  const tableMeta = table.options.meta;
18327
+ const completedRowsCount = tableMeta.editing.getCompletedRowsCount();
18363
18328
  const localization = useLocalization();
18329
+ const saveChanges = () => {
18330
+ requestAnimationFrame(() => {
18331
+ tableMeta.editing.saveChanges();
18332
+ });
18333
+ };
18364
18334
  // save when the row changes
18365
- // store the last row active index, otherwise everytime tableMeta.editing.saveChanges changes the hook runs again
18366
- const lastRowActiveIndexRef = React__default.useRef(tableMeta.rowActive.rowActiveIndex);
18367
18335
  useLazyEffect(() => {
18368
- if (tableMeta.editing.isEditing && tableMeta.rowActive.rowActiveIndex !== lastRowActiveIndexRef.current) {
18369
- lastRowActiveIndexRef.current = tableMeta.rowActive.rowActiveIndex;
18370
- tableMeta.editing.saveChanges(table);
18336
+ if (tableMeta.editing.isEditing) {
18337
+ saveChanges();
18338
+ }
18339
+ }, [tableMeta.rowActive.rowActiveIndex]);
18340
+ useLazyEffect(() => {
18341
+ if (tableMeta.editing.isEditing) {
18342
+ if (tableMeta.rowActive.rowActiveIndex === undefined) {
18343
+ tableMeta.rowActive.setRowActiveIndex(0);
18344
+ }
18345
+ } else {
18346
+ // save
18347
+ saveChanges();
18348
+ // reset detailed mode
18349
+ tableMeta.editing.toggleDetailedMode(false);
18350
+ // reset the last index back to the first focusable element, when editing gets turned off
18351
+ tableMeta.editing.setLastFocusedCellIndex(undefined);
18371
18352
  }
18372
- }, [tableMeta.rowActive.rowActiveIndex, tableMeta.editing.saveChanges]);
18353
+ }, [tableMeta.editing.isEditing]);
18373
18354
  // show a warning if the user navigates away without triggering save, such as using the browser back/forward button
18374
18355
  const hasChanges = tableMeta.editing.hasChanges();
18375
18356
  React__default.useEffect(() => {
@@ -18385,46 +18366,25 @@ function useTableEditingListener(table, tableRef) {
18385
18366
  window.removeEventListener('beforeunload', showUnsavedChangesWarning);
18386
18367
  };
18387
18368
  }, [tableMeta.editing.isEditing, hasChanges]);
18388
- const hasSavedChanges = tableMeta.editing.hasSaved();
18389
- useLazyEffect(() => {
18390
- if (hasSavedChanges) {
18369
+ React__default.useEffect(() => {
18370
+ if (completedRowsCount > 0) {
18391
18371
  resetHighlightedColumnIndexes(table.getState().globalFilter, table, localization);
18392
18372
  }
18393
- }, [hasSavedChanges]);
18373
+ }, [completedRowsCount]);
18394
18374
  React__default.useEffect(() => {
18395
18375
  const onClickOutside = event => {
18396
18376
  if (tableMeta.editing.isEditing) {
18397
- const element = event.target;
18398
- const insideTable = element.getAttribute('data-taco') === 'backdrop' || element.getAttribute('data-table') === 'editing-toggle' || isElementInsideOrTriggeredFromContainer(element, tableRef.current);
18399
- // users can click the white space below rows which could be inside the table, but a valid scenario to save
18400
- if (!insideTable || element.tagName === 'TABLE' || element.tagName === 'TBODY') {
18401
- tableMeta.editing.saveChanges(table);
18377
+ var _event$target$getAttr, _event$target;
18378
+ 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 : '';
18379
+ const insideTable = isElementInsideOrTriggeredFromContainer(event.target, tableRef.current) || element === 'backdrop';
18380
+ if (!insideTable) {
18381
+ saveChanges();
18402
18382
  }
18403
18383
  }
18404
18384
  };
18405
18385
  document.addEventListener('click', onClickOutside);
18406
18386
  return () => document.removeEventListener('click', onClickOutside);
18407
- }, [tableMeta.editing.isEditing, tableMeta.editing.saveChanges]);
18408
- const rows = table.getRowModel().rows;
18409
- // make sure pending changes are removed for rows that no longer exist
18410
- useLazyEffect(() => {
18411
- const pendingChanges = tableMeta.editing.getErrorsShownInAlert();
18412
- pendingChanges.forEach(pendingChange => {
18413
- try {
18414
- table.getRow(pendingChange.rowId);
18415
- } catch {
18416
- tableMeta.editing.discardChanges(pendingChange.rowId, table);
18417
- }
18418
- });
18419
- }, [rows.length]);
18420
- useGlobalKeyDown(tableMeta.editing.isEditing ? {
18421
- key: 's',
18422
- meta: true,
18423
- shift: false
18424
- } : undefined, event => {
18425
- event.preventDefault();
18426
- tableMeta.editing.saveChanges(table);
18427
- });
18387
+ }, [saveChanges, tableMeta.editing.isEditing]);
18428
18388
  }
18429
18389
 
18430
18390
  function willRowMove(cell, change, rowIndex, localization) {
@@ -18506,544 +18466,444 @@ function willRowMoveAfterSorting(cell, change, rowIndex) {
18506
18466
  }
18507
18467
  return ((_resortedRows$index = resortedRows[index]) === null || _resortedRows$index === void 0 ? void 0 : _resortedRows$index.id) !== cell.row.id;
18508
18468
  }
18509
- const TEMPORARY_ROW_ID_PREFIX = 'temp-';
18510
- function isTemporaryRow(rowId) {
18511
- return rowId === null || rowId === void 0 ? void 0 : rowId.startsWith(TEMPORARY_ROW_ID_PREFIX);
18469
+ function animateCreateRow(id) {
18470
+ const templateRow = document.querySelector(`[data-row-id="${id}"]`);
18471
+ if (templateRow) {
18472
+ const firstCell = templateRow.querySelector(':first-child');
18473
+ const checkbox = firstCell === null || firstCell === void 0 ? void 0 : firstCell.querySelector('[data-taco="checkbox"]');
18474
+ firstCell === null || firstCell === void 0 ? void 0 : firstCell.focus();
18475
+ if (checkbox) {
18476
+ setDataFocusAttribute(checkbox);
18477
+ }
18478
+ templateRow.scrollIntoView();
18479
+ const keyframes = [{
18480
+ background: '#b2c7ef'
18481
+ }, {
18482
+ background: '#ebebeb'
18483
+ }];
18484
+ for (const child of templateRow.children) {
18485
+ child.animate(keyframes, {
18486
+ duration: 1000,
18487
+ easing: 'ease-out'
18488
+ });
18489
+ }
18490
+ }
18512
18491
  }
18513
18492
 
18514
- const DELAY_BEFORE_REMOVING_SAVE_STATUS = 3000;
18515
- function reducer$2(state, action) {
18516
- const {
18517
- type,
18518
- rowId,
18519
- payload
18520
- } = action;
18521
- switch (type) {
18522
- case 'setCellValue':
18523
- {
18524
- const {
18525
- columnId,
18526
- row,
18527
- value
18528
- } = payload;
18529
- return {
18530
- ...state,
18531
- changes: {
18532
- ...state.changes,
18533
- rows: setWith(state.changes.rows, `${rowId}.${columnId}`, value, Object),
18534
- originals: setWith(state.changes.originals, rowId, row, Object)
18535
- }
18536
- };
18537
- }
18538
- case 'removeCellValue':
18539
- {
18540
- const {
18541
- columnId,
18542
- rowIdentityAccessor
18543
- } = payload;
18544
- const changes = omit(state.changes.rows, `${rowId}.${columnId}`);
18545
- // if there are no changes left, remove the row
18546
- if (!Object.keys(changes[rowId]).length) {
18547
- return reducer$2(state, {
18548
- type: 'removeRow',
18549
- rowId,
18550
- payload: {
18551
- rowIdentityAccessor
18552
- }
18553
- });
18554
- }
18555
- return {
18556
- ...state,
18557
- changes: {
18558
- ...state.changes,
18559
- rows: omit(state.changes.rows, `${rowId}.${columnId}`),
18560
- errors: omit(state.changes.errors, `${rowId}.cells.${columnId}`),
18561
- moveReasons: omit(state.changes.moveReasons, `${rowId}.${columnId}`)
18562
- }
18563
- };
18564
- }
18565
- case 'updateRow':
18566
- {
18567
- const {
18568
- cellErrors,
18569
- moveReasons,
18570
- original,
18571
- value
18572
- } = payload;
18573
- return {
18574
- ...state,
18575
- changes: {
18576
- ...state.changes,
18577
- rows: setWith(state.changes.rows, rowId, value, Object),
18578
- errors: setWith(state.changes.errors, `${rowId}.cells`, cellErrors !== null && cellErrors !== void 0 ? cellErrors : state.changes.errors.cells[rowId], Object),
18579
- originals: setWith(state.changes.originals, rowId, original !== null && original !== void 0 ? original : state.changes.originals[rowId], Object),
18580
- moveReasons: setWith(state.changes.moveReasons, rowId, moveReasons !== null && moveReasons !== void 0 ? moveReasons : state.changes.moveReasons[rowId], Object),
18581
- // status can be undefined, so don't use ??
18582
- status: setWith(state.changes.status, rowId, undefined, Object)
18583
- }
18584
- };
18585
- }
18586
- case 'removeRow':
18587
- {
18588
- const {
18589
- rowIdentityAccessor
18590
- } = payload;
18591
- return {
18592
- ...state,
18593
- changes: {
18594
- ...state.changes,
18595
- rows: omit(state.changes.rows, rowId),
18596
- errors: omit(state.changes.errors, rowId),
18597
- moveReasons: omit(state.changes.moveReasons, rowId),
18598
- originals: omit(state.changes.originals, rowId),
18599
- status: omit(state.changes.status, rowId)
18600
- },
18601
- temporaryRows: state.temporaryRows.filter(row => row[rowIdentityAccessor] !== rowId)
18602
- };
18603
- }
18604
- case 'setRowStatus':
18605
- {
18606
- const {
18607
- status
18608
- } = payload;
18609
- return {
18610
- ...state,
18611
- changes: {
18612
- ...state.changes,
18613
- status: status ? setWith(state.changes.status, rowId, status, Object) : omit(state.changes.status, rowId)
18614
- }
18615
- };
18616
- }
18617
- case 'setRowErrors':
18618
- {
18619
- const {
18620
- ...errors
18621
- } = payload;
18622
- return {
18623
- ...state,
18624
- changes: {
18625
- ...state.changes,
18626
- errors: setWith(state.changes.errors, rowId, errors, Object)
18627
- }
18628
- };
18629
- }
18630
- case 'createRow':
18631
- {
18632
- const {
18633
- value
18634
- } = payload;
18635
- return {
18636
- ...state,
18637
- temporaryRows: state.temporaryRows.concat(value),
18638
- changes: {
18639
- ...state.changes,
18640
- rows: setWith(state.changes.rows, rowId, value, Object),
18641
- originals: setWith(state.changes.originals, rowId, value, Object)
18642
- }
18643
- };
18644
- }
18645
- default:
18646
- return state;
18647
- }
18493
+ function useTableEditing(isEnabled = false, handleSave, handleChange, validator) {
18494
+ // used to switch the table into editing mode
18495
+ const [isEditing, toggleEditing] = React__default.useState(false);
18496
+ // used to switch the editing between "detailed" mode
18497
+ const [isDetailedMode, toggleDetailedMode] = React__default.useState(false);
18498
+ // store the last focused cell, so that up/down arrow key navigation remains in the same column
18499
+ const [lastFocusedCellIndex, setLastFocusedCellIndex] = useLastFocusedCellIndex();
18500
+ // store pending changes for each row
18501
+ // changes are saved as soon as the active row changes, so in most cases this will only contain the active row's changes
18502
+ // but not always - if validation or server requests fail when saving, those rows remain until the failure is resolved
18503
+ const pendingChangesFns = usePendingChanges(isEnabled, handleSave, handleChange, validator);
18504
+ useGlobalKeyDown(isEnabled && isEditing ? {
18505
+ key: 's',
18506
+ meta: true,
18507
+ shift: false
18508
+ } : undefined, event => {
18509
+ event.preventDefault();
18510
+ pendingChangesFns.saveChanges();
18511
+ });
18512
+ return {
18513
+ isEnabled,
18514
+ isEditing,
18515
+ isDetailedMode,
18516
+ toggleDetailedMode: isEnabled ? toggleDetailedMode : () => undefined,
18517
+ toggleEditing: isEnabled ? toggleEditing : () => undefined,
18518
+ lastFocusedCellIndex,
18519
+ setLastFocusedCellIndex,
18520
+ ...pendingChangesFns
18521
+ };
18648
18522
  }
18649
- function usePendingChangesState(handleSave, handleChange, rowIdentityAccessor, validator) {
18650
- const saveChanges = function (table, rowId = undefined) {
18523
+ function usePendingChanges(isEnabled, handleSave, handleChange, validator) {
18524
+ const saveChanges = function (rowId = undefined) {
18651
18525
  try {
18652
18526
  let _exit = false;
18653
18527
  if (!handleSave) {
18654
18528
  console.warn('Tried to save, but Table has no onEditingSave handler');
18655
- return Promise.resolve(false);
18529
+ return Promise.resolve();
18656
18530
  }
18657
- // sometimes we only want to save one row
18658
- const changes = rowId ? {
18659
- [rowId]: state.changes.rows[rowId]
18660
- } : state.changes.rows;
18661
- let completed = true;
18662
- const _temp9 = _forOf(Object.keys(changes), function (rowId) {
18663
- const status = getRowStatus(rowId);
18664
- return _catch(function () {
18665
- function _temp8(_result) {
18666
- return _exit ? _result : Promise.resolve(handleSave(changeSet)).then(function () {
18667
- // cleanup changes, we don't need them after saving
18668
- discardChanges(rowId, table);
18669
- // show the saved status, then remove it after a delay
18670
- setRowStatus(rowId, 'saved');
18671
- setTimeout(() => {
18672
- setRowStatus(rowId, undefined);
18673
- }, DELAY_BEFORE_REMOVING_SAVE_STATUS);
18674
- });
18675
- }
18676
- // don't try to save if - already saving, or there are known errors
18677
- if (status === 'saving' || status === 'errored') {
18678
- return;
18679
- }
18680
- setRowStatus(rowId, 'saving');
18681
- const changeSet = {
18682
- ...state.changes.originals[rowId],
18683
- ...changes[rowId]
18684
- };
18685
- // if we had to create a temporary id, delete it first - it's our data, not theirs
18686
- if (isTemporaryRow(changeSet[rowIdentityAccessor])) {
18687
- delete changeSet[rowIdentityAccessor];
18688
- }
18689
- // re-run validation, maybe a cell is already invalid but has never been blurred
18690
- const _temp7 = function () {
18691
- if (validator) {
18692
- return Promise.resolve(validator(changeSet)).then(function (errors) {
18693
- if (errors && Object.keys(errors).length) {
18694
- throw errors;
18531
+ // we save back to pendingChanges, so make a copy of it's state when save was triggered
18532
+ const changesToSave = rowId ? {
18533
+ [rowId]: pendingChanges[rowId]
18534
+ } : {
18535
+ ...pendingChanges
18536
+ };
18537
+ const changes = Object.keys(changesToSave);
18538
+ return Promise.resolve(function () {
18539
+ if (changes.length) {
18540
+ return _forOf(changes, function (rowId) {
18541
+ const pendingChange = changesToSave[rowId];
18542
+ const changeSet = getChangesetFromChanges(pendingChange);
18543
+ return _catch(function () {
18544
+ function _temp3(_result) {
18545
+ return _exit ? _result : Promise.resolve(handleSave(changeSet)).then(function () {
18546
+ // cleanup changes, we don't need them after saving
18547
+ resetChanges(rowId);
18548
+ setRowSaveStatus(rowId, 'complete');
18549
+ });
18550
+ }
18551
+ if (getRowSaveStatus(rowId) === 'pending') {
18552
+ _exit = true;
18553
+ return;
18554
+ }
18555
+ // set saving = true
18556
+ setRowSaveStatus(rowId, 'pending');
18557
+ // re-run validation, maybe a cell is already invalid but has never been blurred
18558
+ const _temp2 = function () {
18559
+ if (validator) {
18560
+ return Promise.resolve(validator(changeSet)).then(function (errors) {
18561
+ if (errors && Object.keys(errors).length) {
18562
+ throw errors;
18563
+ }
18564
+ });
18695
18565
  }
18696
- });
18697
- }
18698
- }();
18699
- return _temp7 && _temp7.then ? _temp7.then(_temp8) : _temp8(_temp7); // send new data to the server
18700
- }, function (error) {
18701
- var _error$response;
18702
- if (error instanceof ReferenceError || error instanceof TypeError || (error === null || error === void 0 ? void 0 : (_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.status) >= 500) {
18703
- console.error(error);
18704
- }
18705
- // the onEditingSave handler should throw errors when something fails, e.g. validation, network errors etc
18706
- // this code handles those errors and maps them either to row errors or cell specific errors
18707
- let rowError;
18708
- let cellErrors;
18709
- if (typeof error === 'string') {
18710
- rowError = error;
18711
- } else if (error instanceof Error) {
18712
- var _error$response2;
18713
- rowError = error.message;
18714
- // most of our apis return error objects within this shape
18715
- if (typeof ((_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.data) === 'object') {
18716
- var _error$response3;
18717
- cellErrors = (_error$response3 = error.response) === null || _error$response3 === void 0 ? void 0 : _error$response3.data;
18718
- }
18719
- } else if (typeof error === 'object') {
18720
- cellErrors = error;
18721
- }
18722
- if (rowError || cellErrors) {
18723
- dispatch({
18724
- type: 'setRowErrors',
18725
- rowId,
18726
- payload: {
18727
- row: rowError,
18728
- cells: cellErrors,
18729
- shouldShowErrorAlert: true
18566
+ }();
18567
+ return _temp2 && _temp2.then ? _temp2.then(_temp3) : _temp3(_temp2); // send new data to the server
18568
+ }, function (error) {
18569
+ // the onEditingSave handler should throw errors when something fails, e.g. validation, network errors etc
18570
+ // this code handles those errors and maps them either to row errors or cell specific errors
18571
+ let rowError;
18572
+ let cellErrors;
18573
+ if (typeof error === 'string') {
18574
+ rowError = error;
18575
+ } else if (error instanceof Error) {
18576
+ var _error$response;
18577
+ rowError = error.message;
18578
+ // most of our apis return error objects within this shape
18579
+ if (typeof ((_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.data) === 'object') {
18580
+ var _error$response2;
18581
+ cellErrors = (_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.data;
18582
+ }
18583
+ } else if (typeof error === 'object') {
18584
+ cellErrors = error;
18585
+ }
18586
+ if (rowError || cellErrors) {
18587
+ setPendingChanges(currentChanges => {
18588
+ const nextChanges = {
18589
+ ...currentChanges
18590
+ };
18591
+ nextChanges[rowId]._meta.errors = {
18592
+ row: rowError,
18593
+ cells: cellErrors,
18594
+ shouldShowErrorAlert: true
18595
+ };
18596
+ return nextChanges;
18597
+ });
18730
18598
  }
18599
+ setRowSaveStatus(rowId, undefined);
18731
18600
  });
18732
- }
18733
- setRowStatus(rowId, 'errored');
18734
- completed = false;
18735
- });
18736
- }, function () {
18737
- return _exit;
18738
- });
18739
- return Promise.resolve(_temp9 && _temp9.then ? _temp9.then(function (_result3) {
18740
- return _exit ? _result3 : completed;
18741
- }) : _exit ? _temp9 : completed);
18601
+ }, function () {
18602
+ return _exit;
18603
+ });
18604
+ }
18605
+ }());
18742
18606
  } catch (e) {
18743
18607
  return Promise.reject(e);
18744
18608
  }
18745
18609
  };
18746
- const onCellChanged = function (cell, rowIndex) {
18610
+ const validateCell = function (cell) {
18747
18611
  try {
18748
- function _temp6() {
18749
- var _state$changes$errors8;
18750
- function _temp4() {
18751
- // only set errors and move reasons for the cells we're currently acting on
18752
- // why? because the UX is not good if we set them for cells the user hasn't touched yet
18753
- const cellsToActOn = [cell.column.id, ...Object.keys(updatesForOtherCells)];
18754
- const allCells = cell.row._getAllCellsByColumnId();
18755
- cellsToActOn.forEach(accessor => {
18756
- if (validationErrors[accessor]) {
18757
- nextCellErrors[accessor] = validationErrors[accessor];
18758
- // don't show move indicator for cells with errors, they aren't valid and can't be saved
18759
- delete nextMoveReasons[accessor];
18760
- } else {
18761
- var _allCells$accessor;
18762
- // there isn't any error in this run, remove any error set in state
18763
- delete nextCellErrors[accessor];
18764
- if ((_allCells$accessor = allCells[accessor]) !== null && _allCells$accessor !== void 0 && _allCells$accessor.column.getIsSorted()) {
18765
- // run row move determination
18766
- const reason = willRowMove(cell, nextChanges[accessor], rowIndex, localization);
18767
- // if the row will move based on this change save why, otherwise delete any existing state
18768
- if (reason) {
18769
- nextMoveReasons[accessor] = reason;
18770
- } else {
18771
- delete nextMoveReasons[accessor];
18772
- }
18773
- }
18774
- }
18775
- });
18776
- dispatch({
18777
- type: 'updateRow',
18778
- rowId: cell.row.id,
18779
- payload: {
18780
- cellErrors: nextCellErrors,
18781
- moveReasons: nextMoveReasons,
18782
- value: nextChanges
18783
- }
18784
- });
18785
- }
18786
- // create a projection of the next state, so we can act against it
18787
- const nextChanges = {
18788
- ...state.changes.rows[cell.row.id],
18789
- ...updatesForOtherCells
18790
- };
18791
- const nextMoveReasons = {
18792
- ...state.changes.moveReasons[cell.row.id]
18793
- };
18794
- const nextCellErrors = {
18795
- ...((_state$changes$errors8 = state.changes.errors[cell.row.id]) === null || _state$changes$errors8 === void 0 ? void 0 : _state$changes$errors8.cells)
18796
- };
18797
- // run validation
18798
- let validationErrors = {};
18799
- const _temp3 = function () {
18800
- if (validator) {
18801
- const nextRowValue = {
18802
- ...state.changes.originals[cell.row.id],
18803
- ...changes,
18804
- ...updatesForOtherCells
18805
- };
18806
- return Promise.resolve(validator(nextRowValue)).then(function (_validator2) {
18807
- validationErrors = _validator2 !== null && _validator2 !== void 0 ? _validator2 : {};
18808
- });
18809
- }
18810
- }();
18811
- return _temp3 && _temp3.then ? _temp3.then(_temp4) : _temp4(_temp3);
18812
- }
18813
- const changes = state.changes.rows[cell.row.id];
18814
- if (!changes) {
18612
+ if (!validator || !isEnabled) {
18815
18613
  return Promise.resolve();
18816
18614
  }
18817
- let updatesForOtherCells = {};
18818
- // run the updater handler if there is one, to see if there are any other cells to update
18819
- const _temp5 = function () {
18820
- if (typeof handleChange === 'function') {
18821
- const previousRowValue = {
18822
- ...state.changes.originals[cell.row.id]
18823
- };
18824
- const nextRowValue = {
18825
- ...state.changes.originals[cell.row.id],
18826
- ...changes
18827
- };
18828
- return Promise.resolve(handleChange(cell.column.id, changes[cell.column.id], nextRowValue, previousRowValue)).then(function (_handleChange) {
18829
- updatesForOtherCells = _handleChange !== null && _handleChange !== void 0 ? _handleChange : {};
18615
+ const changeSet = getChangesetFromChanges(pendingChanges[cell.row.id]);
18616
+ // only validate if the cell being blurred actually has any changes
18617
+ const _temp = function () {
18618
+ if (cell.column.id in changeSet) {
18619
+ return Promise.resolve(validator(changeSet)).then(function (errors) {
18620
+ setPendingChanges(currentChanges => {
18621
+ const nextChanges = {
18622
+ ...currentChanges
18623
+ };
18624
+ nextChanges[cell.row.id]._meta = {
18625
+ ...nextChanges[cell.row.id]._meta,
18626
+ errors: {
18627
+ ...nextChanges[cell.row.id]._meta.errors,
18628
+ cells: errors,
18629
+ shouldShowErrorAlert: !Object.keys(errors).length ? false : nextChanges[cell.row.id]._meta.errors.shouldShowErrorAlert
18630
+ }
18631
+ };
18632
+ return nextChanges;
18633
+ });
18830
18634
  });
18831
18635
  }
18832
18636
  }();
18833
- return Promise.resolve(_temp5 && _temp5.then ? _temp5.then(_temp6) : _temp6(_temp5));
18637
+ return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
18834
18638
  } catch (e) {
18835
18639
  return Promise.reject(e);
18836
18640
  }
18837
- }; // general
18838
- const createRow = function (data) {
18641
+ };
18642
+ const setCellValue = function (cell, change, rowIndex) {
18839
18643
  try {
18840
- const newRowId = `${TEMPORARY_ROW_ID_PREFIX}${uuid.v4()}`;
18841
- const value = {
18842
- ...data,
18843
- [rowIdentityAccessor]: newRowId
18644
+ const changes = {
18645
+ [cell.column.id]: change
18844
18646
  };
18845
- dispatch({
18846
- type: 'createRow',
18847
- rowId: newRowId,
18848
- payload: {
18849
- value
18850
- }
18647
+ setPendingChanges(currentChanges => {
18648
+ const nextChanges = createPendingChangesSetter(currentChanges, cell.row, rowIndex, changes, localization);
18649
+ pendingChangesUpdater.syncCellChanges(nextChanges);
18650
+ return nextChanges;
18851
18651
  });
18852
- return Promise.resolve(newRowId);
18652
+ pendingChangesUpdater.runCellUpdates(changes, cell, rowIndex);
18653
+ return Promise.resolve();
18853
18654
  } catch (e) {
18854
18655
  return Promise.reject(e);
18855
18656
  }
18856
- }; // cells
18857
- // rows
18858
- const setRowValue = function (rowId, original, value) {
18657
+ };
18658
+ const addCreatedRowChangeset = function (row) {
18859
18659
  try {
18860
- function _temp2() {
18861
- dispatch({
18862
- type: 'updateRow',
18863
- rowId,
18864
- payload: {
18865
- cellErrors,
18866
- original,
18867
- value
18660
+ const cells = row.getAllCells();
18661
+ setPendingChanges(currentChanges => {
18662
+ return cells.reduce((changes, cell) => {
18663
+ if (cell.getValue()) {
18664
+ var _currentChanges$cell$, _currentChanges$cell$2, _currentChanges$cell$3;
18665
+ return {
18666
+ ...changes,
18667
+ [cell.row.id]: {
18668
+ ...changes[cell.row.id],
18669
+ [cell.column.id]: cell.getValue(),
18670
+ _meta: {
18671
+ ...((_currentChanges$cell$ = currentChanges[cell.row.id]) === null || _currentChanges$cell$ === void 0 ? void 0 : _currentChanges$cell$._meta),
18672
+ original: cell.row.original,
18673
+ moveReason: {
18674
+ ...((_currentChanges$cell$2 = currentChanges[cell.row.id]) === null || _currentChanges$cell$2 === void 0 ? void 0 : _currentChanges$cell$2._meta.moveReason)
18675
+ },
18676
+ errors: {
18677
+ ...((_currentChanges$cell$3 = currentChanges[cell.row.id]) === null || _currentChanges$cell$3 === void 0 ? void 0 : _currentChanges$cell$3._meta.errors)
18678
+ }
18679
+ }
18680
+ }
18681
+ };
18682
+ } else {
18683
+ return changes;
18868
18684
  }
18869
- });
18870
- }
18871
- let cellErrors;
18872
- const _temp = function () {
18873
- if (validator) {
18874
- const row = {
18875
- ...original,
18876
- ...value
18877
- };
18878
- return Promise.resolve(validator(row)).then(function (_validator) {
18879
- cellErrors = _validator !== null && _validator !== void 0 ? _validator : {};
18880
- });
18881
- }
18882
- }();
18883
- return Promise.resolve(_temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp));
18685
+ }, currentChanges);
18686
+ });
18687
+ return Promise.resolve();
18884
18688
  } catch (e) {
18885
18689
  return Promise.reject(e);
18886
18690
  }
18887
18691
  };
18888
18692
  const localization = useLocalization();
18889
- const [state, dispatch] = React__default.useReducer(reducer$2, {
18890
- changes: {
18891
- rows: {},
18892
- errors: {},
18893
- moveReasons: {},
18894
- originals: {},
18895
- status: {}
18896
- },
18897
- temporaryRows: []
18898
- });
18899
- function getRowValue(rowId) {
18900
- var _state$changes$rows$r, _state$changes$rows;
18901
- return (_state$changes$rows$r = (_state$changes$rows = state.changes.rows) === null || _state$changes$rows === void 0 ? void 0 : _state$changes$rows[rowId]) !== null && _state$changes$rows$r !== void 0 ? _state$changes$rows$r : undefined;
18693
+ const [pendingChanges, setPendingChanges] = React__default.useState({});
18694
+ // we maintain save status as separate state because 'complete' needs to briefly show after pendingChanges are deleted
18695
+ const [saveStates, setSaveState] = React__default.useState({});
18696
+ function getCellValue(cell) {
18697
+ var _pendingChanges$cell$;
18698
+ return (_pendingChanges$cell$ = pendingChanges[cell.row.id]) === null || _pendingChanges$cell$ === void 0 ? void 0 : _pendingChanges$cell$[cell.column.id];
18902
18699
  }
18903
- function getRowMoveReason(rowId) {
18904
- var _Object$values$, _state$changes$moveRe, _state$changes$moveRe2;
18905
- return (_Object$values$ = Object.values((_state$changes$moveRe = (_state$changes$moveRe2 = state.changes.moveReasons) === null || _state$changes$moveRe2 === void 0 ? void 0 : _state$changes$moveRe2[rowId]) !== null && _state$changes$moveRe !== void 0 ? _state$changes$moveRe : {})[0]) !== null && _Object$values$ !== void 0 ? _Object$values$ : undefined;
18700
+ function getCellError(cell) {
18701
+ var _pendingChanges$cell$2, _pendingChanges$cell$3, _pendingChanges$cell$4;
18702
+ 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];
18906
18703
  }
18704
+ const pendingChangesUpdater = usePendingChangesUpdater(handleChange, setPendingChanges);
18907
18705
  function hasRowErrors(rowId) {
18908
- var _state$changes$errors, _state$changes$errors2, _state$changes$errors3;
18909
- return !!((_state$changes$errors = state.changes.errors[rowId]) !== null && _state$changes$errors !== void 0 && _state$changes$errors.row) || !!Object.keys((_state$changes$errors2 = (_state$changes$errors3 = state.changes.errors[rowId]) === null || _state$changes$errors3 === void 0 ? void 0 : _state$changes$errors3.cells) !== null && _state$changes$errors2 !== void 0 ? _state$changes$errors2 : {}).length;
18706
+ var _pendingChanges$rowId, _pendingChanges$rowId2, _pendingChanges$rowId3, _pendingChanges$rowId4, _pendingChanges$rowId5;
18707
+ if (!isEnabled) {
18708
+ return false;
18709
+ }
18710
+ 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;
18910
18711
  }
18911
- function hasRowErrorsShownInAlert(rowId) {
18912
- var _state$changes$errors4;
18913
- return hasRowErrors(rowId) && !!((_state$changes$errors4 = state.changes.errors[rowId]) !== null && _state$changes$errors4 !== void 0 && _state$changes$errors4.shouldShowErrorAlert);
18712
+ function hasRowErrorsSeen(rowId) {
18713
+ var _pendingChanges$rowId6;
18714
+ if (!isEnabled) {
18715
+ return false;
18716
+ }
18717
+ return hasRowErrors(rowId) && !!((_pendingChanges$rowId6 = pendingChanges[rowId]._meta.errors) !== null && _pendingChanges$rowId6 !== void 0 && _pendingChanges$rowId6.shouldShowErrorAlert);
18914
18718
  }
18915
- function getRowStatus(rowId) {
18916
- return state.changes.status[rowId];
18719
+ function getRowPendingChange(rowId) {
18720
+ const rowPendingChanges = pendingChanges[rowId];
18721
+ if (rowPendingChanges) {
18722
+ const {
18723
+ _meta,
18724
+ ...pendingChange
18725
+ } = rowPendingChanges;
18726
+ return pendingChange;
18727
+ }
18728
+ return undefined;
18917
18729
  }
18918
- function setRowStatus(rowId, status) {
18919
- dispatch({
18920
- type: 'setRowStatus',
18921
- rowId,
18922
- payload: {
18923
- status
18730
+ function getRowSaveStatus(rowId) {
18731
+ if (!isEnabled) {
18732
+ return false;
18733
+ }
18734
+ return saveStates[rowId];
18735
+ }
18736
+ function setRowSaveStatus(rowId, status) {
18737
+ setSaveState(currentStates => {
18738
+ const nextStates = {
18739
+ ...currentStates
18740
+ };
18741
+ if (status) {
18742
+ nextStates[rowId] = status;
18743
+ } else {
18744
+ delete nextStates[rowId];
18924
18745
  }
18746
+ return nextStates;
18925
18747
  });
18926
18748
  }
18927
- function setCellValue(cell, value) {
18928
- const rowId = cell.row.id;
18929
- const columnId = cell.column.id;
18930
- // update if the change is different to the original value
18931
- if (value !== cell.row.original[columnId]) {
18932
- dispatch({
18933
- type: 'setCellValue',
18934
- rowId,
18935
- payload: {
18936
- columnId,
18937
- row: cell.row.original,
18938
- value
18939
- }
18940
- });
18941
- }
18942
- // otherwise remove any previous change - no point saving the same value
18943
- else if (cell.row.id in state.changes.rows) {
18944
- dispatch({
18945
- type: 'removeCellValue',
18946
- rowId,
18947
- payload: {
18948
- columnId,
18949
- rowIdentityAccessor
18950
- }
18951
- });
18952
- }
18953
- }
18954
- function getCellValue(cell) {
18955
- var _state$changes$rows2, _state$changes$rows2$;
18956
- return (_state$changes$rows2 = state.changes.rows) === null || _state$changes$rows2 === void 0 ? void 0 : (_state$changes$rows2$ = _state$changes$rows2[cell.row.id]) === null || _state$changes$rows2$ === void 0 ? void 0 : _state$changes$rows2$[cell.column.id];
18749
+ function getRowMoveReason(rowId) {
18750
+ var _pendingChanges$rowId7;
18751
+ return (_pendingChanges$rowId7 = pendingChanges[rowId]) !== null && _pendingChanges$rowId7 !== void 0 && _pendingChanges$rowId7._meta.moveReason ? Object.values(pendingChanges[rowId]._meta.moveReason)[0] : undefined;
18957
18752
  }
18958
- function getCellError(cell) {
18959
- var _state$changes$errors5, _state$changes$errors6, _state$changes$errors7;
18960
- return (_state$changes$errors5 = state.changes.errors) === null || _state$changes$errors5 === void 0 ? void 0 : (_state$changes$errors6 = _state$changes$errors5[cell.row.id]) === null || _state$changes$errors6 === void 0 ? void 0 : (_state$changes$errors7 = _state$changes$errors6.cells) === null || _state$changes$errors7 === void 0 ? void 0 : _state$changes$errors7[cell.column.id];
18753
+ function hasChanges(rowId) {
18754
+ if (!isEnabled) {
18755
+ return false;
18756
+ }
18757
+ return rowId ? !!pendingChanges[rowId] : !!Object.keys(pendingChanges).length;
18961
18758
  }
18962
- function getErrorsShownInAlert() {
18963
- const rowsWithErrors = Object.keys(state.changes.errors);
18964
- if (!rowsWithErrors.length) {
18965
- return [];
18759
+ function hasAlertErrors() {
18760
+ if (!isEnabled) {
18761
+ return false;
18966
18762
  }
18967
- return rowsWithErrors.filter(hasRowErrorsShownInAlert).map(rowId => ({
18763
+ return !!getAlertErrors().length;
18764
+ }
18765
+ function getAlertErrors() {
18766
+ return Object.keys(pendingChanges).filter(hasRowErrorsSeen).map(rowId => ({
18968
18767
  rowId,
18969
- changes: state.changes.rows[rowId],
18970
- errors: state.changes.errors[rowId]
18768
+ pendingChange: pendingChanges[rowId]
18971
18769
  }));
18972
18770
  }
18973
- function hasSaved() {
18974
- return !!Object.values(state.changes.status).filter(value => value === 'saved').length;
18975
- }
18976
- function hasChanges(rowId) {
18977
- return rowId ? !!state.changes.rows[rowId] : !!Object.keys(state.changes.rows).length;
18978
- }
18979
- function discardChanges(rowId, table) {
18980
- // remove any new rows from pinned state before discarding them
18981
- table.resetRowPinning(true);
18982
- dispatch({
18983
- type: 'removeRow',
18984
- rowId,
18985
- payload: {
18986
- rowIdentityAccessor
18987
- }
18771
+ function resetChanges(rowId) {
18772
+ setPendingChanges(currentChanges => {
18773
+ const nextChanges = {
18774
+ ...currentChanges
18775
+ };
18776
+ delete nextChanges[rowId];
18777
+ return nextChanges;
18988
18778
  });
18989
18779
  }
18780
+ function getCompletedRowsCount() {
18781
+ return Object.values(saveStates).filter(value => value === 'complete').length;
18782
+ }
18990
18783
  return {
18991
- // row
18992
- setRowValue,
18993
- getRowValue,
18994
- getRowMoveReason,
18995
- hasRowErrors,
18996
- hasRowErrorsShownInAlert,
18997
- getRowStatus,
18998
- setRowStatus,
18999
- // cells
19000
- setCellValue,
19001
18784
  getCellValue,
19002
18785
  getCellError,
19003
- onCellChanged,
19004
- // general
19005
- getErrorsShownInAlert,
18786
+ setCellValue,
18787
+ validateCell,
18788
+ addCreatedRowChangeset,
19006
18789
  hasChanges,
18790
+ hasAlertErrors,
18791
+ getAlertErrors,
19007
18792
  saveChanges,
19008
- discardChanges,
19009
- hasSaved,
19010
- // new rows
19011
- createRow,
19012
- temporaryRows: state.temporaryRows
18793
+ resetChanges,
18794
+ hasRowErrors,
18795
+ hasRowErrorsSeen,
18796
+ getRowPendingChange,
18797
+ getRowSaveStatus,
18798
+ setRowSaveStatus,
18799
+ getRowMoveReason,
18800
+ getCompletedRowsCount
19013
18801
  };
19014
18802
  }
19015
-
19016
- function useTableEditing(isEnabled = false, handleSave, handleChange, rowIdentityAccessor, validator) {
19017
- // used to switch the table into editing mode
19018
- const [isEditing, setEditing] = React__default.useState(false);
19019
- // used to switch the editing between "detailed" mode
19020
- const [isDetailedMode, toggleDetailedMode] = React__default.useState(false);
19021
- // used to contain ref to the create button
19022
- const createRowButtonRef = React__default.useRef(null);
18803
+ function useLastFocusedCellIndex() {
19023
18804
  // store the last focused cell, so that up/down arrow key navigation remains in the same column
19024
- const [lastFocusedCellIndex, setLastFocusedCellIndex] = React__default.useState(undefined);
19025
- const pendingChangesFns = usePendingChangesState(handleSave, handleChange, rowIdentityAccessor, validator);
19026
- function toggleEditing(enabled, table) {
19027
- if (!enabled) {
19028
- // save
19029
- pendingChangesFns.saveChanges(table);
19030
- // reset detailed mode
19031
- toggleDetailedMode(false);
19032
- // reset the last index back to the first focusable element, when editing gets turned off
19033
- setLastFocusedCellIndex(undefined);
18805
+ const lastFocusedCellIndexRef = React__default.useRef(undefined);
18806
+ const setLastFocusedCellIndex = React__default.useCallback(index => {
18807
+ lastFocusedCellIndexRef.current = index;
18808
+ }, []);
18809
+ return [lastFocusedCellIndexRef.current, setLastFocusedCellIndex];
18810
+ }
18811
+ function usePendingChangesUpdater(handleChange, setPendingChanges) {
18812
+ const localization = useLocalization();
18813
+ const updatersRef = React__default.useRef({});
18814
+ const runCellUpdates = React__default.useCallback(lodash.debounce(function (changes, cell, rowIndex) {
18815
+ try {
18816
+ const _temp4 = function () {
18817
+ if (typeof handleChange === 'function') {
18818
+ const previousValues = {
18819
+ ...cell.row.original,
18820
+ ...getChangesetFromChanges(updatersRef.current[cell.row.id])
18821
+ };
18822
+ const nextValues = {
18823
+ ...previousValues,
18824
+ ...changes
18825
+ };
18826
+ return Promise.resolve(handleChange(cell.column.id, changes[cell.column.id], nextValues, previousValues)).then(function (updates) {
18827
+ if (updates && Object.keys(updates).length) {
18828
+ setPendingChanges(currentChanges => createPendingChangesSetter(currentChanges, cell.row, rowIndex, updates, localization));
18829
+ }
18830
+ });
18831
+ }
18832
+ }();
18833
+ return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(function () {}) : void 0);
18834
+ } catch (e) {
18835
+ return Promise.reject(e);
19034
18836
  }
19035
- setEditing(enabled);
18837
+ }, 250), []);
18838
+ function syncCellChanges(changes) {
18839
+ updatersRef.current = changes;
19036
18840
  }
19037
18841
  return {
19038
- isEnabled,
19039
- isEditing,
19040
- isDetailedMode,
19041
- toggleDetailedMode: isEnabled ? toggleDetailedMode : () => undefined,
19042
- toggleEditing: isEnabled ? toggleEditing : () => undefined,
19043
- lastFocusedCellIndex,
19044
- setLastFocusedCellIndex,
19045
- createRowButtonRef,
19046
- ...pendingChangesFns
18842
+ syncCellChanges,
18843
+ runCellUpdates
18844
+ };
18845
+ }
18846
+ function createPendingChangesSetter(currentChanges, row, rowIndex, changes, localization) {
18847
+ var _currentChanges$row$i, _currentChanges$row$i2, _currentChanges$row$i3;
18848
+ // prepare
18849
+ const nextChanges = {
18850
+ ...currentChanges
18851
+ };
18852
+ const rowChanges = {
18853
+ ...currentChanges[row.id],
18854
+ _meta: {
18855
+ ...((_currentChanges$row$i = currentChanges[row.id]) === null || _currentChanges$row$i === void 0 ? void 0 : _currentChanges$row$i._meta),
18856
+ original: row.original,
18857
+ moveReason: {
18858
+ ...((_currentChanges$row$i2 = currentChanges[row.id]) === null || _currentChanges$row$i2 === void 0 ? void 0 : _currentChanges$row$i2._meta.moveReason)
18859
+ },
18860
+ errors: {
18861
+ ...((_currentChanges$row$i3 = currentChanges[row.id]) === null || _currentChanges$row$i3 === void 0 ? void 0 : _currentChanges$row$i3._meta.errors)
18862
+ }
18863
+ }
18864
+ };
18865
+ // run changes
18866
+ const cells = row._getAllCellsByColumnId();
18867
+ for (const [accessor, change] of Object.entries(changes)) {
18868
+ // update if the change is different to the original (saved) value,
18869
+ // otherwise remove any change - no point saving the same value
18870
+ if (change !== row.original[accessor]) {
18871
+ rowChanges[accessor] = change;
18872
+ // consumers sometimes include properties in onEditingChange that aren't rendered as columns, we need to guard against that.
18873
+ // eslint-disable-next-line no-prototype-builtins
18874
+ if (cells.hasOwnProperty(accessor)) {
18875
+ // determine if the row will move position based on this change, and save why it will move
18876
+ const reason = willRowMove(cells[accessor], change, rowIndex, localization);
18877
+ if (reason) {
18878
+ rowChanges._meta.moveReason[accessor] = reason;
18879
+ } else {
18880
+ delete rowChanges._meta.moveReason[accessor];
18881
+ }
18882
+ }
18883
+ } else {
18884
+ delete rowChanges[accessor];
18885
+ delete rowChanges._meta.moveReason[accessor];
18886
+ }
18887
+ }
18888
+ // set changes
18889
+ // or delete if there are no changes left, so that we don't store changes with unchanged data
18890
+ if (Object.keys(rowChanges).filter(k => k !== '_meta').length) {
18891
+ nextChanges[row.id] = rowChanges;
18892
+ } else {
18893
+ delete nextChanges[row.id];
18894
+ }
18895
+ return nextChanges;
18896
+ }
18897
+ function getChangesetFromChanges(changes) {
18898
+ // extract the original data from the row changes
18899
+ const {
18900
+ _meta,
18901
+ ...changeset
18902
+ } = changes !== null && changes !== void 0 ? changes : {};
18903
+ // and mix them in with the changes, ready to send to the server
18904
+ return {
18905
+ ...(_meta === null || _meta === void 0 ? void 0 : _meta.original),
18906
+ ...changeset
19047
18907
  };
19048
18908
  }
19049
18909
 
@@ -19285,28 +19145,13 @@ function EditingControlCell(props) {
19285
19145
  const {
19286
19146
  rowIndex
19287
19147
  } = React__default.useContext(RowContext);
19288
- const {
19289
- table
19290
- } = cell.getContext();
19291
- const tableMeta = table.options.meta;
19148
+ const tableMeta = cell.getContext().table.options.meta;
19292
19149
  const columnMeta = cell.column.columnDef.meta;
19293
19150
  const isActiveRow = tableMeta.rowActive.rowActiveIndex === rowIndex;
19294
- const type = (_columnMeta$control = columnMeta.control) !== null && _columnMeta$control !== void 0 ? _columnMeta$control : 'input';
19295
19151
  const handleFocus = useEditingCellAutofocus(props);
19296
- // some controls, like select2, should trigger cell changed (validation, updates) as the value changes
19297
- const hasNonTextControl = React__default.useMemo(() => {
19298
- var _cellRef$current;
19299
- return typeof type === 'function' && !!((_cellRef$current = cellRef.current) !== null && _cellRef$current !== void 0 && _cellRef$current.querySelector('[data-taco="Select2"],[data-taco="switch"],[data-taco="checkbox"]'));
19300
- }, [cellRef.current]);
19301
- const handleChange = value => {
19302
- tableMeta.editing.setCellValue(cell, value);
19303
- if (hasNonTextControl) {
19304
- tableMeta.editing.onCellChanged(cell, rowIndex);
19305
- }
19306
- };
19307
19152
  const handleBlur = () => {
19308
19153
  tableMeta.editing.toggleDetailedMode(false);
19309
- tableMeta.editing.onCellChanged(cell, rowIndex);
19154
+ tableMeta.editing.validateCell(cell);
19310
19155
  };
19311
19156
  // ensure that blur runs when the cell gets unmounted (when vertically arrow key navigating)
19312
19157
  React__default.useEffect(() => {
@@ -19326,12 +19171,13 @@ function EditingControlCell(props) {
19326
19171
  isDetailedMode: tableMeta.editing.isDetailedMode,
19327
19172
  isTruncated: !!columnMeta.enableTruncate,
19328
19173
  onBlur: handleBlur,
19329
- onChange: handleChange,
19174
+ onChange: value => tableMeta.editing.setCellValue(cell, value, rowIndex),
19330
19175
  row: cell.row.original,
19331
- rowPendingChanges: tableMeta.editing.getRowValue(cell.row.id),
19176
+ rowPendingChanges: tableMeta.editing.getRowPendingChange(cell.row.id),
19332
19177
  tabIndex: isActiveRow ? 0 : -1,
19178
+ toggleEditing: tableMeta.editing.toggleEditing,
19333
19179
  toggleDetailedMode: tableMeta.editing.toggleDetailedMode,
19334
- type,
19180
+ type: (_columnMeta$control = columnMeta.control) !== null && _columnMeta$control !== void 0 ? _columnMeta$control : 'input',
19335
19181
  value: cell.getValue()
19336
19182
  };
19337
19183
  const cellAttributes = {
@@ -19364,6 +19210,7 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19364
19210
  row,
19365
19211
  rowPendingChanges,
19366
19212
  tabIndex = -1,
19213
+ toggleEditing,
19367
19214
  toggleDetailedMode,
19368
19215
  type = 'input',
19369
19216
  value
@@ -19394,6 +19241,13 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19394
19241
  ref: controlRef
19395
19242
  }));
19396
19243
  }
19244
+ if (type === 'checkbox') {
19245
+ return /*#__PURE__*/React__default.createElement(Checkbox, Object.assign({}, commonProps, {
19246
+ checked: Boolean(value),
19247
+ onChange: onChange,
19248
+ ref: controlRef
19249
+ }));
19250
+ }
19397
19251
  const handleInputKeyDown = event => {
19398
19252
  const target = event.target;
19399
19253
  if (target.readOnly) {
@@ -19422,8 +19276,8 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19422
19276
  }
19423
19277
  // reset the value, or exit edit mode when pressing escape
19424
19278
  if (event.key === 'Escape') {
19279
+ event.preventDefault();
19425
19280
  if (isDetailedMode) {
19426
- event.preventDefault();
19427
19281
  toggleDetailedMode(false);
19428
19282
  if (value !== currentValue) {
19429
19283
  props.onChange(currentValue);
@@ -19433,9 +19287,15 @@ const MemoedEditingCell = /*#__PURE__*/React__default.memo(function MemoedEditin
19433
19287
  var _target$select2;
19434
19288
  return (_target$select2 = target.select) === null || _target$select2 === void 0 ? void 0 : _target$select2.call(target);
19435
19289
  });
19290
+ } else {
19291
+ toggleEditing(false);
19436
19292
  }
19437
19293
  return;
19438
19294
  }
19295
+ const shortcutWhitelist = ['f', 'p', 'e']; // f = search, p = print, and e = edit
19296
+ if (isPressingMetaKey(event) && !shortcutWhitelist.some(s => s === event.key)) {
19297
+ event.stopPropagation();
19298
+ }
19439
19299
  // toggle into detailed mode when actually inputting something
19440
19300
  if (!isPressingMetaKey(event) && (/^[a-z0-9]$/i.test(event.key) || event.key === 'Backspace')) {
19441
19301
  toggleDetailedMode(true);
@@ -19531,37 +19391,12 @@ function Cell$5(props) {
19531
19391
  return /*#__PURE__*/React__default.createElement(DisplayCell, Object.assign({}, props));
19532
19392
  }
19533
19393
 
19534
- function DiscardChangesConfirmationDialog(props) {
19535
- const {
19536
- onDiscard: handleDiscard,
19537
- ...dialogProps
19538
- } = props;
19539
- const {
19540
- texts
19541
- } = useLocalization();
19542
- const handleClickInsideDialogContent = event => {
19543
- // Prevents the click event from propagating to the table, ensuring the row isn't saved when a click occurs
19544
- // inside the dialog
19545
- event.stopPropagation();
19546
- };
19547
- return /*#__PURE__*/React__default.createElement(Dialog, Object.assign({}, dialogProps), /*#__PURE__*/React__default.createElement(Dialog.Content, {
19548
- "aria-label": texts.table3.editing.clearChangesConfirmationDialog.title,
19549
- onClick: handleClickInsideDialogContent
19550
- }, /*#__PURE__*/React__default.createElement(Dialog.Title, null, texts.table3.editing.clearChangesConfirmationDialog.title), /*#__PURE__*/React__default.createElement("p", null, texts.table3.editing.clearChangesConfirmationDialog.description), /*#__PURE__*/React__default.createElement(Dialog.Footer, null, /*#__PURE__*/React__default.createElement(Group, null, /*#__PURE__*/React__default.createElement(Dialog.Close, null, /*#__PURE__*/React__default.createElement(Button$1, {
19551
- tabIndex: 0
19552
- }, texts.table3.editing.clearChangesConfirmationDialog.cancel)), /*#__PURE__*/React__default.createElement(Dialog.Close, null, /*#__PURE__*/React__default.createElement(Button$1, {
19553
- autoFocus: true,
19554
- tabIndex: 0,
19555
- appearance: "primary",
19556
- onClick: handleDiscard
19557
- }, texts.table3.editing.clearChangesConfirmationDialog.confirm))))));
19558
- }
19559
-
19560
19394
  function EditingActionMenu(props) {
19561
19395
  const {
19562
19396
  hasChanges,
19563
19397
  hasErrors,
19564
- onDiscard: handleDiscard,
19398
+ onClear: handleClear,
19399
+ onExit: handleExit,
19565
19400
  onEditingSave: handleSave,
19566
19401
  isLastRow
19567
19402
  } = props;
@@ -19583,6 +19418,7 @@ function EditingActionMenu(props) {
19583
19418
  return /*#__PURE__*/React__default.createElement(IconButton, {
19584
19419
  appearance: "transparent",
19585
19420
  "aria-label": texts.table3.editing.actions.tooltip,
19421
+ className: "group-[[data-row-editing-status]]/row:hidden",
19586
19422
  icon: "more",
19587
19423
  onKeyDown: handleKeyDown,
19588
19424
  menu: menuProps => (/*#__PURE__*/React__default.createElement(Menu$1, Object.assign({}, menuProps), /*#__PURE__*/React__default.createElement(Menu$1.Content, {
@@ -19594,13 +19430,42 @@ function EditingActionMenu(props) {
19594
19430
  }, texts.table3.editing.actions.save), /*#__PURE__*/React__default.createElement(Menu$1.Item, {
19595
19431
  icon: "close",
19596
19432
  disabled: !hasChanges,
19597
- dialog: props => /*#__PURE__*/React__default.createElement(DiscardChangesConfirmationDialog, Object.assign({}, props, {
19598
- onDiscard: handleDiscard
19433
+ dialog: props => /*#__PURE__*/React__default.createElement(ConfirmClearChangesDialog, Object.assign({}, props, {
19434
+ onClear: handleClear
19599
19435
  }))
19600
- }, texts.table3.editing.actions.clear))))
19436
+ }, texts.table3.editing.actions.clear), /*#__PURE__*/React__default.createElement(Menu$1.Item, {
19437
+ icon: "undo",
19438
+ onClick: handleExit
19439
+ }, texts.table3.editing.actions.exit))))
19601
19440
  });
19602
19441
  }
19442
+ function ConfirmClearChangesDialog(props) {
19443
+ const {
19444
+ onClear: handleClear,
19445
+ ...dialogProps
19446
+ } = props;
19447
+ const {
19448
+ texts
19449
+ } = useLocalization();
19450
+ const handleClickInsideDialogContent = event => {
19451
+ // Prevents the click event from propagating to the table, ensuring the row isn't saved when a click occurs
19452
+ // inside the dialog
19453
+ event.stopPropagation();
19454
+ };
19455
+ return /*#__PURE__*/React__default.createElement(Dialog, Object.assign({}, dialogProps), /*#__PURE__*/React__default.createElement(Dialog.Content, {
19456
+ "aria-label": texts.table3.editing.clearChangesConfirmationDialog.title,
19457
+ onClick: handleClickInsideDialogContent
19458
+ }, /*#__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, {
19459
+ tabIndex: 0
19460
+ }, texts.table3.editing.clearChangesConfirmationDialog.cancel)), /*#__PURE__*/React__default.createElement(Dialog.Close, null, /*#__PURE__*/React__default.createElement(Button$1, {
19461
+ autoFocus: true,
19462
+ tabIndex: 0,
19463
+ appearance: "primary",
19464
+ onClick: handleClear
19465
+ }, texts.table3.editing.clearChangesConfirmationDialog.confirm))))));
19466
+ }
19603
19467
 
19468
+ const COMPLETE_INDICATOR_DELAY = 3000;
19604
19469
  function SaveStatus(props) {
19605
19470
  const {
19606
19471
  rowId,
@@ -19610,7 +19475,18 @@ function SaveStatus(props) {
19610
19475
  texts
19611
19476
  } = useLocalization();
19612
19477
  const tableMeta = table.options.meta;
19613
- const status = tableMeta.editing.getRowStatus(rowId);
19478
+ const status = tableMeta.editing.getRowSaveStatus(rowId);
19479
+ React__default.useEffect(() => {
19480
+ let timeout;
19481
+ if (status === 'complete') {
19482
+ timeout = setTimeout(() => {
19483
+ tableMeta.editing.setRowSaveStatus(rowId, undefined);
19484
+ }, COMPLETE_INDICATOR_DELAY);
19485
+ }
19486
+ return () => {
19487
+ clearTimeout(timeout);
19488
+ };
19489
+ }, [status]);
19614
19490
  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)]', {
19615
19491
  'mt-0.5': tableMeta.rowHeight.height === 'short',
19616
19492
  'mt-1': tableMeta.rowHeight.height === 'medium',
@@ -19621,7 +19497,7 @@ function SaveStatus(props) {
19621
19497
  className: "!contents"
19622
19498
  }, /*#__PURE__*/React__default.createElement("span", {
19623
19499
  className: className
19624
- }, status === 'saving' ? (/*#__PURE__*/React__default.createElement(Tooltip, {
19500
+ }, status === 'pending' ? (/*#__PURE__*/React__default.createElement(Tooltip, {
19625
19501
  title: texts.table3.editing.saving.progress
19626
19502
  }, /*#__PURE__*/React__default.createElement(Spinner, {
19627
19503
  delay: 0,
@@ -19659,46 +19535,15 @@ function Row$2(props) {
19659
19535
  }
19660
19536
  }
19661
19537
  }, [tableMeta.editing.isEditing, isActiveRow]);
19662
- const rowStatus = tableMeta.editing.getRowStatus(row.id);
19663
- // discard new row
19664
- const [showDiscardDialog, setShowDiscardDialog] = React__default.useState(false);
19665
- function handleDiscard() {
19666
- tableMeta.editing.discardChanges(row.id, table);
19667
- requestAnimationFrame(() => {
19668
- if (isTemporaryRow(row.id)) {
19669
- var _tableMeta$editing$cr;
19670
- (_tableMeta$editing$cr = tableMeta.editing.createRowButtonRef.current) === null || _tableMeta$editing$cr === void 0 ? void 0 : _tableMeta$editing$cr.focus();
19671
- } else {
19672
- focusManager.focusFirst();
19673
- }
19674
- });
19675
- }
19676
- function handleKeyDown(event) {
19677
- if (props.onKeyDown) {
19678
- props.onKeyDown(event);
19679
- }
19680
- if (event.isDefaultPrevented() || event.isPropagationStopped()) {
19681
- return;
19682
- }
19683
- if (event.key === 'Escape' && tableMeta.editing.hasChanges(row.id) && !isElementTriggeredFromContainer(event.target, event.currentTarget)) {
19684
- event.preventDefault();
19685
- setShowDiscardDialog(true);
19686
- }
19687
- }
19688
19538
  const attributes = {
19689
- 'data-row-editing-invalid': tableMeta.editing.hasRowErrors(row.id) ? !tableMeta.editing.hasRowErrorsShownInAlert(row.id) ? 'unseen' : true : undefined,
19690
- 'data-row-editing-status': rowStatus,
19691
- onFocus: handleFocus,
19692
- onKeyDown: handleKeyDown
19539
+ 'data-row-editing-invalid': tableMeta.editing.isEnabled && tableMeta.editing.hasRowErrors(row.id) ? !tableMeta.editing.hasRowErrorsSeen(row.id) ? 'unseen' : true : undefined,
19540
+ 'data-row-editing-status': tableMeta.editing.isEnabled && tableMeta.editing.getRowSaveStatus(row.id) ? tableMeta.editing.getRowSaveStatus(row.id) : undefined,
19541
+ onFocus: handleFocus
19693
19542
  };
19694
- return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(DisplayRow, Object.assign({}, props, attributes), rowStatus === 'saving' || rowStatus === 'saved' ? /*#__PURE__*/React__default.createElement(SaveStatus, {
19543
+ return /*#__PURE__*/React__default.createElement(DisplayRow, Object.assign({}, props, attributes), tableMeta.editing.getRowSaveStatus(row.id) ? /*#__PURE__*/React__default.createElement(SaveStatus, {
19695
19544
  rowId: row.id,
19696
19545
  table: table
19697
- }) : null), /*#__PURE__*/React__default.createElement(DiscardChangesConfirmationDialog, {
19698
- open: showDiscardDialog,
19699
- onChange: setShowDiscardDialog,
19700
- onDiscard: handleDiscard
19701
- }));
19546
+ }) : null);
19702
19547
  }
19703
19548
 
19704
19549
  const RENDERERS$1 = {
@@ -19706,46 +19551,29 @@ const RENDERERS$1 = {
19706
19551
  cell: Cell$5
19707
19552
  };
19708
19553
  function useTable3(props, ref) {
19709
- const editing = useTableEditing(props.enableEditing, props.onEditingSave, props.onEditingChange, props.rowIdentityAccessor, props.validator);
19554
+ const editing = useTableEditing(props.enableEditing, props.onEditingSave, props.onEditingChange, props.validator);
19710
19555
  const creationEnabled = editing.isEnabled && !!props.onEditingCreate;
19711
- // this gives me the performance heeby jeebies, but can't think of a better way to internalise the state
19712
- const data = React__default.useMemo(() => {
19713
- if (editing.isEditing && editing.temporaryRows.length) {
19714
- var _props$data;
19715
- return editing.temporaryRows.concat((_props$data = props.data) !== null && _props$data !== void 0 ? _props$data : []);
19716
- }
19717
- return props.data;
19718
- }, [JSON.stringify(props.data), editing.temporaryRows.length]);
19719
19556
  const extendedProps = {
19720
19557
  ...props,
19721
- data,
19722
19558
  enableRowActions: editing.isEditing ? true : props.enableRowActions,
19723
- rowActions: editing.isEditing ? [(_, rowId, table) => (/*#__PURE__*/React__default.createElement(EditingActionMenu, {
19559
+ rowActions: editing.isEditing ? [(_, rowId) => (/*#__PURE__*/React__default.createElement(EditingActionMenu, {
19724
19560
  hasChanges: editing.hasChanges(rowId),
19725
19561
  hasErrors: editing.hasRowErrors(rowId),
19726
- onDiscard: () => editing.discardChanges(rowId, table),
19727
- onEditingSave: function () {
19728
- try {
19729
- return Promise.resolve(editing.saveChanges(table, rowId)).then(function () {});
19730
- } catch (e) {
19731
- return Promise.reject(e);
19732
- }
19733
- },
19562
+ onClear: () => editing.resetChanges(rowId),
19563
+ onEditingSave: () => editing.saveChanges(rowId),
19564
+ onExit: () => editing.toggleEditing(false),
19734
19565
  isLastRow: !creationEnabled && table.meta.rowActive.rowActiveIndex === table.meta.length - 1
19735
19566
  }))] : props.rowActions
19736
19567
  };
19737
19568
  const meta = {
19738
19569
  editing
19739
19570
  };
19740
- const options = {
19741
- virtualiserPaddingEndOffset: props.enableEditing && props.onEditingCreate ? 1 : 0
19742
- };
19743
- const table = useTable(extendedProps, ref, RENDERERS$1, meta, options);
19571
+ const table = useTable(extendedProps, ref, RENDERERS$1, meta);
19744
19572
  // listeners
19745
19573
  useTableEditingListener(table.instance, table.ref);
19746
19574
  React__default.useEffect(() => {
19747
19575
  if (table.ref.current) {
19748
- table.ref.current.instance.toggleEditing = enabled => table.meta.editing.toggleEditing(enabled !== null && enabled !== void 0 ? enabled : editing => !editing, table.instance);
19576
+ table.ref.current.instance.toggleEditing = enabled => table.meta.editing.toggleEditing(enabled !== null && enabled !== void 0 ? enabled : editing => !editing);
19749
19577
  }
19750
19578
  }, [table.ref.current]);
19751
19579
  return table;
@@ -19764,7 +19592,7 @@ function Alert$1(props) {
19764
19592
  const validationTexts = texts.table3.editing.validation;
19765
19593
  const tableMeta = table.options.meta;
19766
19594
  const [showFilterResetDialog, setShowFilterResetDialog] = React__default.useState(false);
19767
- const pendingChangesWithErrors = tableMeta.editing.getErrorsShownInAlert();
19595
+ const pendingChangesWithErrors = tableMeta.editing.getAlertErrors();
19768
19596
  function scrollToRow(rowIndex) {
19769
19597
  tableMeta.rowActive.setRowActiveIndex(rowIndex);
19770
19598
  scrollToIndex(rowIndex, {
@@ -19783,43 +19611,38 @@ function Alert$1(props) {
19783
19611
  const title = (pendingChangesWithErrors.length === 1 ? validationTexts.alert.titleOne : validationTexts.alert.titlePlural).replace('[COUNT]', String(pendingChangesWithErrors.length));
19784
19612
  // generate links to each invalid row, to go into the error message
19785
19613
  const links = [];
19786
- const visibleColumns = table.getVisibleFlatColumns().map(c => c.id);
19787
- const rowIdentityColumn = tableMeta.rowIdentityAccessor && visibleColumns.includes(String(tableMeta.rowIdentityAccessor)) ? table.getColumn(String(tableMeta.rowIdentityAccessor)) : undefined;
19788
- pendingChangesWithErrors.forEach((pendingChangeWithError, index) => {
19614
+ const rowIdentityColumn = tableMeta.rowIdentityColumnId ? table.getColumn(tableMeta.rowIdentityColumnId) : undefined;
19615
+ pendingChangesWithErrors.forEach((error, index) => {
19789
19616
  // if appropriate, concatenate the item with the text "and"
19790
19617
  if (pendingChangesWithErrors.length > 1 && index === pendingChangesWithErrors.length - 1) {
19791
19618
  // Add space before and after `messageAnd` text
19792
19619
  links.push(` ${validationTexts.alert.messageAnd} `);
19793
19620
  }
19794
- const rowIndex = table.getRowModel().rows.findIndex(row => row.id === pendingChangeWithError.rowId);
19621
+ const rowIndex = table.getRowModel().rows.findIndex(row => row.id === error.rowId);
19795
19622
  const handleClick = () => {
19796
- // if row is visible
19797
19623
  if (rowIndex > -1) {
19798
19624
  scrollToRow(rowIndex);
19799
- }
19800
- // if row is filtered out
19801
- else {
19802
- setShowFilterResetDialog(pendingChangeWithError.rowId);
19625
+ } else {
19626
+ setShowFilterResetDialog(error.rowId);
19803
19627
  }
19804
19628
  };
19805
19629
  let tooltip;
19806
- if (pendingChangeWithError.errors.row) {
19807
- tooltip = pendingChangeWithError.errors.row;
19630
+ if (error.pendingChange._meta.errors.row) {
19631
+ tooltip = error.pendingChange._meta.errors.row;
19808
19632
  } else {
19809
19633
  var _table$getAllColumns$, _table$getAllColumns$2;
19810
- const firstCellErrorColumnId = Object.keys(pendingChangeWithError.errors.cells)[0];
19634
+ const firstCellErrorColumnId = Object.keys(error.pendingChange._meta.errors.cells)[0];
19811
19635
  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;
19812
- tooltip = `${columnName}: ${pendingChangeWithError.errors.cells[firstCellErrorColumnId]}`;
19636
+ tooltip = `${columnName}: ${error.pendingChange._meta.errors.cells[firstCellErrorColumnId]}`;
19813
19637
  }
19814
- const row = table.getRow(pendingChangeWithError.rowId).original;
19815
19638
  links.push(/*#__PURE__*/React__default.createElement(Tooltip, {
19816
- key: pendingChangeWithError.rowId,
19639
+ key: error.rowId,
19817
19640
  title: tooltip
19818
19641
  }, /*#__PURE__*/React__default.createElement("span", {
19819
19642
  className: "text-blue",
19820
19643
  onClick: handleClick,
19821
19644
  role: "button"
19822
- }, rowIdentityColumn ? row[rowIdentityColumn.id] : rowIndex + 1)));
19645
+ }, rowIdentityColumn ? error.pendingChange._meta.original[rowIdentityColumn.id] : rowIndex + 1)));
19823
19646
  // if appropriate, concatenate the item with the text ","
19824
19647
  if (pendingChangesWithErrors.length > 2 && index < pendingChangesWithErrors.length - 2) {
19825
19648
  links.push(', ');
@@ -19875,6 +19698,89 @@ function FilterResetDialog(props) {
19875
19698
  }, texts.table3.editing.validation.resetFiltersDialog.confirm)))));
19876
19699
  }
19877
19700
 
19701
+ function CreateNewRowButton(props) {
19702
+ const {
19703
+ onEditingCreate,
19704
+ scrollToIndex,
19705
+ table,
19706
+ tableMeta
19707
+ } = props;
19708
+ const {
19709
+ texts
19710
+ } = useLocalization();
19711
+ const rows = table.getCoreRowModel().rows.filter(row => row.original !== undefined);
19712
+ const [rowCreated, setRowCreated] = React__default.useState({
19713
+ rowFinder: undefined
19714
+ });
19715
+ const handleKeyDown = event => {
19716
+ if (!tableMeta.editing.hasChanges() && event.key === 'Tab') {
19717
+ tableMeta.editing.saveChanges();
19718
+ }
19719
+ };
19720
+ const handleCreate = function () {
19721
+ try {
19722
+ if (!onEditingCreate) {
19723
+ return Promise.resolve();
19724
+ }
19725
+ const createdRow = rows.find(row => {
19726
+ var _rowCreated$rowFinder;
19727
+ 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);
19728
+ });
19729
+ const _temp = function () {
19730
+ if (createdRow) {
19731
+ return Promise.resolve(tableMeta.editing.saveChanges()).then(function () {
19732
+ if (!tableMeta.editing.hasRowErrors(createdRow.id)) {
19733
+ const rowFinder = onEditingCreate();
19734
+ setRowCreated({
19735
+ rowFinder
19736
+ });
19737
+ }
19738
+ });
19739
+ } else {
19740
+ const rowFinder = onEditingCreate();
19741
+ setRowCreated({
19742
+ rowFinder
19743
+ });
19744
+ }
19745
+ }();
19746
+ return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
19747
+ } catch (e) {
19748
+ return Promise.reject(e);
19749
+ }
19750
+ };
19751
+ React__default.useEffect(() => {
19752
+ if (typeof (rowCreated === null || rowCreated === void 0 ? void 0 : rowCreated.rowFinder) === 'function') {
19753
+ const createdRow = rows.find(row => {
19754
+ var _rowCreated$rowFinder2;
19755
+ 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);
19756
+ });
19757
+ if (createdRow) {
19758
+ const rowInTable = table.getRowModel().rows.filter(row => row.original !== undefined).find(row => {
19759
+ var _rowCreated$rowFinder3;
19760
+ 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);
19761
+ });
19762
+ if (rowInTable) {
19763
+ tableMeta.editing.toggleEditing(true);
19764
+ tableMeta.rowActive.setRowActiveIndex(createdRow.index);
19765
+ scrollToIndex(createdRow.index);
19766
+ requestAnimationFrame(() => animateCreateRow(createdRow.id));
19767
+ }
19768
+ requestAnimationFrame(() => tableMeta.editing.addCreatedRowChangeset(createdRow));
19769
+ }
19770
+ }
19771
+ }, [rowCreated]);
19772
+ return /*#__PURE__*/React__default.createElement("tr", {
19773
+ onClick: handleCreate,
19774
+ className: "border-grey-300 hover:bg-grey-100 group !sticky bottom-10 left-0 z-[21] !block cursor-pointer border-t"
19775
+ }, /*#__PURE__*/React__default.createElement("td", {
19776
+ className: "!border-t-0 !bg-transparent"
19777
+ }, /*#__PURE__*/React__default.createElement(Button$1, {
19778
+ onKeyDown: handleKeyDown,
19779
+ className: "group-hover:bg-grey-200 sticky left-0",
19780
+ appearance: "transparent"
19781
+ }, "+ ", texts.table3.editing.buttons.create.label)));
19782
+ }
19783
+
19878
19784
  function Editing(props) {
19879
19785
  const {
19880
19786
  scrollToIndex,
@@ -19900,193 +19806,21 @@ function Editing(props) {
19900
19806
  (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.click();
19901
19807
  });
19902
19808
  const handleChange = enabled => {
19903
- if (enabled && tableMeta.rowActive.rowActiveIndex === undefined) {
19904
- tableMeta.rowActive.setRowActiveIndex(0);
19905
- }
19809
+ tableMeta.editing.toggleEditing(enabled);
19906
19810
  requestAnimationFrame(() => {
19907
19811
  var _tableMeta$rowActive$;
19908
- // wait for an active row to be set so that we don't trigger save
19909
- tableMeta.editing.toggleEditing(enabled, table);
19910
- scrollToIndex((_tableMeta$rowActive$ = tableMeta.rowActive.rowActiveIndex) !== null && _tableMeta$rowActive$ !== void 0 ? _tableMeta$rowActive$ : 0);
19812
+ return scrollToIndex((_tableMeta$rowActive$ = tableMeta.rowActive.rowActiveIndex) !== null && _tableMeta$rowActive$ !== void 0 ? _tableMeta$rowActive$ : 0);
19911
19813
  });
19912
19814
  };
19913
19815
  return /*#__PURE__*/React__default.createElement(Tooltip, {
19914
19816
  title: tooltip
19915
19817
  }, /*#__PURE__*/React__default.createElement(ModeSwitch, {
19916
- "data-table": "editing-toggle",
19917
19818
  checked: tableMeta.editing.isEditing,
19918
19819
  onChange: handleChange,
19919
19820
  ref: ref
19920
19821
  }));
19921
19822
  }
19922
19823
 
19923
- function CreateNewRow(props) {
19924
- var _temporaryRows$0$tabl, _temporaryRows$, _table$getState$colum;
19925
- const {
19926
- buttonRef,
19927
- onEditingCreate: handleEditingCreate,
19928
- table,
19929
- tableMeta
19930
- } = props;
19931
- const {
19932
- texts
19933
- } = useLocalization();
19934
- const temporaryRows = tableMeta.editing.temporaryRows;
19935
- const temporaryRowId = (_temporaryRows$0$tabl = (_temporaryRows$ = temporaryRows[0]) === null || _temporaryRows$ === void 0 ? void 0 : _temporaryRows$[tableMeta.rowIdentityAccessor]) !== null && _temporaryRows$0$tabl !== void 0 ? _temporaryRows$0$tabl : '';
19936
- const isDisabled = !!table.getState().globalFilter || !!((_table$getState$colum = table.getState().columnFilters) !== null && _table$getState$colum !== void 0 && _table$getState$colum.length) || !!temporaryRowId && !!tableMeta.editing.hasRowErrors(temporaryRowId);
19937
- const isSaving = !!temporaryRowId && tableMeta.editing.getRowStatus(temporaryRowId) === 'saving';
19938
- const handleCreate = function (event) {
19939
- try {
19940
- // prevent save being triggered by click outside - TODO: investigate why the button triggers clickoutside
19941
- event === null || event === void 0 ? void 0 : event.stopPropagation();
19942
- if (!handleEditingCreate || isDisabled) {
19943
- return Promise.resolve();
19944
- }
19945
- return Promise.resolve(tableMeta.editing.saveChanges(table)).then(function (saved) {
19946
- if (!saved) {
19947
- return;
19948
- }
19949
- try {
19950
- const changeset = handleEditingCreate();
19951
- if (changeset) {
19952
- // change the row before reating because it triggers a save
19953
- // saving would trigger the validation flow and immediately make the row red
19954
- tableMeta.rowActive.setRowActiveIndex(tableMeta.length);
19955
- requestAnimationFrame(function () {
19956
- try {
19957
- tableMeta.editing.toggleEditing(true, table);
19958
- return Promise.resolve(tableMeta.editing.createRow(changeset)).then(function (rowId) {
19959
- tableMeta.editing.setLastFocusedCellIndex(0);
19960
- try {
19961
- const row = table.getRow(rowId);
19962
- row.pin('bottom');
19963
- } catch {
19964
- //
19965
- }
19966
- });
19967
- } catch (e) {
19968
- return Promise.reject(e);
19969
- }
19970
- });
19971
- }
19972
- } catch (error) {
19973
- console.error(error);
19974
- }
19975
- });
19976
- } catch (e) {
19977
- return Promise.reject(e);
19978
- }
19979
- };
19980
- let tooltip;
19981
- if (isSaving) {
19982
- tooltip = texts.table3.editing.buttons.create.saving;
19983
- } else if (isDisabled) {
19984
- tooltip = texts.table3.editing.buttons.create.disabled;
19985
- }
19986
- return /*#__PURE__*/React__default.createElement("tr", {
19987
- "data-row-create": true,
19988
- className: "border-grey-300 group/row",
19989
- tabIndex: -1
19990
- }, /*#__PURE__*/React__default.createElement("td", {
19991
- className: "!bg-grey-50 col-span-full !border-b-0 !px-1"
19992
- }, /*#__PURE__*/React__default.createElement(Button$1, {
19993
- appearance: "transparent",
19994
- className: "group-hover:bg-grey-200 sticky left-[4px]",
19995
- disabled: isDisabled,
19996
- onClick: handleCreate,
19997
- ref: buttonRef,
19998
- tooltip: tooltip
19999
- }, /*#__PURE__*/React__default.createElement(Icon, {
20000
- name: "circle-plus"
20001
- }), texts.table3.editing.buttons.create.label)));
20002
- }
20003
-
20004
- function TemporaryRow(props) {
20005
- var _tableRef$current, _tableRef$current2;
20006
- const {
20007
- createRowButtonRef,
20008
- table,
20009
- tableMeta,
20010
- tableRef
20011
- } = props;
20012
- const isScrolled = tableRef.current ? ((_tableRef$current = tableRef.current) === null || _tableRef$current === void 0 ? void 0 : _tableRef$current.scrollHeight) > ((_tableRef$current2 = tableRef.current) === null || _tableRef$current2 === void 0 ? void 0 : _tableRef$current2.clientHeight) : false;
20013
- const handleKeyDown = function (event) {
20014
- try {
20015
- const _temp2 = function () {
20016
- if (event.key === 'ArrowDown') {
20017
- event.preventDefault();
20018
- const _temp = function () {
20019
- if (!isElementTriggeredFromContainer(event.target, event.currentTarget)) {
20020
- return Promise.resolve(tableMeta.editing.saveChanges(table)).then(function (saved) {
20021
- if (saved) {
20022
- var _createRowButtonRef$c;
20023
- (_createRowButtonRef$c = createRowButtonRef.current) === null || _createRowButtonRef$c === void 0 ? void 0 : _createRowButtonRef$c.focus();
20024
- }
20025
- });
20026
- }
20027
- }();
20028
- if (_temp && _temp.then) return _temp.then(function () {});
20029
- } else if (event.key === 'ArrowUp') {
20030
- event.preventDefault();
20031
- event.stopPropagation();
20032
- if (tableRef.current) {
20033
- var _tableRef$current$que, _tableRef$current$que2, _tableRef$current$que3;
20034
- const availableRows = Array.from((_tableRef$current$que = tableRef.current.querySelectorAll(`tbody tr:not([data-row-id^='${TEMPORARY_ROW_ID_PREFIX}'])`)) !== null && _tableRef$current$que !== void 0 ? _tableRef$current$que : []);
20035
- const footerHeight = (_tableRef$current$que2 = (_tableRef$current$que3 = tableRef.current.querySelector('tfoot')) === null || _tableRef$current$que3 === void 0 ? void 0 : _tableRef$current$que3.getBoundingClientRect().height) !== null && _tableRef$current$que2 !== void 0 ? _tableRef$current$que2 : 0;
20036
- const newRowHeight = event.currentTarget.getBoundingClientRect().height;
20037
- const visibleHeight = tableRef.current.clientHeight - footerHeight - newRowHeight;
20038
- const tableTopOffset = tableRef.current.getBoundingClientRect().top;
20039
- let nextRowIndex;
20040
- // iterate available rows in reverse order, since we're working at the bottom
20041
- for (let index = availableRows.length - 1; index >= 0; index--) {
20042
- const rowRect = availableRows[index].getBoundingClientRect();
20043
- const topPlusHalfRow = rowRect.top + rowRect.height / 2;
20044
- if (topPlusHalfRow - tableTopOffset <= visibleHeight) {
20045
- nextRowIndex = index;
20046
- break;
20047
- }
20048
- }
20049
- if (nextRowIndex) {
20050
- tableMeta.rowActive.setRowActiveIndex(Number(availableRows[nextRowIndex < 0 ? 0 : nextRowIndex].getAttribute('data-row-index')));
20051
- }
20052
- }
20053
- }
20054
- }();
20055
- return Promise.resolve(_temp2 && _temp2.then ? _temp2.then(function () {}) : void 0);
20056
- } catch (e) {
20057
- return Promise.reject(e);
20058
- }
20059
- };
20060
- const handleKeyDownCapture = event => {
20061
- if (event.key === 'ArrowLeft' && tableMeta.editing.lastFocusedCellIndex === 0) {
20062
- event.preventDefault();
20063
- event.stopPropagation();
20064
- } else if (event.key === 'ArrowRight' && tableMeta.editing.lastFocusedCellIndex) {
20065
- if (tableMeta.editing.lastFocusedCellIndex === table.getVisibleFlatColumns().length - 1) {
20066
- event.preventDefault();
20067
- event.stopPropagation();
20068
- }
20069
- }
20070
- };
20071
- const className = cn('group/row border-grey-300 !sticky z-[21]', {
20072
- 'bottom-20': tableMeta.footer.isEnabled,
20073
- 'bottom-10': !tableMeta.footer.isEnabled,
20074
- 'border-b border-t shadow-[0px_-5px_20px_0px_rgba(0,0,0,0.1)] border-t-grey-500/[0.75]': isScrolled
20075
- });
20076
- return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, table.getBottomRows().map(row => (/*#__PURE__*/React__default.createElement(Row, {
20077
- key: row.id,
20078
- cellRenderer: RENDERERS$1.cell,
20079
- index: tableMeta.length,
20080
- measureRow: () => null,
20081
- renderer: RENDERERS$1.row,
20082
- row: row,
20083
- table: table,
20084
- className: className,
20085
- onKeyDown: handleKeyDown,
20086
- onKeyDownCapture: handleKeyDownCapture
20087
- }))));
20088
- }
20089
-
20090
19824
  function Column$3(_) {
20091
19825
  return null;
20092
19826
  }
@@ -20102,18 +19836,8 @@ const BaseTable3 = /*#__PURE__*/fixedForwardRef(function BaseTable3(props, ref)
20102
19836
  '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,
20103
19837
  enableHorizontalArrowKeyNavigation: table3.meta.editing.isEditing
20104
19838
  };
20105
- const hasAlertErrors = table3.meta.editing.isEditing && table3.meta.editing.getErrorsShownInAlert().length;
20106
- const hasCreateWorkflow = table3.meta.editing.isEnabled && props.onEditingCreate;
20107
- let footerRows;
20108
- if (hasCreateWorkflow) {
20109
- footerRows = /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(CreateNewRow, {
20110
- buttonRef: table3.meta.editing.createRowButtonRef,
20111
- onEditingCreate: props.onEditingCreate,
20112
- table: table3.instance,
20113
- tableMeta: table3.meta,
20114
- tableRef: table3.ref
20115
- }));
20116
- }
19839
+ const hasAlertErrors = table3.meta.editing.hasAlertErrors();
19840
+ const showCreateRowButton = table3.meta.editing.isEnabled && props.onEditingCreate;
20117
19841
  return /*#__PURE__*/React__default.createElement(Table, null, /*#__PURE__*/React__default.createElement(Table.Toolbar, {
20118
19842
  table: table3
20119
19843
  }, table3.meta.editing.isEnabled ? (/*#__PURE__*/React__default.createElement(Editing, {
@@ -20126,14 +19850,13 @@ const BaseTable3 = /*#__PURE__*/fixedForwardRef(function BaseTable3(props, ref)
20126
19850
  tableRef: table3.ref
20127
19851
  })) : null, /*#__PURE__*/React__default.createElement(Table.Grid, Object.assign({}, gridAttributes, {
20128
19852
  "data-taco": "table3",
20129
- rowsForFooter: footerRows,
20130
19853
  table: table3
20131
- }), hasCreateWorkflow ? (/*#__PURE__*/React__default.createElement(TemporaryRow, {
20132
- createRowButtonRef: table3.meta.editing.createRowButtonRef,
19854
+ }), showCreateRowButton && (/*#__PURE__*/React__default.createElement(CreateNewRowButton, {
20133
19855
  table: table3.instance,
20134
19856
  tableMeta: table3.meta,
20135
- tableRef: table3.ref
20136
- })) : null));
19857
+ onEditingCreate: props.onEditingCreate,
19858
+ scrollToIndex: table3.renderer.scrollToIndex
19859
+ }))));
20137
19860
  });
20138
19861
  const Table3 = /*#__PURE__*/fixedForwardRef(function Table3(props, ref) {
20139
19862
  const stringifiedChildren = String(props.children);