@revolist/revogrid 4.27.0 → 4.27.2
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-C7rdgaov.js → cell-renderer-BDIx0xys.js} +1 -1
- package/dist/cjs/{column.service-Bbml5C2j.js → column.service-D-ENzqyb.js} +2 -0
- package/dist/cjs/{filter.button-F2Bw3UAd.js → filter.button-C6ixuMmr.js} +3 -2
- package/dist/cjs/{header-cell-renderer-BljFI6wj.js → header-cell-renderer-B5Y4fdZC.js} +1 -1
- package/dist/cjs/index.cjs.js +7 -5
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/revo-grid.cjs.entry.js +63 -43
- package/dist/cjs/revo-grid.cjs.js +1 -1
- package/dist/cjs/revogr-attribution_7.cjs.entry.js +1 -1
- package/dist/cjs/revogr-data_4.cjs.entry.js +12 -11
- package/dist/cjs/revogr-filter-panel.cjs.entry.js +139 -33
- package/dist/cjs/{row-resize.plugin-BRQy_qNn.js → row-resize.plugin-C4YOF1lN.js} +353 -185
- package/dist/collection/components/header/header-renderer.js +7 -6
- package/dist/collection/components/header/revogr-header-style.css +8 -3
- package/dist/collection/components/revoGrid/revo-grid-style.css +12 -2
- package/dist/collection/components/revoGrid/revo-grid.js +37 -21
- package/dist/collection/plugins/filter/filter.button.js +3 -2
- package/dist/collection/plugins/filter/filter.indexed.js +5 -0
- package/dist/collection/plugins/filter/filter.panel.js +138 -31
- package/dist/collection/plugins/filter/filter.plugin.js +48 -5
- package/dist/collection/plugins/filter/filter.style.css +25 -3
- package/dist/collection/plugins/groupingRow/grouping.const.js +1 -0
- package/dist/collection/plugins/groupingRow/grouping.row.plugin.js +84 -54
- 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/row-resize/row-resize.plugin.js +144 -113
- package/dist/collection/plugins/sorting/sorting.plugin.js +16 -13
- package/dist/collection/plugins/wcag/index.js +5 -4
- package/dist/collection/services/dimension.provider.js +17 -1
- package/dist/esm/{cell-renderer-BFpmdV8H.js → cell-renderer-D9ze8OJw.js} +1 -1
- package/dist/esm/{column.service-CM-wgGs8.js → column.service-pu_fdQ0S.js} +2 -1
- package/dist/esm/{filter.button-DMhpuAiw.js → filter.button-CEPUxLUo.js} +3 -2
- package/dist/{revo-grid/header-cell-renderer-Bqh1PrgH.js → esm/header-cell-renderer-YCiVIQ2E.js} +1 -1
- package/dist/esm/index.js +6 -6
- package/dist/esm/loader.js +1 -1
- package/dist/esm/revo-grid.entry.js +63 -43
- package/dist/esm/revo-grid.js +1 -1
- package/dist/esm/revogr-attribution_7.entry.js +1 -1
- package/dist/esm/revogr-data_4.entry.js +12 -11
- package/dist/esm/revogr-filter-panel.entry.js +139 -33
- package/dist/esm/{row-resize.plugin-BRiaHlHA.js → row-resize.plugin-Beu0pMds.js} +354 -187
- package/dist/revo-grid/{cell-renderer-BFpmdV8H.js → cell-renderer-D9ze8OJw.js} +1 -1
- package/dist/revo-grid/{column.service-CM-wgGs8.js → column.service-pu_fdQ0S.js} +2 -1
- package/dist/revo-grid/{filter.button-DMhpuAiw.js → filter.button-CEPUxLUo.js} +3 -2
- package/dist/{esm/header-cell-renderer-Bqh1PrgH.js → revo-grid/header-cell-renderer-YCiVIQ2E.js} +1 -1
- package/dist/revo-grid/index.esm.js +6 -6
- package/dist/revo-grid/revo-grid.entry.js +63 -43
- package/dist/revo-grid/revo-grid.esm.js +1 -1
- package/dist/revo-grid/revogr-attribution_7.entry.js +1 -1
- package/dist/revo-grid/revogr-data_4.entry.js +12 -11
- package/dist/revo-grid/revogr-filter-panel.entry.js +139 -33
- package/dist/revo-grid/{row-resize.plugin-BRiaHlHA.js → row-resize.plugin-Beu0pMds.js} +354 -187
- package/dist/types/components/revoGrid/revo-grid.d.ts +2 -0
- package/dist/types/plugins/filter/filter.indexed.d.ts +2 -0
- package/dist/types/plugins/filter/filter.panel.d.ts +9 -2
- package/dist/types/plugins/filter/filter.plugin.d.ts +8 -1
- package/dist/types/plugins/filter/filter.types.d.ts +8 -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/row-resize/row-resize.plugin.d.ts +14 -12
- package/dist/types/plugins/sorting/sorting.plugin.d.ts +5 -0
- package/dist/types/services/dimension.provider.d.ts +7 -1
- package/dist/types/types/interfaces.d.ts +13 -1
- package/hydrate/index.js +561 -264
- package/hydrate/index.mjs +561 -264
- package/package.json +1 -1
- package/standalone/column.service.js +1 -1
- package/standalone/filter.button.js +1 -1
- package/standalone/index.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
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { h } from "@stencil/core";
|
|
6
6
|
import { BasePlugin } from "../base.plugin";
|
|
7
7
|
import { FILTER_PROP, isFilterBtn } from "./filter.button";
|
|
8
|
-
import { filterCoreFunctionsIndexedByType, filterNames, filterTypes, } from "./filter.indexed";
|
|
8
|
+
import { filterCoreFunctionsIndexedByType, filterNames, filterTypeDefaults, filterTypes, } from "./filter.indexed";
|
|
9
9
|
import { resolveBlankSemantics } from "./filter.blank";
|
|
10
10
|
import { timeout } from "../../utils";
|
|
11
11
|
import { ASYNC_FILTER_ROW_THRESHOLD, FILTER_CHUNK_SIZE, FILTER_TIME_BUDGET_MS, } from "./filter.constants";
|
|
@@ -30,6 +30,8 @@ export const FILTE_PANEL = 'revogr-filter-panel';
|
|
|
30
30
|
*
|
|
31
31
|
* @property {FilterLocalization|undefined} localization - translation for filter popup captions.
|
|
32
32
|
*
|
|
33
|
+
* @property {boolean|undefined} defaultFilter - creates a draft condition when an empty filter panel opens. Defaults to true.
|
|
34
|
+
*
|
|
33
35
|
* @property {boolean|undefined} disableDynamicFiltering - disables dynamic filtering. A way to apply filters on Save only.
|
|
34
36
|
*/
|
|
35
37
|
/**
|
|
@@ -51,7 +53,7 @@ export class FilterPlugin extends BasePlugin {
|
|
|
51
53
|
* number: ['eqN', 'neqN', 'gt']
|
|
52
54
|
* }
|
|
53
55
|
*/
|
|
54
|
-
this.filterByType = Object.
|
|
56
|
+
this.filterByType = Object.fromEntries(Object.entries(filterTypes).map(([type, filters]) => [type, [...filters]]));
|
|
55
57
|
this.filterNameIndexByType = Object.assign({}, filterNames);
|
|
56
58
|
this.filterFunctionsIndexedByType = Object.assign({}, filterCoreFunctionsIndexedByType);
|
|
57
59
|
this.filterProp = FILTER_PROP;
|
|
@@ -135,11 +137,16 @@ export class FilterPlugin extends BasePlugin {
|
|
|
135
137
|
return null;
|
|
136
138
|
}
|
|
137
139
|
initConfig(config) {
|
|
138
|
-
var _a;
|
|
140
|
+
var _a, _b, _c, _d;
|
|
139
141
|
this.config = config;
|
|
140
142
|
this.allowDuplicateOperators = (_a = config.allowDuplicateOperators) !== null && _a !== void 0 ? _a : true;
|
|
141
143
|
if (this.pop) {
|
|
142
144
|
this.pop.allowDuplicateOperators = this.allowDuplicateOperators;
|
|
145
|
+
this.pop.disableDynamicFiltering =
|
|
146
|
+
(_b = config.disableDynamicFiltering) !== null && _b !== void 0 ? _b : false;
|
|
147
|
+
this.pop.closeOnOutsideClick =
|
|
148
|
+
(_c = config.closeFilterPanelOnOutsideClick) !== null && _c !== void 0 ? _c : true;
|
|
149
|
+
this.pop.filterCaptions = (_d = config.localization) === null || _d === void 0 ? void 0 : _d.captions;
|
|
143
150
|
}
|
|
144
151
|
if (config.multiFilterItems) {
|
|
145
152
|
this.multiFilterItems = Object.assign({}, config.multiFilterItems);
|
|
@@ -228,11 +235,12 @@ export class FilterPlugin extends BasePlugin {
|
|
|
228
235
|
}
|
|
229
236
|
// filter button clicked, open filter dialog
|
|
230
237
|
const buttonPos = (filterButton instanceof HTMLElement ? filterButton : el).getBoundingClientRect();
|
|
231
|
-
const data = Object.assign(Object.assign(Object.assign({}, e.detail), this.filterCollection[prop]), { x: buttonPos.x, y: buttonPos.y + buttonPos.height, anchorY: buttonPos.y, autoCorrect: true, filterTypes: this.getColumnFilter(e.detail.filter), filterItems: this.multiFilterItems, extraContent: this.extraHyperContent, extraBottomContent: this.extraBottomHyperContent });
|
|
238
|
+
const data = Object.assign(Object.assign(Object.assign({}, e.detail), this.filterCollection[prop]), { x: buttonPos.x, y: buttonPos.y + buttonPos.height, anchorY: buttonPos.y, autoCorrect: true, filterTypes: this.getColumnFilter(e.detail.filter), defaultFilterType: this.getDefaultFilter(e.detail.filter), showDefaultFilter: this.shouldShowDefaultFilter(e.detail.filter), filterItems: this.multiFilterItems, extraContent: this.extraHyperContent, extraBottomContent: this.extraBottomHyperContent });
|
|
232
239
|
(_b = this.beforeshow) === null || _b === void 0 ? void 0 : _b.call(this, data);
|
|
233
240
|
this.pop.show(data);
|
|
234
241
|
}
|
|
235
|
-
getColumnFilter(
|
|
242
|
+
getColumnFilter(config) {
|
|
243
|
+
const type = this.isColumnFilterOption(config) ? config.type : config;
|
|
236
244
|
let filterType = 'string';
|
|
237
245
|
if (!type) {
|
|
238
246
|
return { [filterType]: this.filterByType[filterType] };
|
|
@@ -252,6 +260,41 @@ export class FilterPlugin extends BasePlugin {
|
|
|
252
260
|
}
|
|
253
261
|
return { [filterType]: this.filterByType[filterType] };
|
|
254
262
|
}
|
|
263
|
+
/** Resolve the preferred operator against the column's available filters. */
|
|
264
|
+
getDefaultFilter(config) {
|
|
265
|
+
var _a;
|
|
266
|
+
const filters = this.getColumnFilter(config);
|
|
267
|
+
const availableFilters = Object.values(filters).flat();
|
|
268
|
+
const columnDefault = this.isColumnFilterOption(config)
|
|
269
|
+
? config.default
|
|
270
|
+
: undefined;
|
|
271
|
+
if (typeof columnDefault === 'string' &&
|
|
272
|
+
availableFilters.includes(columnDefault)) {
|
|
273
|
+
return columnDefault;
|
|
274
|
+
}
|
|
275
|
+
const firstFamily = Object.keys(filters)[0];
|
|
276
|
+
const familyDefault = filterTypeDefaults[firstFamily];
|
|
277
|
+
if (familyDefault && ((_a = filters[firstFamily]) === null || _a === void 0 ? void 0 : _a.includes(familyDefault))) {
|
|
278
|
+
return familyDefault;
|
|
279
|
+
}
|
|
280
|
+
return availableFilters[0];
|
|
281
|
+
}
|
|
282
|
+
/** Resolve grid and column-level draft opt-outs. */
|
|
283
|
+
shouldShowDefaultFilter(config) {
|
|
284
|
+
var _a;
|
|
285
|
+
if (this.isColumnFilterOption(config)) {
|
|
286
|
+
if (config.default === false) {
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
if (typeof config.default === 'string') {
|
|
290
|
+
return true;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return ((_a = this.config) === null || _a === void 0 ? void 0 : _a.defaultFilter) !== false;
|
|
294
|
+
}
|
|
295
|
+
isColumnFilterOption(value) {
|
|
296
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
297
|
+
}
|
|
255
298
|
isValidType(type) {
|
|
256
299
|
return !!(typeof type === 'string' && this.filterByType[type]);
|
|
257
300
|
}
|
|
@@ -112,15 +112,36 @@ revogr-filter-panel .filter-panel-dialog .filter-actions button {
|
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
.rgHeaderCell:hover .rv-filter {
|
|
115
|
-
transition: opacity 267ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, transform 178ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
|
|
115
|
+
transition: opacity 267ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, width 267ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, transform 178ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
|
|
116
116
|
}
|
|
117
|
-
.rgHeaderCell:hover .rv-filter,
|
|
117
|
+
.rgHeaderCell:hover:has(.rv-filter) .header-content, .rgHeaderCell:focus-within:has(.rv-filter) .header-content, .rgHeaderCell:has(.rv-filter.active) .header-content {
|
|
118
|
+
margin-right: 24px;
|
|
119
|
+
}
|
|
120
|
+
.rgHeaderCell:hover:has(.rv-filter):has(.desc) .header-content, .rgHeaderCell:hover:has(.rv-filter):has(.asc) .header-content, .rgHeaderCell:focus-within:has(.rv-filter):has(.desc) .header-content, .rgHeaderCell:focus-within:has(.rv-filter):has(.asc) .header-content, .rgHeaderCell:has(.rv-filter.active):has(.desc) .header-content, .rgHeaderCell:has(.rv-filter.active):has(.asc) .header-content {
|
|
121
|
+
margin-right: 8px;
|
|
122
|
+
padding-right: 24px;
|
|
123
|
+
}
|
|
124
|
+
.rgHeaderCell:hover .rv-filter, .rgHeaderCell:focus-within .rv-filter,
|
|
118
125
|
.rgHeaderCell .rv-filter.active {
|
|
119
126
|
opacity: 1;
|
|
127
|
+
width: 24px;
|
|
128
|
+
}
|
|
129
|
+
@media (hover: none), (pointer: coarse) {
|
|
130
|
+
.rgHeaderCell:has(.rv-filter) .header-content {
|
|
131
|
+
margin-right: 24px;
|
|
132
|
+
}
|
|
133
|
+
.rgHeaderCell:has(.rv-filter):has(.desc) .header-content, .rgHeaderCell:has(.rv-filter):has(.asc) .header-content {
|
|
134
|
+
margin-right: 8px;
|
|
135
|
+
padding-right: 24px;
|
|
136
|
+
}
|
|
137
|
+
.rgHeaderCell .rv-filter {
|
|
138
|
+
opacity: 1;
|
|
139
|
+
width: 24px;
|
|
140
|
+
}
|
|
120
141
|
}
|
|
121
142
|
.rgHeaderCell .rv-filter {
|
|
122
143
|
height: 24px;
|
|
123
|
-
width:
|
|
144
|
+
width: 0;
|
|
124
145
|
background: none;
|
|
125
146
|
border: 0;
|
|
126
147
|
opacity: 0;
|
|
@@ -129,6 +150,7 @@ revogr-filter-panel .filter-panel-dialog .filter-actions button {
|
|
|
129
150
|
border-radius: 4px;
|
|
130
151
|
position: relative;
|
|
131
152
|
z-index: 1;
|
|
153
|
+
padding: 0;
|
|
132
154
|
}
|
|
133
155
|
.rgHeaderCell .rv-filter.active {
|
|
134
156
|
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,6 +162,7 @@ export class GroupingRowPlugin extends BasePlugin {
|
|
|
166
162
|
customRenderer: options.groupLabelTemplate,
|
|
167
163
|
cellRenderer: options.groupCellTemplate,
|
|
168
164
|
});
|
|
165
|
+
queueMicrotask(() => this.remapRowDefinitions(oldNewIndexes !== null && oldNewIndexes !== void 0 ? oldNewIndexes : {}, oldNewIndexMap, currentSource, sourceWithGroups));
|
|
169
166
|
this.updateTrimmed(trimmed, oldNewIndexMap, undefined, sourceWithGroups, { filterTrimmedMode: 'recompute-after-source-set' });
|
|
170
167
|
}
|
|
171
168
|
/**
|
|
@@ -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,9 +244,57 @@ 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
299
|
updateTrimmed(trimmedGroup = {}, firstLevelMap = {}, secondLevelMap, source = this.getStore().get('source'), { filterTrimmedMode = 'remap', } = {}) {
|
|
270
300
|
// map previously trimmed data
|
|
@@ -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;
|