@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.
- package/dist/cjs/{cell-renderer-Cf2Pu4S0.js → cell-renderer-BDIx0xys.js} +3 -3
- package/dist/cjs/{column.service-C7p5eC5V.js → column.service-D-ENzqyb.js} +5 -3
- package/dist/cjs/{dimension.helpers-CgHhnN1d.js → dimension.helpers-CptesQOZ.js} +52 -8
- package/dist/cjs/{edit.utils-rAcGublN.js → edit.utils-CBAbQhGP.js} +1 -1
- package/dist/cjs/{header-cell-renderer-DHClfIto.js → header-cell-renderer-B5Y4fdZC.js} +1 -1
- package/dist/cjs/{index--FdNLz1Z.js → index-BVESmpqW.js} +1 -1
- package/dist/cjs/index.cjs.js +72 -55
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/revo-grid.cjs.entry.js +131 -86
- package/dist/cjs/revo-grid.cjs.js +1 -1
- package/dist/cjs/revogr-attribution_7.cjs.entry.js +51 -19
- package/dist/cjs/revogr-clipboard_3.cjs.entry.js +4 -4
- package/dist/cjs/revogr-data_4.cjs.entry.js +21 -15
- package/dist/cjs/revogr-filter-panel.cjs.entry.js +9 -9
- package/dist/cjs/{column.drag.plugin-CK5HADlW.js → row-resize.plugin-sK9_rcUN.js} +759 -86
- package/dist/cjs/{text-editor-F04kTx53.js → text-editor-CJyQaYei.js} +2 -2
- package/dist/cjs/{throttle-fV6BUmM7.js → throttle-BsaP4fgu.js} +3 -3
- package/dist/cjs/{viewport.store-B4Clk4m9.js → viewport.store-mhsdi61t.js} +1 -1
- package/dist/collection/components/data/revogr-data-style.css +11 -0
- package/dist/collection/components/data/revogr-data.js +14 -8
- package/dist/collection/components/header/revogr-header-style.css +1 -0
- package/dist/collection/components/overlay/keyboard.service.js +33 -3
- package/dist/collection/components/overlay/revogr-overlay-selection.js +12 -10
- package/dist/collection/components/revoGrid/plugin.service.js +2 -2
- package/dist/collection/components/revoGrid/revo-grid.js +80 -30
- package/dist/collection/components/revoGrid/viewport.scrolling.service.js +24 -13
- package/dist/collection/components/revoGrid/viewport.service.js +1 -1
- package/dist/collection/plugins/filter/filter.constants.js +9 -0
- package/dist/collection/plugins/filter/filter.panel.js +8 -8
- package/dist/collection/plugins/filter/filter.plugin.js +109 -10
- package/dist/collection/plugins/filter/filter.style.css +2 -0
- package/dist/collection/plugins/groupingRow/grouping.const.js +1 -0
- package/dist/collection/plugins/groupingRow/grouping.row.plugin.js +93 -56
- package/dist/collection/plugins/groupingRow/grouping.row.renderer.js +1 -1
- package/dist/collection/plugins/groupingRow/grouping.service.js +1 -1
- package/dist/collection/plugins/groupingRow/grouping.sorting.service.js +58 -0
- package/dist/collection/plugins/groupingRow/grouping.trimmed.service.js +5 -3
- package/dist/collection/plugins/index.js +1 -0
- package/dist/collection/plugins/row-resize/index.js +6 -0
- package/dist/collection/plugins/row-resize/row-resize.plugin.js +416 -0
- package/dist/collection/plugins/row-resize/row-resize.types.js +1 -0
- package/dist/collection/plugins/row-resize/row-resize.utils.js +55 -0
- package/dist/collection/plugins/sorting/sorting.plugin.js +16 -13
- package/dist/collection/plugins/wcag/index.js +5 -4
- package/dist/collection/serve/controller.js +1 -1
- package/dist/collection/services/data.provider.js +8 -2
- package/dist/collection/services/dimension.provider.js +17 -1
- package/dist/collection/services/local.scroll.timer.js +3 -3
- package/dist/collection/services/selection.store.connector.js +4 -2
- package/dist/collection/store/dataSource/data.pending.plugin.js +21 -0
- package/dist/collection/store/dataSource/data.store.js +25 -3
- package/dist/collection/store/dataSource/trimmed.plugin.js +9 -6
- package/dist/collection/store/dimension/dimension.trim.plugin.js +1 -3
- package/dist/collection/types/events.js +4 -1
- package/dist/collection/utils/column.utils.js +1 -1
- package/dist/esm/{cell-renderer-11cf-lu3.js → cell-renderer-D9ze8OJw.js} +3 -3
- package/dist/esm/{column.service-Cfw3L0PN.js → column.service-pu_fdQ0S.js} +5 -4
- package/dist/{revo-grid/dimension.helpers-fl4HSSK9.js → esm/dimension.helpers-Cln9sALu.js} +52 -9
- package/dist/{revo-grid/edit.utils-4e9fsqOR.js → esm/edit.utils-3ZbhQCv_.js} +1 -1
- package/dist/esm/{header-cell-renderer-Cqtg1ETB.js → header-cell-renderer-YCiVIQ2E.js} +1 -1
- package/dist/esm/{index-D24ku9ej.js → index-BvMNbQyq.js} +1 -1
- package/dist/esm/index.js +14 -11
- package/dist/esm/loader.js +1 -1
- package/dist/esm/revo-grid.entry.js +113 -68
- package/dist/esm/revo-grid.js +1 -1
- package/dist/esm/revogr-attribution_7.entry.js +51 -19
- package/dist/esm/revogr-clipboard_3.entry.js +4 -4
- package/dist/esm/revogr-data_4.entry.js +21 -15
- package/dist/esm/revogr-filter-panel.entry.js +9 -9
- package/dist/esm/{column.drag.plugin-DDBKeTGI.js → row-resize.plugin-DBOgjLdE.js} +748 -87
- package/dist/{revo-grid/text-editor-DlMnLkRK.js → esm/text-editor-eHtrwvxH.js} +2 -2
- package/dist/{revo-grid/throttle-Cpk1LoGk.js → esm/throttle-3rhqdcLy.js} +3 -3
- package/dist/{revo-grid/viewport.store-BSXmsiZc.js → esm/viewport.store-DWMKRDSH.js} +1 -1
- package/dist/revo-grid/{cell-renderer-11cf-lu3.js → cell-renderer-D9ze8OJw.js} +3 -3
- package/dist/revo-grid/{column.service-Cfw3L0PN.js → column.service-pu_fdQ0S.js} +5 -4
- package/dist/{esm/dimension.helpers-fl4HSSK9.js → revo-grid/dimension.helpers-Cln9sALu.js} +52 -9
- package/dist/{esm/edit.utils-4e9fsqOR.js → revo-grid/edit.utils-3ZbhQCv_.js} +1 -1
- package/dist/revo-grid/{header-cell-renderer-Cqtg1ETB.js → header-cell-renderer-YCiVIQ2E.js} +1 -1
- package/dist/revo-grid/{index-D24ku9ej.js → index-BvMNbQyq.js} +1 -1
- package/dist/revo-grid/index.esm.js +14 -11
- package/dist/revo-grid/revo-grid.entry.js +113 -68
- package/dist/revo-grid/revo-grid.esm.js +1 -1
- package/dist/revo-grid/revogr-attribution_7.entry.js +51 -19
- package/dist/revo-grid/revogr-clipboard_3.entry.js +4 -4
- package/dist/revo-grid/revogr-data_4.entry.js +21 -15
- package/dist/revo-grid/revogr-filter-panel.entry.js +9 -9
- package/dist/revo-grid/{column.drag.plugin-DDBKeTGI.js → row-resize.plugin-DBOgjLdE.js} +748 -87
- package/dist/{esm/text-editor-DlMnLkRK.js → revo-grid/text-editor-eHtrwvxH.js} +2 -2
- package/dist/{esm/throttle-Cpk1LoGk.js → revo-grid/throttle-3rhqdcLy.js} +3 -3
- package/dist/{esm/viewport.store-BSXmsiZc.js → revo-grid/viewport.store-DWMKRDSH.js} +1 -1
- package/dist/types/components/data/revogr-data.d.ts +1 -0
- package/dist/types/components/overlay/keyboard.service.d.ts +6 -0
- package/dist/types/components/overlay/revogr-overlay-selection.d.ts +3 -1
- package/dist/types/components/revoGrid/revo-grid.d.ts +9 -1
- package/dist/types/components/revoGrid/viewport.scrolling.service.d.ts +3 -1
- package/dist/types/components.d.ts +23 -10
- package/dist/types/plugins/filter/filter.constants.d.ts +6 -0
- package/dist/types/plugins/filter/filter.plugin.d.ts +15 -0
- package/dist/types/plugins/groupingRow/grouping.const.d.ts +1 -0
- package/dist/types/plugins/groupingRow/grouping.row.plugin.d.ts +5 -7
- package/dist/types/plugins/groupingRow/grouping.sorting.service.d.ts +7 -0
- package/dist/types/plugins/groupingRow/grouping.trimmed.service.d.ts +9 -0
- package/dist/types/plugins/index.d.ts +1 -0
- package/dist/types/plugins/row-resize/index.d.ts +3 -0
- package/dist/types/plugins/row-resize/row-resize.plugin.d.ts +46 -0
- package/dist/types/plugins/row-resize/row-resize.types.d.ts +40 -0
- package/dist/types/plugins/row-resize/row-resize.utils.d.ts +14 -0
- package/dist/types/plugins/sorting/sorting.plugin.d.ts +5 -0
- package/dist/types/services/data.provider.d.ts +2 -0
- package/dist/types/services/dimension.provider.d.ts +7 -1
- package/dist/types/store/dataSource/data.pending.plugin.d.ts +9 -0
- package/dist/types/store/dataSource/data.store.d.ts +10 -0
- package/dist/types/store/dataSource/trimmed.plugin.d.ts +5 -0
- package/dist/types/types/events.d.ts +1 -1
- package/dist/types/types/interfaces.d.ts +3 -1
- package/hydrate/index.js +980 -191
- package/hydrate/index.mjs +980 -191
- package/package.json +1 -1
- package/readme.md +4 -1
- package/standalone/column.service.js +1 -1
- package/standalone/data.store.js +1 -1
- package/standalone/dimension.helpers.js +1 -1
- package/standalone/index.js +1 -1
- package/standalone/local.scroll.timer.js +1 -1
- package/standalone/revo-grid.js +1 -1
- package/standalone/revogr-data2.js +1 -1
- package/standalone/revogr-filter-panel.js +1 -1
- package/standalone/revogr-header2.js +1 -1
- package/standalone/revogr-overlay-selection2.js +1 -1
- 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 (
|
|
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.
|
|
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: '
|
|
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: '
|
|
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 =
|
|
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 (
|
|
85
|
+
if (!this.hasActiveFilters()) {
|
|
86
|
+
this.cancelFiltering();
|
|
84
87
|
return;
|
|
85
88
|
}
|
|
86
|
-
|
|
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
|
-
|
|
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
|
|
45
|
-
|
|
46
|
-
let
|
|
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,
|
|
38
|
+
const { trimmed, items: expandedItems } = doExpand(virtualIndex, source, store.get('items'));
|
|
50
39
|
newTrimmed = Object.assign(Object.assign({}, newTrimmed), trimmed);
|
|
51
|
-
if (
|
|
52
|
-
setItems(
|
|
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
|
-
|
|
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
|
|
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
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
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
|
-
|
|
120
|
-
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
17
|
-
const sourceIndex =
|
|
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 =
|
|
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';
|