@revolist/revogrid 4.26.2 → 4.27.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/dist/cjs/{cell-renderer-Cf2Pu4S0.js → cell-renderer-BDIx0xys.js} +3 -3
  2. package/dist/cjs/{column.service-C7p5eC5V.js → column.service-D-ENzqyb.js} +5 -3
  3. package/dist/cjs/{dimension.helpers-CgHhnN1d.js → dimension.helpers-CptesQOZ.js} +52 -8
  4. package/dist/cjs/{edit.utils-rAcGublN.js → edit.utils-CBAbQhGP.js} +1 -1
  5. package/dist/cjs/{header-cell-renderer-DHClfIto.js → header-cell-renderer-B5Y4fdZC.js} +1 -1
  6. package/dist/cjs/{index--FdNLz1Z.js → index-BVESmpqW.js} +1 -1
  7. package/dist/cjs/index.cjs.js +72 -55
  8. package/dist/cjs/loader.cjs.js +1 -1
  9. package/dist/cjs/revo-grid.cjs.entry.js +131 -86
  10. package/dist/cjs/revo-grid.cjs.js +1 -1
  11. package/dist/cjs/revogr-attribution_7.cjs.entry.js +51 -19
  12. package/dist/cjs/revogr-clipboard_3.cjs.entry.js +4 -4
  13. package/dist/cjs/revogr-data_4.cjs.entry.js +21 -15
  14. package/dist/cjs/revogr-filter-panel.cjs.entry.js +9 -9
  15. package/dist/cjs/{column.drag.plugin-CK5HADlW.js → row-resize.plugin-sK9_rcUN.js} +759 -86
  16. package/dist/cjs/{text-editor-F04kTx53.js → text-editor-CJyQaYei.js} +2 -2
  17. package/dist/cjs/{throttle-fV6BUmM7.js → throttle-BsaP4fgu.js} +3 -3
  18. package/dist/cjs/{viewport.store-B4Clk4m9.js → viewport.store-mhsdi61t.js} +1 -1
  19. package/dist/collection/components/data/revogr-data-style.css +11 -0
  20. package/dist/collection/components/data/revogr-data.js +14 -8
  21. package/dist/collection/components/header/revogr-header-style.css +1 -0
  22. package/dist/collection/components/overlay/keyboard.service.js +33 -3
  23. package/dist/collection/components/overlay/revogr-overlay-selection.js +12 -10
  24. package/dist/collection/components/revoGrid/plugin.service.js +2 -2
  25. package/dist/collection/components/revoGrid/revo-grid.js +80 -30
  26. package/dist/collection/components/revoGrid/viewport.scrolling.service.js +24 -13
  27. package/dist/collection/components/revoGrid/viewport.service.js +1 -1
  28. package/dist/collection/plugins/filter/filter.constants.js +9 -0
  29. package/dist/collection/plugins/filter/filter.panel.js +8 -8
  30. package/dist/collection/plugins/filter/filter.plugin.js +109 -10
  31. package/dist/collection/plugins/filter/filter.style.css +2 -0
  32. package/dist/collection/plugins/groupingRow/grouping.const.js +1 -0
  33. package/dist/collection/plugins/groupingRow/grouping.row.plugin.js +93 -56
  34. package/dist/collection/plugins/groupingRow/grouping.row.renderer.js +1 -1
  35. package/dist/collection/plugins/groupingRow/grouping.service.js +1 -1
  36. package/dist/collection/plugins/groupingRow/grouping.sorting.service.js +58 -0
  37. package/dist/collection/plugins/groupingRow/grouping.trimmed.service.js +5 -3
  38. package/dist/collection/plugins/index.js +1 -0
  39. package/dist/collection/plugins/row-resize/index.js +6 -0
  40. package/dist/collection/plugins/row-resize/row-resize.plugin.js +416 -0
  41. package/dist/collection/plugins/row-resize/row-resize.types.js +1 -0
  42. package/dist/collection/plugins/row-resize/row-resize.utils.js +55 -0
  43. package/dist/collection/plugins/sorting/sorting.plugin.js +16 -13
  44. package/dist/collection/plugins/wcag/index.js +5 -4
  45. package/dist/collection/serve/controller.js +1 -1
  46. package/dist/collection/services/data.provider.js +8 -2
  47. package/dist/collection/services/dimension.provider.js +17 -1
  48. package/dist/collection/services/local.scroll.timer.js +3 -3
  49. package/dist/collection/services/selection.store.connector.js +4 -2
  50. package/dist/collection/store/dataSource/data.pending.plugin.js +21 -0
  51. package/dist/collection/store/dataSource/data.store.js +25 -3
  52. package/dist/collection/store/dataSource/trimmed.plugin.js +9 -6
  53. package/dist/collection/store/dimension/dimension.trim.plugin.js +1 -3
  54. package/dist/collection/types/events.js +4 -1
  55. package/dist/collection/utils/column.utils.js +1 -1
  56. package/dist/esm/{cell-renderer-11cf-lu3.js → cell-renderer-D9ze8OJw.js} +3 -3
  57. package/dist/esm/{column.service-Cfw3L0PN.js → column.service-pu_fdQ0S.js} +5 -4
  58. package/dist/{revo-grid/dimension.helpers-fl4HSSK9.js → esm/dimension.helpers-Cln9sALu.js} +52 -9
  59. package/dist/{revo-grid/edit.utils-4e9fsqOR.js → esm/edit.utils-3ZbhQCv_.js} +1 -1
  60. package/dist/esm/{header-cell-renderer-Cqtg1ETB.js → header-cell-renderer-YCiVIQ2E.js} +1 -1
  61. package/dist/esm/{index-D24ku9ej.js → index-BvMNbQyq.js} +1 -1
  62. package/dist/esm/index.js +14 -11
  63. package/dist/esm/loader.js +1 -1
  64. package/dist/esm/revo-grid.entry.js +113 -68
  65. package/dist/esm/revo-grid.js +1 -1
  66. package/dist/esm/revogr-attribution_7.entry.js +51 -19
  67. package/dist/esm/revogr-clipboard_3.entry.js +4 -4
  68. package/dist/esm/revogr-data_4.entry.js +21 -15
  69. package/dist/esm/revogr-filter-panel.entry.js +9 -9
  70. package/dist/esm/{column.drag.plugin-DDBKeTGI.js → row-resize.plugin-DBOgjLdE.js} +748 -87
  71. package/dist/{revo-grid/text-editor-DlMnLkRK.js → esm/text-editor-eHtrwvxH.js} +2 -2
  72. package/dist/{revo-grid/throttle-Cpk1LoGk.js → esm/throttle-3rhqdcLy.js} +3 -3
  73. package/dist/{revo-grid/viewport.store-BSXmsiZc.js → esm/viewport.store-DWMKRDSH.js} +1 -1
  74. package/dist/revo-grid/{cell-renderer-11cf-lu3.js → cell-renderer-D9ze8OJw.js} +3 -3
  75. package/dist/revo-grid/{column.service-Cfw3L0PN.js → column.service-pu_fdQ0S.js} +5 -4
  76. package/dist/{esm/dimension.helpers-fl4HSSK9.js → revo-grid/dimension.helpers-Cln9sALu.js} +52 -9
  77. package/dist/{esm/edit.utils-4e9fsqOR.js → revo-grid/edit.utils-3ZbhQCv_.js} +1 -1
  78. package/dist/revo-grid/{header-cell-renderer-Cqtg1ETB.js → header-cell-renderer-YCiVIQ2E.js} +1 -1
  79. package/dist/revo-grid/{index-D24ku9ej.js → index-BvMNbQyq.js} +1 -1
  80. package/dist/revo-grid/index.esm.js +14 -11
  81. package/dist/revo-grid/revo-grid.entry.js +113 -68
  82. package/dist/revo-grid/revo-grid.esm.js +1 -1
  83. package/dist/revo-grid/revogr-attribution_7.entry.js +51 -19
  84. package/dist/revo-grid/revogr-clipboard_3.entry.js +4 -4
  85. package/dist/revo-grid/revogr-data_4.entry.js +21 -15
  86. package/dist/revo-grid/revogr-filter-panel.entry.js +9 -9
  87. package/dist/revo-grid/{column.drag.plugin-DDBKeTGI.js → row-resize.plugin-DBOgjLdE.js} +748 -87
  88. package/dist/{esm/text-editor-DlMnLkRK.js → revo-grid/text-editor-eHtrwvxH.js} +2 -2
  89. package/dist/{esm/throttle-Cpk1LoGk.js → revo-grid/throttle-3rhqdcLy.js} +3 -3
  90. package/dist/{esm/viewport.store-BSXmsiZc.js → revo-grid/viewport.store-DWMKRDSH.js} +1 -1
  91. package/dist/types/components/data/revogr-data.d.ts +1 -0
  92. package/dist/types/components/overlay/keyboard.service.d.ts +6 -0
  93. package/dist/types/components/overlay/revogr-overlay-selection.d.ts +3 -1
  94. package/dist/types/components/revoGrid/revo-grid.d.ts +9 -1
  95. package/dist/types/components/revoGrid/viewport.scrolling.service.d.ts +3 -1
  96. package/dist/types/components.d.ts +23 -10
  97. package/dist/types/plugins/filter/filter.constants.d.ts +6 -0
  98. package/dist/types/plugins/filter/filter.plugin.d.ts +15 -0
  99. package/dist/types/plugins/groupingRow/grouping.const.d.ts +1 -0
  100. package/dist/types/plugins/groupingRow/grouping.row.plugin.d.ts +5 -7
  101. package/dist/types/plugins/groupingRow/grouping.sorting.service.d.ts +7 -0
  102. package/dist/types/plugins/groupingRow/grouping.trimmed.service.d.ts +9 -0
  103. package/dist/types/plugins/index.d.ts +1 -0
  104. package/dist/types/plugins/row-resize/index.d.ts +3 -0
  105. package/dist/types/plugins/row-resize/row-resize.plugin.d.ts +46 -0
  106. package/dist/types/plugins/row-resize/row-resize.types.d.ts +40 -0
  107. package/dist/types/plugins/row-resize/row-resize.utils.d.ts +14 -0
  108. package/dist/types/plugins/sorting/sorting.plugin.d.ts +5 -0
  109. package/dist/types/services/data.provider.d.ts +2 -0
  110. package/dist/types/services/dimension.provider.d.ts +7 -1
  111. package/dist/types/store/dataSource/data.pending.plugin.d.ts +9 -0
  112. package/dist/types/store/dataSource/data.store.d.ts +10 -0
  113. package/dist/types/store/dataSource/trimmed.plugin.d.ts +5 -0
  114. package/dist/types/types/events.d.ts +1 -1
  115. package/dist/types/types/interfaces.d.ts +3 -1
  116. package/hydrate/index.js +980 -191
  117. package/hydrate/index.mjs +980 -191
  118. package/package.json +1 -1
  119. package/readme.md +4 -1
  120. package/standalone/column.service.js +1 -1
  121. package/standalone/data.store.js +1 -1
  122. package/standalone/dimension.helpers.js +1 -1
  123. package/standalone/index.js +1 -1
  124. package/standalone/local.scroll.timer.js +1 -1
  125. package/standalone/revo-grid.js +1 -1
  126. package/standalone/revogr-data2.js +1 -1
  127. package/standalone/revogr-filter-panel.js +1 -1
  128. package/standalone/revogr-header2.js +1 -1
  129. package/standalone/revogr-overlay-selection2.js +1 -1
  130. package/standalone/revogr-row-headers2.js +1 -1
@@ -107,7 +107,7 @@ export class FilterPanel {
107
107
  getFilterItemsList() {
108
108
  var _a, _b;
109
109
  const prop = (_a = this.changes) === null || _a === void 0 ? void 0 : _a.prop;
110
- if (typeof prop === 'undefined')
110
+ if (prop === undefined)
111
111
  return '';
112
112
  const propFilters = (_b = this.filterItems[prop]) !== null && _b !== void 0 ? _b : [];
113
113
  const visibleFilterCount = propFilters.filter(filter => !filter.hidden).length;
@@ -131,7 +131,7 @@ export class FilterPanel {
131
131
  'filter-row-dragging': isDragging,
132
132
  'filter-row-drag-over': isDragOver,
133
133
  } }, canReorder ? (h("button", { type: "button", class: "filter-row-drop-target", tabIndex: -1, "aria-label": `${capts.filterCondition} ${index + 1}`, onDragOver: e => this.onFilterDragOver(e, filter.id), onDragLeave: () => this.onFilterDragLeave(filter.id), onDrop: e => this.onFilterDrop(e, prop, filter.id) })) : '', canReorder ? (h(ReorderButton, { ariaLabel: capts.reorderFilter, dragging: isDragging, dragOver: isDragOver, onDragStart: e => this.onFilterDragStart(e, filter.id), onDragEnd: () => this.onFilterDragEnd(), onKeyDown: e => this.onFilterReorderKeyDown(e, prop, filter.id) })) : '', h("div", { class: { 'select-input': true } }, h("select", { class: "select-css select-filter", onChange: e => this.onFilterTypeChange(e, prop, index) }, this.renderSelectOptions(this.filterItems[prop][index].type, true)), extra ? h("div", { class: "filter-extra" }, extra) : ''), h("div", { class: FILTER_LIST_CLASS_ACTION }, andOrButton, h(TrashButton, { ariaLabel: capts.removeFilter, onClick: () => this.onRemoveFilter(filter.id) })))));
134
- })), propFilters.filter(f => !f.hidden).length > 0 ? h("div", { class: "add-filter-divider" }) : ''));
134
+ })), propFilters.some(f => !f.hidden) ? h("div", { class: "add-filter-divider" }) : ''));
135
135
  }
136
136
  componentDidRender() {
137
137
  this.syncDialog();
@@ -492,7 +492,7 @@ export class FilterPanel {
492
492
  top: `${(_d = (_c = this.changes) === null || _c === void 0 ? void 0 : _c.y) !== null && _d !== void 0 ? _d : 0}px`,
493
493
  };
494
494
  const capts = Object.assign(Object.assign({}, this.filterCaptionsInternal), this.filterCaptions);
495
- return (h(Host, { key: '8859c452eb08838f65f18efecbdde7f65fda2b49' }, h("dialog", { key: 'f603067ff0986a9f344cbbf816388d2bbac198bb', class: "filter-panel-dialog", style: style, ref: el => (this.dialog = el), onCancel: e => {
495
+ return (h(Host, { key: 'd0e4ebb408750b11b3965da6a25e581733c968e3' }, h("dialog", { key: '3df36777c931ec1063e8574169ca880a99dbfe41', class: "filter-panel-dialog", style: style, ref: el => (this.dialog = el), onCancel: e => {
496
496
  e.preventDefault();
497
497
  this.onCancel();
498
498
  } }, this.changes && [
@@ -501,16 +501,16 @@ export class FilterPanel {
501
501
  ((_g = this.changes) === null || _g === void 0 ? void 0 : _g.hideDefaultFilters) !== true && [
502
502
  h("label", { key: "filter-title" }, capts.title),
503
503
  h("div", { key: "filter-holder", class: "filter-holder" }, this.getFilterItemsList()),
504
- h("div", { key: "add-filter", class: "add-filter" }, h("select", { key: '2ec0a66918edf91bdde3962b6ec84c89f6f1c8f1', id: FILTER_ID, class: "select-css", onChange: e => this.onAddNewFilter(e) }, this.renderSelectOptions(this.currentFilterType))),
504
+ h("div", { key: "add-filter", class: "add-filter" }, h("select", { key: 'e2a8bd29f2090d3e6c933795427b71ca190b82aa', id: FILTER_ID, class: "select-css", onChange: e => this.onAddNewFilter(e) }, this.renderSelectOptions(this.currentFilterType))),
505
505
  ],
506
506
  h("slot", { key: "default-slot" }),
507
507
  ((_j = (_h = this.changes).extraBottomContent) === null || _j === void 0 ? void 0 : _j.call(_h, this.changes)) || '',
508
508
  h("div", { key: "filter-actions", class: "filter-actions" }, this.disableDynamicFiltering && [
509
- h("button", { key: "save", id: "revo-button-save", "aria-label": "save", class: "revo-button green", onClick: () => this.onSave() }, capts.save),
510
- h("button", { key: "cancel", id: "revo-button-ok", "aria-label": "ok", class: "revo-button green", onClick: () => this.onCancel() }, capts.cancel),
509
+ h("button", { key: "save", type: "button", id: "revo-button-save", "aria-label": "save", class: "revo-button green", onClick: () => this.onSave() }, capts.save),
510
+ h("button", { key: "cancel", type: "button", id: "revo-button-ok", "aria-label": "ok", class: "revo-button green", onClick: () => this.onCancel() }, capts.cancel),
511
511
  ], !this.disableDynamicFiltering && [
512
- h("button", { key: "ok", id: "revo-button-ok", "aria-label": "ok", class: "revo-button green", onClick: () => this.onCancel() }, capts.ok),
513
- h("button", { key: "reset", id: "revo-button-reset", "aria-label": "reset", class: "revo-button outline", onClick: () => this.onReset() }, capts.reset),
512
+ h("button", { key: "ok", type: "button", id: "revo-button-ok", "aria-label": "ok", class: "revo-button green", onClick: () => this.onCancel() }, capts.ok),
513
+ h("button", { key: "reset", type: "button", id: "revo-button-reset", "aria-label": "reset", class: "revo-button outline", onClick: () => this.onReset() }, capts.reset),
514
514
  ]),
515
515
  h("slot", { key: "footer-slot", slot: "footer" }),
516
516
  ])));
@@ -6,8 +6,9 @@ import { h } from "@stencil/core";
6
6
  import { BasePlugin } from "../base.plugin";
7
7
  import { FILTER_PROP, isFilterBtn } from "./filter.button";
8
8
  import { filterCoreFunctionsIndexedByType, filterNames, filterTypes, } from "./filter.indexed";
9
- import { timeout } from "../../utils";
10
9
  import { resolveBlankSemantics } from "./filter.blank";
10
+ import { timeout } from "../../utils";
11
+ import { ASYNC_FILTER_ROW_THRESHOLD, FILTER_CHUNK_SIZE, FILTER_TIME_BUDGET_MS, } from "./filter.constants";
11
12
  export * from './filter.types';
12
13
  export * from './filter.indexed';
13
14
  export * from './filter.blank';
@@ -55,6 +56,7 @@ export class FilterPlugin extends BasePlugin {
55
56
  this.filterFunctionsIndexedByType = Object.assign({}, filterCoreFunctionsIndexedByType);
56
57
  this.filterProp = FILTER_PROP;
57
58
  this.allowDuplicateOperators = true;
59
+ this.filteringRunId = 0;
58
60
  if (config) {
59
61
  this.initConfig(config);
60
62
  }
@@ -63,7 +65,7 @@ export class FilterPlugin extends BasePlugin {
63
65
  ...existingNodes,
64
66
  h("revogr-filter-panel", { filterNames: this.filterNameIndexByType, filterEntities: this.filterFunctionsIndexedByType, filterCaptions: (_a = config === null || config === void 0 ? void 0 : config.localization) === null || _a === void 0 ? void 0 : _a.captions, onFilterChange: e => this.onFilterChange(e.detail), onResetChange: e => this.onFilterReset(e.detail), disableDynamicFiltering: config === null || config === void 0 ? void 0 : config.disableDynamicFiltering, closeOnOutsideClick: config === null || config === void 0 ? void 0 : config.closeFilterPanelOnOutsideClick, allowDuplicateOperators: this.allowDuplicateOperators, ref: e => (this.pop = e) }, ' ', this.extraContent()),
65
67
  ];
66
- const aftersourceset = async () => {
68
+ const aftersourceset = () => {
67
69
  const filterCollectionProps = Object.keys(this.filterCollection);
68
70
  if (filterCollectionProps.length > 0) {
69
71
  // handle old way of filtering by reworking FilterCollection to new MultiFilterItem
@@ -80,12 +82,26 @@ export class FilterPlugin extends BasePlugin {
80
82
  }
81
83
  });
82
84
  }
83
- if (Object.keys(this.multiFilterItems).length === 0) {
85
+ if (!this.hasActiveFilters()) {
86
+ this.cancelFiltering();
84
87
  return;
85
88
  }
86
- await timeout();
87
- await this.runFiltering(this.multiFilterItems);
89
+ void this.runFiltering(this.multiFilterItems);
88
90
  };
91
+ /**
92
+ * This executes before the data store replaces its source.
93
+ * For a large source with active filters:
94
+ * 1. Existing filtering runs are invalidated.
95
+ * 2. Pending state starts.
96
+ * 3. Visible rows become empty.
97
+ * 4. The source is replaced while the DataStore guard prevents it from exposing unfiltered rows.
98
+ */
99
+ this.addEventListener('beforesourceset', ({ detail }) => {
100
+ if (detail.source.length >= ASYNC_FILTER_ROW_THRESHOLD &&
101
+ this.hasActiveFilters()) {
102
+ this.deferFiltering();
103
+ }
104
+ });
89
105
  this.addEventListener('headerclick', e => this.headerclick(e));
90
106
  this.addEventListener(FILTER_CONFIG_CHANGED_EVENT, ({ detail }) => {
91
107
  if (!detail) {
@@ -246,7 +262,7 @@ export class FilterPlugin extends BasePlugin {
246
262
  // store the filter items
247
263
  this.multiFilterItems = filterItems;
248
264
  // run the filtering when the items change
249
- this.runFiltering(this.multiFilterItems);
265
+ await this.runFiltering(this.multiFilterItems);
250
266
  }
251
267
  onFilterReset(prop) {
252
268
  delete this.multiFilterItems[prop !== null && prop !== void 0 ? prop : ''];
@@ -256,6 +272,8 @@ export class FilterPlugin extends BasePlugin {
256
272
  * Triggers grid filtering
257
273
  */
258
274
  async doFiltering(collection, source, columns, filterItems) {
275
+ // creates the execution token - owns the actual calculation
276
+ const runId = this.beginFiltering();
259
277
  const columnsToUpdate = [];
260
278
  /**
261
279
  * Loop through the columns and update the columns that need to be updated with the `hasFilter` property.
@@ -280,7 +298,25 @@ export class FilterPlugin extends BasePlugin {
280
298
  column[this.filterProp] = true;
281
299
  }
282
300
  });
283
- const itemsToTrim = this.getRowFilter(source, filterItems, columnByProp);
301
+ let itemsToTrim;
302
+ const hasFilters = Object.keys(filterItems).length > 0 || this.hasActiveFilters();
303
+ const isLargeSource = hasFilters && source.length >= ASYNC_FILTER_ROW_THRESHOLD;
304
+ if (isLargeSource) {
305
+ this.providers.data.setItemsPending(true);
306
+ await timeout();
307
+ }
308
+ if (!hasFilters) {
309
+ itemsToTrim = {};
310
+ }
311
+ else if (isLargeSource && this.supportsChunkedFiltering()) {
312
+ itemsToTrim = await this.getRowFilterInChunks(source, filterItems, columnByProp, runId);
313
+ }
314
+ else {
315
+ itemsToTrim = this.getRowFilter(source, filterItems, columnByProp);
316
+ }
317
+ if (!itemsToTrim || runId !== this.filteringRunId) {
318
+ return;
319
+ }
284
320
  // check is filter event prevented
285
321
  const { defaultPrevented, detail } = this.emit('beforefiltertrimmed', {
286
322
  collection,
@@ -288,10 +324,12 @@ export class FilterPlugin extends BasePlugin {
288
324
  source,
289
325
  filterItems,
290
326
  });
291
- if (defaultPrevented) {
327
+ if (defaultPrevented || runId !== this.filteringRunId) {
328
+ this.releaseFiltering(runId);
292
329
  return;
293
330
  }
294
331
  this.providers.data.setTrimmed({ [FILTER_TRIMMED_TYPE]: detail.itemsToFilter });
332
+ this.releaseFiltering(runId);
295
333
  // applies the hasFilter to the columns to show filter icon
296
334
  this.providers.column.updateColumns(columnsToUpdate);
297
335
  this.emit('afterfilterapply', {
@@ -305,6 +343,10 @@ export class FilterPlugin extends BasePlugin {
305
343
  await this.runFiltering(this.multiFilterItems);
306
344
  }
307
345
  async runFiltering(multiFilterItems) {
346
+ // runFiltering: First token: "Is this request still valid after event handlers run?"
347
+ // doFiltering: Second token: "Is this calculation still the newest one?"
348
+ // creates a preflight token and sets the grid to a pending state
349
+ const runId = this.beginFiltering();
308
350
  const collection = {};
309
351
  // handle old filterCollection to return the first filter only (if any) from multiFilterItems
310
352
  const filterProps = Object.keys(multiFilterItems);
@@ -328,10 +370,67 @@ export class FilterPlugin extends BasePlugin {
328
370
  columns,
329
371
  filterItems: this.multiFilterItems,
330
372
  });
331
- if (defaultPrevented) {
373
+ if (defaultPrevented || runId !== this.filteringRunId) {
374
+ this.releaseFiltering(runId);
332
375
  return;
333
376
  }
334
- this.doFiltering(detail.collection, detail.source, detail.columns, detail.filterItems);
377
+ await this.doFiltering(detail.collection, detail.source, detail.columns, detail.filterItems);
378
+ }
379
+ /** Whether this plugin currently owns filter state that must follow a new source. */
380
+ hasActiveFilters() {
381
+ return (Object.keys(this.multiFilterItems).length > 0 ||
382
+ Object.keys(this.filterCollection).length > 0);
383
+ }
384
+ /** Preserve whole-source semantics for plugins that override getRowFilter. */
385
+ supportsChunkedFiltering() {
386
+ return this.getRowFilter === FilterPlugin.prototype.getRowFilter;
387
+ }
388
+ /**
389
+ * Hide visible rows and invalidate current filtering until a deferred filter
390
+ * run is ready. Used by filter extensions with their own debounced state.
391
+ */
392
+ deferFiltering() {
393
+ this.beginFiltering(true);
394
+ }
395
+ beginFiltering(pending = false) {
396
+ const runId = ++this.filteringRunId;
397
+ if (pending) {
398
+ this.providers.data.setItemsPending(true);
399
+ }
400
+ return runId;
401
+ }
402
+ releaseFiltering(runId) {
403
+ if (runId === this.filteringRunId) {
404
+ this.providers.data.setItemsPending(false);
405
+ }
406
+ }
407
+ cancelFiltering() {
408
+ this.releaseFiltering(this.beginFiltering());
409
+ }
410
+ async getRowFilterInChunks(rows, filterItems, columnByProp, runId) {
411
+ const trimmed = {};
412
+ let sliceStarted = performance.now();
413
+ for (let offset = 0; offset < rows.length; offset += FILTER_CHUNK_SIZE) {
414
+ if (runId !== this.filteringRunId) {
415
+ return;
416
+ }
417
+ const end = Math.min(offset + FILTER_CHUNK_SIZE, rows.length);
418
+ const chunkTrimmed = this.getRowFilter(rows.slice(offset, end), filterItems, columnByProp);
419
+ // filter that chunk
420
+ for (const chunkIndex in chunkTrimmed) {
421
+ trimmed[offset + Number(chunkIndex)] = true;
422
+ }
423
+ if (end < rows.length &&
424
+ performance.now() - sliceStarted >= FILTER_TIME_BUDGET_MS) {
425
+ await timeout();
426
+ sliceStarted = performance.now();
427
+ }
428
+ }
429
+ return runId === this.filteringRunId ? trimmed : undefined;
430
+ }
431
+ destroy() {
432
+ this.cancelFiltering();
433
+ super.destroy();
335
434
  }
336
435
  /**
337
436
  * Get trimmed rows based on filter
@@ -127,6 +127,8 @@ revogr-filter-panel .filter-panel-dialog .filter-actions button {
127
127
  visibility: visible;
128
128
  cursor: pointer;
129
129
  border-radius: 4px;
130
+ position: relative;
131
+ z-index: 1;
130
132
  }
131
133
  .rgHeaderCell .rv-filter.active {
132
134
  color: var(--rg-theme-filter-panel-icon-active);
@@ -12,4 +12,5 @@ export const GROUP_COLUMN_PROP = `${GRID_INTERNALS}-prop`;
12
12
  export const GROUP_ORIGINAL_INDEX = `${GRID_INTERNALS}-original-index`;
13
13
  export const GROUP_EXPAND_BTN = `group-expand`;
14
14
  export const GROUP_EXPAND_EVENT = `groupexpandclick`;
15
+ export const BEFORE_GROUPING_APPLY_EVENT = `beforegroupingapply`;
15
16
  export const GROUPING_ROW_TYPE = 'rgRow';
@@ -1,26 +1,14 @@
1
1
  /*!
2
2
  * Built by Revolist OU ❤️
3
3
  */
4
- var __rest = (this && this.__rest) || function (s, e) {
5
- var t = {};
6
- for (var p in s)
7
- if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
8
- t[p] = s[p];
9
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
10
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
11
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
12
- t[p[i]] = s[p[i]];
13
- }
14
- return t;
15
- };
16
4
  import { getPhysical, setItems, columnTypes, } from "../../store/index";
17
5
  import { BasePlugin } from "../base.plugin";
18
6
  import { FILTER_TRIMMED_TYPE } from "../filter/filter.plugin";
19
- import { SortingPlugin } from "../sorting/sorting.plugin";
20
- import { GROUP_EXPAND_EVENT, GROUPING_ROW_TYPE, PSEUDO_GROUP_COLUMN, } from "./grouping.const";
7
+ import { SortingPlugin, hasActiveSorting } from "../sorting/sorting.plugin";
8
+ import { BEFORE_GROUPING_APPLY_EVENT, GROUP_EXPAND_EVENT, GROUPING_ROW_TYPE, PSEUDO_GROUP_COLUMN, PSEUDO_GROUP_ITEM_ID, } from "./grouping.const";
21
9
  import { doExpand, doCollapse } from "./grouping.row.expand.service";
22
10
  import { gatherGrouping, getExpanded, getSource, isGrouping, isGroupingColumn, } from "./grouping.service";
23
- import { filterOutEmptyGroupRows, processDoubleConversionTrimmed, TRIMMED_GROUPING, } from "./grouping.trimmed.service";
11
+ import { convertGroupingIndex, filterOutEmptyGroupRows, processDoubleConversionTrimmed, TRIMMED_GROUPING, } from "./grouping.trimmed.service";
24
12
  export * from './grouping.const';
25
13
  export * from './grouping.row.expand.service';
26
14
  export * from './grouping.row.types';
@@ -41,15 +29,16 @@ export class GroupingRowPlugin extends BasePlugin {
41
29
  }
42
30
  // expand event triggered
43
31
  onExpand({ virtualIndex }) {
44
- const { source } = getSource(this.getStore().get('source'), this.getStore().get('proxyItems'));
45
- let newTrimmed = this.getStore().get('trimmed')[TRIMMED_GROUPING];
46
- let i = getPhysical(this.getStore(), virtualIndex);
32
+ const store = this.getStore();
33
+ const source = store.get('source');
34
+ let newTrimmed = store.get('trimmed')[TRIMMED_GROUPING];
35
+ const i = getPhysical(store, virtualIndex);
47
36
  const isExpanded = getExpanded(source[i]);
48
37
  if (!isExpanded) {
49
- const { trimmed, items } = doExpand(virtualIndex, source, this.getStore().get('items'));
38
+ const { trimmed, items: expandedItems } = doExpand(virtualIndex, source, store.get('items'));
50
39
  newTrimmed = Object.assign(Object.assign({}, newTrimmed), trimmed);
51
- if (items) {
52
- setItems(this.getStore(), items);
40
+ if (expandedItems) {
41
+ setItems(store, expandedItems);
53
42
  }
54
43
  }
55
44
  else {
@@ -57,7 +46,7 @@ export class GroupingRowPlugin extends BasePlugin {
57
46
  newTrimmed = Object.assign(Object.assign({}, newTrimmed), trimmed);
58
47
  this.revogrid.clearFocus();
59
48
  }
60
- this.getStore().set('source', source);
49
+ store.set('source', source);
61
50
  this.revogrid.addTrimmed(newTrimmed, TRIMMED_GROUPING);
62
51
  }
63
52
  setColumnGrouping(cols) {
@@ -79,7 +68,7 @@ export class GroupingRowPlugin extends BasePlugin {
79
68
  onDrag(e) {
80
69
  const { from, to } = e.detail;
81
70
  const isDown = to - from >= 0;
82
- const { source } = getSource(this.getStore().get('source'), this.getStore().get('proxyItems'));
71
+ const source = this.getStore().get('source');
83
72
  const items = this.getStore().get('items');
84
73
  let i = isDown ? from : to;
85
74
  const end = isDown ? to : from;
@@ -105,21 +94,13 @@ export class GroupingRowPlugin extends BasePlugin {
105
94
  const source = this.getStore().get('source');
106
95
  return filterOutEmptyGroupRows(source, trimmed);
107
96
  }
108
- isSortingRunning() {
109
- const sortingPlugin = this.providers.plugins.getByClass(SortingPlugin);
110
- return !!(sortingPlugin === null || sortingPlugin === void 0 ? void 0 : sortingPlugin.sortingPromise);
111
- }
112
97
  /**
113
- * Returns grouping options for regrouping that must preserve current UI state.
114
- *
115
- * `expandedAll` and config `prevExpanded` are initial/config instructions.
116
- * Reusing them after sorting would reopen groups the user collapsed before
117
- * sorting instead of using the current grouped source state.
98
+ * Sorting changes proxy order without changing the physical source baseline.
99
+ * Other proxy changes, such as row dragging, are user-authored source order
100
+ * and must be retained when grouping is rebuilt.
118
101
  */
119
- getCurrentExpandedOptions() {
120
- var _a;
121
- const _b = (_a = this.options) !== null && _a !== void 0 ? _a : {}, { expandedAll: _expandedAll, prevExpanded: _prevExpanded } = _b, options = __rest(_b, ["expandedAll", "prevExpanded"]);
122
- return options;
102
+ isSortingActiveOrPending(sortingPlugin) {
103
+ return !!(sortingPlugin === null || sortingPlugin === void 0 ? void 0 : sortingPlugin.sortingPromise) || hasActiveSorting(sortingPlugin === null || sortingPlugin === void 0 ? void 0 : sortingPlugin.sorting);
123
104
  }
124
105
  /**
125
106
  * Starts global source update with group clearing and applying new one
@@ -132,7 +113,12 @@ export class GroupingRowPlugin extends BasePlugin {
132
113
  * @param newOldIndexMap - provides us mapping with new indexes vs old indexes, we would use it for trimmed mapping
133
114
  */
134
115
  const store = this.getStore();
135
- const { source, prevExpanded, oldNewIndexes } = getSource(store.get('source'), store.get('proxyItems'), true);
116
+ const sortingPlugin = this.providers.plugins.getByClass(SortingPlugin);
117
+ const currentSource = store.get('source');
118
+ const sourceItems = this.isSortingActiveOrPending(sortingPlugin)
119
+ ? currentSource.map((_, index) => index)
120
+ : store.get('proxyItems');
121
+ const { source, prevExpanded, oldNewIndexes } = getSource(currentSource, sourceItems, true);
136
122
  const expanded = Object.assign({ prevExpanded }, options);
137
123
  /**
138
124
  * Group again
@@ -142,8 +128,13 @@ export class GroupingRowPlugin extends BasePlugin {
142
128
  const customRenderer = options === null || options === void 0 ? void 0 : options.groupLabelTemplate;
143
129
  const cellRenderer = options === null || options === void 0 ? void 0 : options.groupCellTemplate;
144
130
  // setup source
131
+ this.revogrid.dispatchEvent(new CustomEvent(BEFORE_GROUPING_APPLY_EVENT));
145
132
  this.providers.data.setData(sourceWithGroups, GROUPING_ROW_TYPE, this.revogrid.disableVirtualY, { depth, customRenderer, cellRenderer }, true);
133
+ this.remapRowDefinitions(oldNewIndexes !== null && oldNewIndexes !== void 0 ? oldNewIndexes : {}, oldNewIndexMap, currentSource, sourceWithGroups);
146
134
  this.updateTrimmed(trimmed, oldNewIndexes !== null && oldNewIndexes !== void 0 ? oldNewIndexes : {}, oldNewIndexMap, sourceWithGroups);
135
+ if (hasActiveSorting(sortingPlugin === null || sortingPlugin === void 0 ? void 0 : sortingPlugin.sorting)) {
136
+ sortingPlugin === null || sortingPlugin === void 0 ? void 0 : sortingPlugin.reapplySorting();
137
+ }
147
138
  }
148
139
  /**
149
140
  * Apply grouping on data set
@@ -152,9 +143,14 @@ export class GroupingRowPlugin extends BasePlugin {
152
143
  */
153
144
  onDataSet(data) {
154
145
  var _a, _b, _c;
146
+ const currentSource = this.getStore().get('source');
147
+ const sortingPlugin = this.providers.plugins.getByClass(SortingPlugin);
148
+ const currentItems = this.isSortingActiveOrPending(sortingPlugin)
149
+ ? currentSource.map((_, index) => index)
150
+ : this.getStore().get('proxyItems');
151
+ const { prevExpanded, oldNewIndexes } = getSource(currentSource, currentItems, true);
155
152
  let preservedExpanded = {};
156
153
  if (((_a = this.options) === null || _a === void 0 ? void 0 : _a.preserveGroupingOnUpdate) !== false) {
157
- let { prevExpanded } = getSource(this.getStore().get('source'), this.getStore().get('proxyItems'), true);
158
154
  preservedExpanded = prevExpanded;
159
155
  }
160
156
  const source = data.source.filter(s => !isGrouping(s));
@@ -166,7 +162,8 @@ export class GroupingRowPlugin extends BasePlugin {
166
162
  customRenderer: options.groupLabelTemplate,
167
163
  cellRenderer: options.groupCellTemplate,
168
164
  });
169
- this.updateTrimmed(trimmed, oldNewIndexMap, undefined, sourceWithGroups);
165
+ queueMicrotask(() => this.remapRowDefinitions(oldNewIndexes !== null && oldNewIndexes !== void 0 ? oldNewIndexes : {}, oldNewIndexMap, currentSource, sourceWithGroups));
166
+ this.updateTrimmed(trimmed, oldNewIndexMap, undefined, sourceWithGroups, { filterTrimmedMode: 'recompute-after-source-set' });
170
167
  }
171
168
  /**
172
169
  * External call to apply grouping. Called by revogrid when prop changed.
@@ -201,10 +198,6 @@ export class GroupingRowPlugin extends BasePlugin {
201
198
  if (!(((_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.props) === null || _b === void 0 ? void 0 : _b.length) && ((_c = detail === null || detail === void 0 ? void 0 : detail.source) === null || _c === void 0 ? void 0 : _c.length))) {
202
199
  return;
203
200
  }
204
- // if sorting is running don't apply grouping, wait for sorting, then it'll apply in @aftersortingapply
205
- if (this.isSortingRunning()) {
206
- return;
207
- }
208
201
  this.onDataSet(detail);
209
202
  });
210
203
  this.addEventListener('beforecolumnsset', ({ detail }) => {
@@ -219,17 +212,6 @@ export class GroupingRowPlugin extends BasePlugin {
219
212
  this.addEventListener('beforefiltertrimmed', ({ detail }) => {
220
213
  detail.itemsToFilter = this.beforeFilterTrimmed(detail.itemsToFilter);
221
214
  });
222
- /**
223
- * sorting applied need to clear grouping and apply again
224
- * based on new results whole grouping order will changed
225
- */
226
- this.addEventListener('aftersortingapply', () => {
227
- var _a, _b;
228
- if (!((_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.props) === null || _b === void 0 ? void 0 : _b.length)) {
229
- return;
230
- }
231
- this.doSourceUpdate(this.getCurrentExpandedOptions());
232
- });
233
215
  /**
234
216
  * Apply logic for focus inside of grouping
235
217
  * We can't focus on grouping rows, navigation only inside of groups for now
@@ -262,14 +244,69 @@ export class GroupingRowPlugin extends BasePlugin {
262
244
  }
263
245
  });
264
246
  // clear rows
265
- const { source, oldNewIndexes } = getSource(this.getStore().get('source'), this.getStore().get('proxyItems'), true);
247
+ const store = this.getStore();
248
+ const sortingPlugin = this.providers.plugins.getByClass(SortingPlugin);
249
+ const currentSource = store.get('source');
250
+ const sourceItems = this.isSortingActiveOrPending(sortingPlugin)
251
+ ? currentSource.map((_, index) => index)
252
+ : store.get('proxyItems');
253
+ const { source, oldNewIndexes } = getSource(currentSource, sourceItems, true);
254
+ this.revogrid.dispatchEvent(new CustomEvent(BEFORE_GROUPING_APPLY_EVENT));
266
255
  this.providers.data.setData(source, GROUPING_ROW_TYPE, this.revogrid.disableVirtualY, undefined, true);
256
+ this.remapRowDefinitions(oldNewIndexes !== null && oldNewIndexes !== void 0 ? oldNewIndexes : {}, undefined, currentSource, source);
267
257
  this.updateTrimmed(undefined, undefined, oldNewIndexes, source);
258
+ if (hasActiveSorting(sortingPlugin === null || sortingPlugin === void 0 ? void 0 : sortingPlugin.sorting)) {
259
+ sortingPlugin === null || sortingPlugin === void 0 ? void 0 : sortingPlugin.reapplySorting();
260
+ }
261
+ }
262
+ remapRowDefinitions(firstLevelMap, secondLevelMap, previousSource, nextSource) {
263
+ const definitions = this.providers.dimension.getRowDefinitions();
264
+ const nextGroupIndexes = new Map();
265
+ nextSource === null || nextSource === void 0 ? void 0 : nextSource.forEach((row, index) => {
266
+ const groupId = row[PSEUDO_GROUP_ITEM_ID];
267
+ if (groupId && !nextGroupIndexes.has(groupId)) {
268
+ nextGroupIndexes.set(groupId, index);
269
+ }
270
+ });
271
+ let changed = false;
272
+ const remapped = definitions.flatMap(definition => {
273
+ if (definition.type !== GROUPING_ROW_TYPE) {
274
+ return [definition];
275
+ }
276
+ const previousRow = previousSource === null || previousSource === void 0 ? void 0 : previousSource[definition.index];
277
+ const groupId = previousRow === null || previousRow === void 0 ? void 0 : previousRow[PSEUDO_GROUP_ITEM_ID];
278
+ const index = groupId
279
+ ? nextGroupIndexes.get(groupId)
280
+ : convertGroupingIndex(definition.index, firstLevelMap, secondLevelMap);
281
+ if (typeof index !== 'number') {
282
+ changed = true;
283
+ return [];
284
+ }
285
+ if (index < 0) {
286
+ changed = true;
287
+ return [];
288
+ }
289
+ if (index === definition.index) {
290
+ return [definition];
291
+ }
292
+ changed = true;
293
+ return [Object.assign(Object.assign({}, definition), { index })];
294
+ });
295
+ if (changed) {
296
+ this.providers.dimension.setRowDefinitions(remapped);
297
+ }
268
298
  }
269
- updateTrimmed(trimmedGroup = {}, firstLevelMap = {}, secondLevelMap, source = this.getStore().get('source')) {
299
+ updateTrimmed(trimmedGroup = {}, firstLevelMap = {}, secondLevelMap, source = this.getStore().get('source'), { filterTrimmedMode = 'remap', } = {}) {
270
300
  // map previously trimmed data
271
301
  const trimemedOptionsToUpgrade = processDoubleConversionTrimmed(this.getStore().get('trimmed'), firstLevelMap, secondLevelMap);
272
302
  for (let type in trimemedOptionsToUpgrade) {
303
+ if (filterTrimmedMode === 'recompute-after-source-set' &&
304
+ type === FILTER_TRIMMED_TYPE) {
305
+ // The filter plugin recalculates this trim against the installed source
306
+ // during aftersourceset. Reapplying remapped old indexes afterwards
307
+ // would overwrite that fresh result.
308
+ continue;
309
+ }
273
310
  if (type === FILTER_TRIMMED_TYPE) {
274
311
  /** Regrouping changes physical indexes, so filter trim needs fresh group-header state. */
275
312
  trimemedOptionsToUpgrade[type] = filterOutEmptyGroupRows(source, trimemedOptionsToUpgrade[type]);
@@ -88,7 +88,7 @@ export const GroupingRowRenderer = (props) => {
88
88
  depth })))));
89
89
  }
90
90
  return (h(RowRenderer, Object.assign({}, props, groupRowAttrs), hasExpand && [
91
- h("button", { class: { [GROUP_EXPAND_BTN]: true }, onClick: e => expandEvent(e, model, itemIndex) }, expandSvgIconVNode(expanded)),
91
+ h("button", { type: "button", class: { [GROUP_EXPAND_BTN]: true }, onClick: e => expandEvent(e, model, itemIndex) }, expandSvgIconVNode(expanded)),
92
92
  String(name),
93
93
  ]));
94
94
  };
@@ -158,7 +158,7 @@ export function isGrouping(rgRow) {
158
158
  return typeof (rgRow === null || rgRow === void 0 ? void 0 : rgRow[PSEUDO_GROUP_ITEM]) !== 'undefined';
159
159
  }
160
160
  export function isGroupingColumn(column) {
161
- return typeof (column === null || column === void 0 ? void 0 : column[PSEUDO_GROUP_COLUMN]) !== 'undefined';
161
+ return (column === null || column === void 0 ? void 0 : column[PSEUDO_GROUP_COLUMN]) !== undefined;
162
162
  }
163
163
  export function measureEqualDepth(groupA, groupB) {
164
164
  const ln = groupA.length;
@@ -0,0 +1,58 @@
1
+ /*!
2
+ * Built by Revolist OU ❤️
3
+ */
4
+ import { GROUP_DEPTH } from "./grouping.const";
5
+ import { isGrouping } from "./grouping.service";
6
+ /**
7
+ * Restores group headers around already-sorted data indexes without rebuilding
8
+ * the physical source. Group insertion order follows the first sorted member,
9
+ * matching the order produced by regrouping a sorted source.
10
+ */
11
+ export function gatherGroupedRowIndexes(source, sortedDataIndexes) {
12
+ const groupPathByDataIndex = new Map();
13
+ const currentGroupPath = [];
14
+ source.forEach((model, physicalIndex) => {
15
+ if (isGrouping(model)) {
16
+ const depth = model[GROUP_DEPTH];
17
+ if (typeof depth !== 'number') {
18
+ return;
19
+ }
20
+ currentGroupPath.length = depth;
21
+ currentGroupPath[depth] = physicalIndex;
22
+ return;
23
+ }
24
+ if (model != null) {
25
+ groupPathByDataIndex.set(physicalIndex, [...currentGroupPath]);
26
+ }
27
+ });
28
+ const root = {
29
+ children: new Map(),
30
+ items: [],
31
+ };
32
+ for (const physicalIndex of sortedDataIndexes) {
33
+ const groupPath = groupPathByDataIndex.get(physicalIndex);
34
+ if (!(groupPath === null || groupPath === void 0 ? void 0 : groupPath.length)) {
35
+ return undefined;
36
+ }
37
+ let node = root;
38
+ for (const groupIndex of groupPath) {
39
+ let child = node.children.get(groupIndex);
40
+ if (!child) {
41
+ child = { children: new Map(), items: [] };
42
+ node.children.set(groupIndex, child);
43
+ }
44
+ node = child;
45
+ }
46
+ node.items.push(physicalIndex);
47
+ }
48
+ const groupedIndexes = [];
49
+ const appendNode = (node) => {
50
+ node.children.forEach((child, groupIndex) => {
51
+ groupedIndexes.push(groupIndex);
52
+ appendNode(child);
53
+ });
54
+ groupedIndexes.push(...node.items);
55
+ };
56
+ appendNode(root);
57
+ return groupedIndexes;
58
+ }
@@ -13,8 +13,10 @@ export const TRIMMED_GROUPING = 'grouping';
13
13
  * against the grouped physical source can still be remapped. If neither path
14
14
  * resolves to a number, the caller drops the stale trim entry.
15
15
  */
16
- function convertTrimmedIndex(initialIndex, firstLevelMap, secondLevelMap) {
17
- const sourceIndex = Number.parseInt(initialIndex, 10);
16
+ export function convertGroupingIndex(initialIndex, firstLevelMap, secondLevelMap) {
17
+ const sourceIndex = typeof initialIndex === 'number'
18
+ ? initialIndex
19
+ : Number.parseInt(initialIndex, 10);
18
20
  const firstConversionIndex = firstLevelMap[sourceIndex];
19
21
  if (!secondLevelMap) {
20
22
  return firstConversionIndex;
@@ -47,7 +49,7 @@ export function processDoubleConversionTrimmed(initiallyTrimed, firstLevelMap, s
47
49
  * if item exists we find it in collection
48
50
  * we support 2 level of conversions
49
51
  */
50
- const newConversionIndex = convertTrimmedIndex(initialIndex, firstLevelMap, secondLevelMap);
52
+ const newConversionIndex = convertGroupingIndex(initialIndex, firstLevelMap, secondLevelMap);
51
53
  // Group rows do not exist in the ungrouped index map and must not leak into new trims.
52
54
  if (typeof newConversionIndex !== 'number') {
53
55
  continue;
@@ -9,6 +9,7 @@ export * from './export/export.plugin';
9
9
  export * from './filter/filter.plugin';
10
10
  export * from './groupingRow/grouping.row.plugin';
11
11
  export * from './moveColumn/column.drag.plugin';
12
+ export * from './row-resize';
12
13
  export * from './sorting/sorting.plugin';
13
14
  export * from './sorting/sorting.sign';
14
15
  export * from './add-rows-on-paste.plugin';
@@ -0,0 +1,6 @@
1
+ /*!
2
+ * Built by Revolist OU ❤️
3
+ */
4
+ export * from './row-resize.plugin';
5
+ export * from './row-resize.types';
6
+ export * from './row-resize.utils';