@revolist/revogrid 4.24.1 → 4.24.3

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 (77) hide show
  1. package/dist/cjs/{cell-renderer-DfUCisis.js → cell-renderer-DnOCJ9ge.js} +58 -4
  2. package/dist/cjs/{column.drag.plugin-Cz-T4y3M.js → column.drag.plugin-0qtjk7uW.js} +38 -18
  3. package/dist/cjs/{column.service-BNWNiJW3.js → column.service-CD70rNL2.js} +8 -5
  4. package/dist/cjs/{dimension.helpers-B9HgANnM.js → dimension.helpers-CB5sNw5J.js} +2 -1
  5. package/dist/cjs/{edit.utils-pKeiYFLJ.js → edit.utils-DDxnq9lw.js} +1 -1
  6. package/dist/cjs/{header-cell-renderer-DyjOxArm.js → header-cell-renderer-JXYFwayd.js} +1 -1
  7. package/dist/cjs/{index-DxaSE5uZ.js → index-BF6JDcMr.js} +1 -1
  8. package/dist/cjs/index.cjs.js +10 -9
  9. package/dist/cjs/loader.cjs.js +1 -1
  10. package/dist/cjs/revo-grid.cjs.entry.js +12 -8
  11. package/dist/cjs/revo-grid.cjs.js +1 -1
  12. package/dist/cjs/revogr-attribution_7.cjs.entry.js +5 -5
  13. package/dist/cjs/revogr-clipboard_3.cjs.entry.js +4 -4
  14. package/dist/cjs/revogr-data_4.cjs.entry.js +6 -4
  15. package/dist/cjs/revogr-filter-panel.cjs.entry.js +16 -3
  16. package/dist/cjs/{text-editor-B4W-m-r-.js → text-editor-CvgloQdG.js} +2 -2
  17. package/dist/cjs/{viewport.store-BscUCiUk.js → viewport.store-Ci8H1bI9.js} +1 -1
  18. package/dist/collection/components/data/revogr-data.js +2 -0
  19. package/dist/collection/components/revoGrid/revo-grid.js +1 -1
  20. package/dist/collection/plugins/filter/filter.panel.js +36 -3
  21. package/dist/collection/plugins/filter/filter.plugin.js +21 -6
  22. package/dist/collection/plugins/groupingRow/grouping.row.plugin.js +12 -7
  23. package/dist/collection/plugins/groupingRow/grouping.row.renderer.js +59 -3
  24. package/dist/collection/plugins/groupingRow/grouping.service.js +7 -4
  25. package/dist/collection/services/data.provider.js +6 -2
  26. package/dist/collection/store/dataSource/data.store.js +2 -1
  27. package/dist/{revo-grid/cell-renderer-CLTRlCa5.js → esm/cell-renderer-BQjko1zB.js} +58 -5
  28. package/dist/esm/{column.drag.plugin-DKkf7Zqb.js → column.drag.plugin-K0lXn2G3.js} +38 -18
  29. package/dist/esm/{column.service-C6hByxPy.js → column.service-BnFqXqQG.js} +8 -5
  30. package/dist/{revo-grid/dimension.helpers-CGKwSvw6.js → esm/dimension.helpers-CXrsUc6f.js} +2 -1
  31. package/dist/esm/{edit.utils-Dnnbd0xG.js → edit.utils-CXmmCnxE.js} +1 -1
  32. package/dist/{revo-grid/header-cell-renderer-BMmXRsd_.js → esm/header-cell-renderer-B3mYpZD3.js} +1 -1
  33. package/dist/{revo-grid/index-Db3qZoW5.js → esm/index-DBqlJITb.js} +1 -1
  34. package/dist/esm/index.js +10 -10
  35. package/dist/esm/loader.js +1 -1
  36. package/dist/esm/revo-grid.entry.js +12 -8
  37. package/dist/esm/revo-grid.js +1 -1
  38. package/dist/esm/revogr-attribution_7.entry.js +5 -5
  39. package/dist/esm/revogr-clipboard_3.entry.js +4 -4
  40. package/dist/esm/revogr-data_4.entry.js +6 -4
  41. package/dist/esm/revogr-filter-panel.entry.js +16 -3
  42. package/dist/{revo-grid/text-editor-C3RUSwH5.js → esm/text-editor-DQtz2Y7B.js} +2 -2
  43. package/dist/{revo-grid/viewport.store-_c579YyM.js → esm/viewport.store-D5jEuhLq.js} +1 -1
  44. package/dist/{esm/cell-renderer-CLTRlCa5.js → revo-grid/cell-renderer-BQjko1zB.js} +58 -5
  45. package/dist/revo-grid/{column.drag.plugin-DKkf7Zqb.js → column.drag.plugin-K0lXn2G3.js} +38 -18
  46. package/dist/revo-grid/{column.service-C6hByxPy.js → column.service-BnFqXqQG.js} +8 -5
  47. package/dist/{esm/dimension.helpers-CGKwSvw6.js → revo-grid/dimension.helpers-CXrsUc6f.js} +2 -1
  48. package/dist/revo-grid/{edit.utils-Dnnbd0xG.js → edit.utils-CXmmCnxE.js} +1 -1
  49. package/dist/{esm/header-cell-renderer-BMmXRsd_.js → revo-grid/header-cell-renderer-B3mYpZD3.js} +1 -1
  50. package/dist/{esm/index-Db3qZoW5.js → revo-grid/index-DBqlJITb.js} +1 -1
  51. package/dist/revo-grid/index.esm.js +10 -10
  52. package/dist/revo-grid/revo-grid.entry.js +12 -8
  53. package/dist/revo-grid/revo-grid.esm.js +1 -1
  54. package/dist/revo-grid/revogr-attribution_7.entry.js +5 -5
  55. package/dist/revo-grid/revogr-clipboard_3.entry.js +4 -4
  56. package/dist/revo-grid/revogr-data_4.entry.js +6 -4
  57. package/dist/revo-grid/revogr-filter-panel.entry.js +16 -3
  58. package/dist/{esm/text-editor-C3RUSwH5.js → revo-grid/text-editor-DQtz2Y7B.js} +2 -2
  59. package/dist/{esm/viewport.store-_c579YyM.js → revo-grid/viewport.store-D5jEuhLq.js} +1 -1
  60. package/dist/types/components.d.ts +11 -0
  61. package/dist/types/plugins/filter/filter.panel.d.ts +4 -0
  62. package/dist/types/plugins/filter/filter.plugin.d.ts +1 -0
  63. package/dist/types/plugins/filter/filter.types.d.ts +5 -0
  64. package/dist/types/plugins/groupingRow/grouping.row.renderer.d.ts +6 -1
  65. package/dist/types/plugins/groupingRow/grouping.row.types.d.ts +47 -1
  66. package/dist/types/plugins/groupingRow/grouping.service.d.ts +1 -1
  67. package/dist/types/services/data.provider.d.ts +5 -2
  68. package/dist/types/store/dataSource/data.store.d.ts +3 -1
  69. package/hydrate/index.js +122 -25
  70. package/hydrate/index.mjs +122 -25
  71. package/package.json +1 -1
  72. package/standalone/column.service.js +1 -1
  73. package/standalone/data.store.js +1 -1
  74. package/standalone/index.js +1 -1
  75. package/standalone/revo-grid.js +1 -1
  76. package/standalone/revogr-data2.js +1 -1
  77. package/standalone/revogr-filter-panel.js +1 -1
@@ -1,5 +1,5 @@
1
1
  import type { VNode } from '../../stencil-public-runtime';
2
- import type { HyperFunc, ColumnProp, DimensionRows, DataType, Providers, VirtualPositionItem, PositionItem, DimensionCols } from "../../types/index";
2
+ import type { HyperFunc, ColumnProp, DimensionRows, DataType, Providers, VirtualPositionItem, PositionItem, DimensionCols, CellTemplateProp } from "../../types/index";
3
3
  import type { RowProps } from '../../components/data/row-renderer';
4
4
  import { GROUP_EXPAND_EVENT } from './grouping.const';
5
5
  /**
@@ -47,8 +47,38 @@ export interface GroupRowPros extends RowProps {
47
47
  hasExpand: boolean;
48
48
  providers: Providers;
49
49
  groupingCustomRenderer?: GroupLabelTemplateFunc | null;
50
+ groupingCellRenderer?: GroupCellTemplateFunc | null;
51
+ additionalData?: any;
50
52
  }
51
53
  export type GroupLabelTemplateFunc = (createElement: HyperFunc<VNode>, props: GroupTemplateProp & RowGroupingProps, ...args: any[]) => any;
54
+ export interface GroupCellTemplateProp extends Omit<CellTemplateProp, 'colType'> {
55
+ /**
56
+ * Column viewport type that owns the cell.
57
+ */
58
+ colType: DimensionCols | 'rowHeaders';
59
+ /**
60
+ * Current virtual column position. Only columns rendered by the viewport are
61
+ * passed to the group cell template.
62
+ */
63
+ columnItem: VirtualPositionItem;
64
+ /**
65
+ * Current virtual row position.
66
+ */
67
+ rowItem: VirtualPositionItem;
68
+ /**
69
+ * Semantic information about the synthetic group row.
70
+ */
71
+ group: {
72
+ name: string;
73
+ depth: number;
74
+ expanded: boolean;
75
+ prop: ColumnProp;
76
+ isLabelColumn: boolean;
77
+ canExpand: boolean;
78
+ onExpand(event: MouseEvent): void;
79
+ };
80
+ }
81
+ export type GroupCellTemplateFunc = (createElement: HyperFunc<VNode>, props: GroupCellTemplateProp, additionalData?: any) => any;
52
82
  export type GroupingOptions = {
53
83
  /**
54
84
  * Column props to which grouping will be applied
@@ -63,6 +93,12 @@ export type GroupingOptions = {
63
93
  * Custom group label template
64
94
  */
65
95
  groupLabelTemplate?: GroupLabelTemplateFunc;
96
+ /**
97
+ * Custom template for cells in synthetic group rows.
98
+ * When provided, group rows render only the columns in the current horizontal
99
+ * viewport and this template takes precedence over `groupLabelTemplate`.
100
+ */
101
+ groupCellTemplate?: GroupCellTemplateFunc;
66
102
  } & ExpandedOptions;
67
103
  export type BeforeSourceSetEvent = {
68
104
  type: DimensionRows;
@@ -85,10 +121,20 @@ export type ExpandedOptions = {
85
121
  * Custom group label value parser
86
122
  */
87
123
  getGroupValue?(item: DataType, prop: string | number): any;
124
+ /**
125
+ * Replacement group value for `null` and `undefined` keys.
126
+ * Used by the default group value resolver.
127
+ * @default ''
128
+ */
129
+ emptyGroupValue?: any;
88
130
  /**
89
131
  * Custom group label template
90
132
  */
91
133
  groupLabelTemplate?: GroupLabelTemplateFunc;
134
+ /**
135
+ * Custom template for virtualized cells in synthetic group rows.
136
+ */
137
+ groupCellTemplate?: GroupCellTemplateFunc;
92
138
  };
93
139
  declare global {
94
140
  /**
@@ -14,7 +14,7 @@ export declare function getExpanded(model?: DataType): any;
14
14
  * @param columnProps - ids of groups
15
15
  * @param expanded - potentially expanded items if present
16
16
  */
17
- export declare function gatherGrouping(array: DataType[], columnProps: ColumnProp[], { prevExpanded, expandedAll, getGroupValue, }: ExpandedOptions): {
17
+ export declare function gatherGrouping(array: DataType[], columnProps: ColumnProp[], { prevExpanded, expandedAll, getGroupValue, emptyGroupValue, }: ExpandedOptions): {
18
18
  sourceWithGroups: DataType[];
19
19
  depth: number;
20
20
  trimmed: Record<number, boolean>;
@@ -1,6 +1,6 @@
1
1
  import { DataStore, Groups, Trimmed } from "../store/index";
2
2
  import DimensionProvider from './dimension.provider';
3
- import type { GroupLabelTemplateFunc } from '../plugins/groupingRow/grouping.row.types';
3
+ import type { GroupCellTemplateFunc, GroupLabelTemplateFunc } from '../plugins/groupingRow/grouping.row.types';
4
4
  import type { DataLookup, DimensionRows, DataType, BeforeSaveDataDetails } from "../types/index";
5
5
  export type RowDataSources = {
6
6
  [T in DimensionRows]: DataStore<DataType, DimensionRows>;
@@ -32,6 +32,7 @@ export declare class DataProvider {
32
32
  depth: number;
33
33
  groups?: Groups;
34
34
  customRenderer?: GroupLabelTemplateFunc;
35
+ cellRenderer?: GroupCellTemplateFunc;
35
36
  }, silent?: boolean, preserveTrimmed?: boolean): DataType[];
36
37
  getModel(virtualIndex: number, type?: DimensionRows): DataType;
37
38
  changeOrder({ rowType, from, to }: {
@@ -43,8 +44,10 @@ export declare class DataProvider {
43
44
  setRangeData(data: DataLookup, type: DimensionRows): void;
44
45
  refresh(type?: DimensionRows | 'all'): void;
45
46
  refreshItems(type?: DimensionRows): void;
46
- setGrouping({ depth }: {
47
+ setGrouping({ depth, customRenderer, cellRenderer, }: {
47
48
  depth: number;
49
+ customRenderer?: GroupLabelTemplateFunc;
50
+ cellRenderer?: GroupCellTemplateFunc;
48
51
  }, type?: DimensionRows): void;
49
52
  setTrimmed(trimmed: Trimmed, type?: DimensionRows): void;
50
53
  }
@@ -1,6 +1,6 @@
1
1
  import { Trimmed } from './trimmed.plugin';
2
2
  import { Observable } from '../../utils';
3
- import type { GroupLabelTemplateFunc } from '../../plugins/groupingRow/grouping.row.types';
3
+ import type { GroupCellTemplateFunc, GroupLabelTemplateFunc } from '../../plugins/groupingRow/grouping.row.types';
4
4
  import type { DimensionRows, DimensionCols, ColumnProperties, ColumnGrouping, ColumnRegular, DataType, DataSourceState, ColumnProp } from "../../types/index";
5
5
  export interface Group extends ColumnProperties {
6
6
  name: string;
@@ -12,6 +12,7 @@ export type GDataType = DataType | ColumnRegular;
12
12
  export type GDimension = DimensionRows | DimensionCols;
13
13
  export type DSourceState<T1 extends GDataType, T2 extends GDimension> = DataSourceState<T1, T2> & {
14
14
  groupingCustomRenderer?: GroupLabelTemplateFunc | null;
15
+ groupingCellRenderer?: GroupCellTemplateFunc | null;
15
16
  };
16
17
  /**
17
18
  * Data store
@@ -32,6 +33,7 @@ export declare class DataStore<T extends GDataType, ST extends GDimension> {
32
33
  depth: number;
33
34
  groups?: Groups;
34
35
  customRenderer?: GroupLabelTemplateFunc;
36
+ cellRenderer?: GroupCellTemplateFunc;
35
37
  }, silent?: boolean, preserveTrimmed?: boolean): void;
36
38
  addTrimmed(some: Partial<Trimmed>): void;
37
39
  setSourceData(items: Record<number, any>, mutate?: boolean): void;
package/hydrate/index.js CHANGED
@@ -7495,6 +7495,10 @@ class FilterPanel {
7495
7495
  * If true, closes the filter panel when clicking outside
7496
7496
  */
7497
7497
  this.closeOnOutsideClick = true;
7498
+ /**
7499
+ * Whether the filter panel allows the same operator more than once per column.
7500
+ */
7501
+ this.allowDuplicateOperators = true;
7498
7502
  this.debouncedApplyFilter = debounce$1(() => {
7499
7503
  this.filterChange.emit(this.filterItems);
7500
7504
  }, 400);
@@ -7808,11 +7812,15 @@ class FilterPanel {
7808
7812
  }
7809
7813
  }
7810
7814
  renderSelectOptions(type, isDefaultTypeRemoved = false) {
7815
+ var _a;
7811
7816
  if (!this.changes) {
7812
7817
  return;
7813
7818
  }
7814
7819
  const options = [];
7815
7820
  const prop = this.changes.prop;
7821
+ if (prop === undefined) {
7822
+ return;
7823
+ }
7816
7824
  const hidden = new Set();
7817
7825
  Object.keys(this.filterItems).forEach((prop) => {
7818
7826
  const values = this.filterItems[prop];
@@ -7822,6 +7830,9 @@ class FilterPanel {
7822
7830
  }
7823
7831
  });
7824
7832
  });
7833
+ const selectedTypes = new Set(((_a = this.filterItems[prop]) !== null && _a !== void 0 ? _a : [])
7834
+ .filter(filter => !filter.hidden)
7835
+ .map(filter => filter.type));
7825
7836
  if (!isDefaultTypeRemoved) {
7826
7837
  const capts = Object.assign(Object.assign({}, this.filterCaptionsInternal), this.filterCaptions);
7827
7838
  options.push(hAsync("option", { selected: this.currentFilterType === defaultType, value: defaultType }, prop && this.filterItems[prop] && this.filterItems[prop].length > 0
@@ -7829,7 +7840,9 @@ class FilterPanel {
7829
7840
  : this.filterNames[defaultType]));
7830
7841
  }
7831
7842
  for (let gIndex in this.changes.filterTypes) {
7832
- const group = this.changes.filterTypes[gIndex].filter(k => !hidden.has(k));
7843
+ const group = this.changes.filterTypes[gIndex].filter(k => !hidden.has(k) && (this.allowDuplicateOperators ||
7844
+ !selectedTypes.has(k) ||
7845
+ (isDefaultTypeRemoved && type === k)));
7833
7846
  if (group.length) {
7834
7847
  options.push(...group.map(k => (hAsync("option", { value: k, selected: type === k }, this.filterNames[k]))));
7835
7848
  options.push(hAsync("option", { disabled: true }));
@@ -7924,7 +7937,7 @@ class FilterPanel {
7924
7937
  top: `${(_d = (_c = this.changes) === null || _c === void 0 ? void 0 : _c.y) !== null && _d !== void 0 ? _d : 0}px`,
7925
7938
  };
7926
7939
  const capts = Object.assign(Object.assign({}, this.filterCaptionsInternal), this.filterCaptions);
7927
- return (hAsync(Host, { key: '2a19b35adb56fb7d23385fffebc768838edee162' }, hAsync("dialog", { key: '94386d7cbc4bd9c631f72928938b1d1550a3de82', class: "filter-panel-dialog", style: style, ref: el => (this.dialog = el), onCancel: e => {
7940
+ return (hAsync(Host, { key: '8859c452eb08838f65f18efecbdde7f65fda2b49' }, hAsync("dialog", { key: 'f603067ff0986a9f344cbbf816388d2bbac198bb', class: "filter-panel-dialog", style: style, ref: el => (this.dialog = el), onCancel: e => {
7928
7941
  e.preventDefault();
7929
7942
  this.onCancel();
7930
7943
  } }, this.changes && [
@@ -7933,7 +7946,7 @@ class FilterPanel {
7933
7946
  ((_g = this.changes) === null || _g === void 0 ? void 0 : _g.hideDefaultFilters) !== true && [
7934
7947
  hAsync("label", { key: "filter-title" }, capts.title),
7935
7948
  hAsync("div", { key: "filter-holder", class: "filter-holder" }, this.getFilterItemsList()),
7936
- hAsync("div", { key: "add-filter", class: "add-filter" }, hAsync("select", { key: '4f7354e39d8e5cf9ae7b735290eff18d105ab87e', id: FILTER_ID, class: "select-css", onChange: e => this.onAddNewFilter(e) }, this.renderSelectOptions(this.currentFilterType))),
7949
+ hAsync("div", { key: "add-filter", class: "add-filter" }, hAsync("select", { key: '2ec0a66918edf91bdde3962b6ec84c89f6f1c8f1', id: FILTER_ID, class: "select-css", onChange: e => this.onAddNewFilter(e) }, this.renderSelectOptions(this.currentFilterType))),
7937
7950
  ],
7938
7951
  hAsync("slot", { key: "default-slot" }),
7939
7952
  ((_j = (_h = this.changes).extraBottomContent) === null || _j === void 0 ? void 0 : _j.call(_h, this.changes)) || '',
@@ -7958,6 +7971,7 @@ class FilterPanel {
7958
7971
  "filterCaptions": [16],
7959
7972
  "disableDynamicFiltering": [4, "disable-dynamic-filtering"],
7960
7973
  "closeOnOutsideClick": [4, "close-on-outside-click"],
7974
+ "allowDuplicateOperators": [4, "allow-duplicate-operators"],
7961
7975
  "isFilterIdSet": [32],
7962
7976
  "filterId": [32],
7963
7977
  "currentFilterId": [32],
@@ -11556,7 +11570,7 @@ class DataStore {
11556
11570
  return this.dataStore;
11557
11571
  }
11558
11572
  constructor(type, storeData) {
11559
- const store = (this.dataStore = createStore(Object.assign({ items: [], proxyItems: [], source: [], groupingDepth: 0, groups: {}, type, trimmed: {}, groupingCustomRenderer: undefined }, storeData)));
11573
+ const store = (this.dataStore = createStore(Object.assign({ items: [], proxyItems: [], source: [], groupingDepth: 0, groups: {}, type, trimmed: {}, groupingCustomRenderer: undefined, groupingCellRenderer: undefined }, storeData)));
11560
11574
  store.use(proxyPlugin(store));
11561
11575
  store.use(trimmedPlugin$1(store));
11562
11576
  }
@@ -11596,6 +11610,7 @@ class DataStore {
11596
11610
  // if groups are not provided, we will consider that there is only one group with all items
11597
11611
  groups: grouping.groups,
11598
11612
  groupingCustomRenderer: grouping.customRenderer,
11613
+ groupingCellRenderer: grouping.cellRenderer,
11599
11614
  });
11600
11615
  }
11601
11616
  }
@@ -12864,8 +12879,9 @@ const GROUP_EXPAND_BTN = `group-expand`;
12864
12879
  const GROUP_EXPAND_EVENT = `groupexpandclick`;
12865
12880
  const GROUPING_ROW_TYPE = 'rgRow';
12866
12881
 
12867
- function getGroupValueDefault(item, prop) {
12868
- return item[prop] || null;
12882
+ function getGroupValueDefault(item, prop, emptyGroupValue) {
12883
+ var _a;
12884
+ return (_a = item[prop]) !== null && _a !== void 0 ? _a : emptyGroupValue;
12869
12885
  }
12870
12886
  function isDataRow(item) {
12871
12887
  return item != null;
@@ -12971,13 +12987,15 @@ function flattenGroupMaps({ groupedValues, parentIds, isExpanded, itemIndex, exp
12971
12987
  * @param columnProps - ids of groups
12972
12988
  * @param expanded - potentially expanded items if present
12973
12989
  */
12974
- function gatherGrouping(array, columnProps, { prevExpanded = {}, expandedAll = false, getGroupValue = getGroupValueDefault, }) {
12990
+ function gatherGrouping(array, columnProps, { prevExpanded = {}, expandedAll = false, getGroupValue, emptyGroupValue = '', }) {
12975
12991
  const groupedItems = new Map();
12976
12992
  array.forEach((item, originalIndex) => {
12977
12993
  if (!isDataRow(item)) {
12978
12994
  return;
12979
12995
  }
12980
- const groupLevelValues = columnProps.map(groupId => getGroupValue(item, groupId));
12996
+ const groupLevelValues = columnProps.map(groupId => getGroupValue
12997
+ ? getGroupValue(item, groupId)
12998
+ : getGroupValueDefault(item, groupId, emptyGroupValue));
12981
12999
  const lastLevelValue = groupLevelValues.pop();
12982
13000
  let currentGroupLevel = groupedItems;
12983
13001
  groupLevelValues.forEach(value => {
@@ -15006,8 +15024,12 @@ class DataProvider {
15006
15024
  const items = this.stores[type].store.get('items');
15007
15025
  this.stores[type].setData({ items: [...items] });
15008
15026
  }
15009
- setGrouping({ depth }, type = 'rgRow') {
15010
- this.stores[type].setData({ groupingDepth: depth });
15027
+ setGrouping({ depth, customRenderer, cellRenderer, }, type = 'rgRow') {
15028
+ this.stores[type].setData({
15029
+ groupingDepth: depth,
15030
+ groupingCustomRenderer: customRenderer,
15031
+ groupingCellRenderer: cellRenderer,
15032
+ });
15011
15033
  }
15012
15034
  setTrimmed(trimmed, type = 'rgRow') {
15013
15035
  const store = this.stores[type];
@@ -15861,13 +15883,14 @@ class FilterPlugin extends BasePlugin {
15861
15883
  this.filterNameIndexByType = Object.assign({}, filterNames);
15862
15884
  this.filterFunctionsIndexedByType = Object.assign({}, filterCoreFunctionsIndexedByType);
15863
15885
  this.filterProp = FILTER_PROP;
15886
+ this.allowDuplicateOperators = true;
15864
15887
  if (config) {
15865
15888
  this.initConfig(config);
15866
15889
  }
15867
15890
  const existingNodes = this.revogrid.registerVNode.filter(n => typeof n === 'object' && n.$tag$ !== FILTE_PANEL);
15868
15891
  this.revogrid.registerVNode = [
15869
15892
  ...existingNodes,
15870
- hAsync("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, ref: e => (this.pop = e) }, ' ', this.extraContent()),
15893
+ hAsync("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()),
15871
15894
  ];
15872
15895
  const aftersourceset = async () => {
15873
15896
  const filterCollectionProps = Object.keys(this.filterCollection);
@@ -15894,15 +15917,24 @@ class FilterPlugin extends BasePlugin {
15894
15917
  };
15895
15918
  this.addEventListener('headerclick', e => this.headerclick(e));
15896
15919
  this.addEventListener(FILTER_CONFIG_CHANGED_EVENT, ({ detail }) => {
15897
- if (!detail ||
15898
- (typeof detail === 'object' &&
15899
- (!detail.multiFilterItems ||
15900
- !Object.keys(detail.multiFilterItems).length))) {
15920
+ if (!detail) {
15901
15921
  this.clearFiltering();
15902
15922
  return;
15903
15923
  }
15904
15924
  if (typeof detail === 'object') {
15905
- this.initConfig(detail);
15925
+ const detailKeys = Object.keys(detail);
15926
+ const preserveCurrentFilters = !detailKeys.includes('multiFilterItems') &&
15927
+ detailKeys.includes('allowDuplicateOperators');
15928
+ this.initConfig(preserveCurrentFilters
15929
+ ? Object.assign(Object.assign({}, detail), { multiFilterItems: this.multiFilterItems }) : detail);
15930
+ if (!detail.multiFilterItems || !Object.keys(detail.multiFilterItems).length) {
15931
+ if (preserveCurrentFilters) {
15932
+ aftersourceset();
15933
+ return;
15934
+ }
15935
+ this.clearFiltering();
15936
+ return;
15937
+ }
15906
15938
  }
15907
15939
  aftersourceset();
15908
15940
  });
@@ -15916,6 +15948,11 @@ class FilterPlugin extends BasePlugin {
15916
15948
  return null;
15917
15949
  }
15918
15950
  initConfig(config) {
15951
+ var _a;
15952
+ this.allowDuplicateOperators = (_a = config.allowDuplicateOperators) !== null && _a !== void 0 ? _a : true;
15953
+ if (this.pop) {
15954
+ this.pop.allowDuplicateOperators = this.allowDuplicateOperators;
15955
+ }
15919
15956
  if (config.multiFilterItems) {
15920
15957
  this.multiFilterItems = Object.assign({}, config.multiFilterItems);
15921
15958
  }
@@ -17310,8 +17347,58 @@ function expandEvent(e, model, virtualIndex) {
17310
17347
  });
17311
17348
  (_a = e.target) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
17312
17349
  }
17350
+ function renderGroupCells(props, { name, expanded, depth, }) {
17351
+ const { additionalData, columnItems, groupingCellRenderer, hasExpand, itemIndex, model, providers, size, start, end, } = props;
17352
+ if (!groupingCellRenderer) {
17353
+ return [];
17354
+ }
17355
+ const renderOffset = providers.viewport.get('renderOffset') || 0;
17356
+ const data = providers.data.get('source');
17357
+ const rowItem = { itemIndex, size, start, end };
17358
+ const onExpand = (event) => expandEvent(event, model, itemIndex);
17359
+ return columnItems.map(columnItem => {
17360
+ const column = getSourceItem(providers.columns, columnItem.itemIndex);
17361
+ if (!column) {
17362
+ return null;
17363
+ }
17364
+ const isLabelColumn = isGroupingColumn(column);
17365
+ const templateProps = {
17366
+ prop: column.prop,
17367
+ model,
17368
+ data,
17369
+ column,
17370
+ rowIndex: itemIndex,
17371
+ colIndex: columnItem.itemIndex,
17372
+ colType: providers.colType,
17373
+ type: providers.type,
17374
+ value: getCellRaw(model, column),
17375
+ providers,
17376
+ columnItem,
17377
+ rowItem,
17378
+ group: {
17379
+ name,
17380
+ depth,
17381
+ expanded,
17382
+ prop: model[GROUP_COLUMN_PROP],
17383
+ isLabelColumn,
17384
+ canExpand: hasExpand,
17385
+ onExpand,
17386
+ },
17387
+ };
17388
+ return (hAsync("div", { key: columnItem.itemIndex, class: {
17389
+ [CELL_CLASS]: true,
17390
+ groupingCell: true,
17391
+ groupingLabelCell: isLabelColumn,
17392
+ }, [DATA_COL]: columnItem.itemIndex,
17393
+ [DATA_ROW]: itemIndex, style: {
17394
+ width: `${columnItem.size}px`,
17395
+ transform: `translateX(${columnItem.start - renderOffset}px)`,
17396
+ height: size ? `${size}px` : undefined,
17397
+ } }, groupingCellRenderer(hAsync, templateProps, additionalData)));
17398
+ });
17399
+ }
17313
17400
  const GroupingRowRenderer = (props) => {
17314
- const { model, itemIndex, hasExpand, groupingCustomRenderer } = props;
17401
+ const { model, itemIndex, hasExpand, groupingCustomRenderer, groupingCellRenderer, } = props;
17315
17402
  const name = model[PSEUDO_GROUP_ITEM];
17316
17403
  const expanded = model[GROUP_EXPANDED];
17317
17404
  const depth = parseInt(model[GROUP_DEPTH], 10) || 0;
@@ -17320,6 +17407,9 @@ const GroupingRowRenderer = (props) => {
17320
17407
  depth,
17321
17408
  expanded,
17322
17409
  };
17410
+ if (groupingCellRenderer) {
17411
+ return (hAsync(RowRenderer, Object.assign({ index: props.index, size: props.size, start: props.start }, groupRowAttrs), renderGroupCells(props, { name, expanded, depth })));
17412
+ }
17323
17413
  if (groupingCustomRenderer) {
17324
17414
  return (hAsync(RowRenderer, Object.assign({}, props, groupRowAttrs), hAsync("div", { onClick: e => expandEvent(e, model, itemIndex) }, groupingCustomRenderer(hAsync, Object.assign(Object.assign({}, props), { colType: props.providers.colType, name,
17325
17415
  expanded,
@@ -17327,7 +17417,7 @@ const GroupingRowRenderer = (props) => {
17327
17417
  }
17328
17418
  return (hAsync(RowRenderer, Object.assign({}, props, groupRowAttrs), hasExpand && [
17329
17419
  hAsync("button", { class: { [GROUP_EXPAND_BTN]: true }, onClick: e => expandEvent(e, model, itemIndex) }, expandSvgIconVNode(expanded)),
17330
- name,
17420
+ String(name),
17331
17421
  ]));
17332
17422
  };
17333
17423
  const expandSvgIconVNode = (expanded = false) => {
@@ -17446,7 +17536,7 @@ class GroupingRowPlugin extends BasePlugin {
17446
17536
  * Initiated when need to reapply grouping
17447
17537
  */
17448
17538
  doSourceUpdate(options) {
17449
- var _a;
17539
+ var _a, _b;
17450
17540
  /**
17451
17541
  * Get source without grouping
17452
17542
  * @param newOldIndexMap - provides us mapping with new indexes vs old indexes, we would use it for trimmed mapping
@@ -17458,10 +17548,11 @@ class GroupingRowPlugin extends BasePlugin {
17458
17548
  * Group again
17459
17549
  * @param oldNewIndexMap - provides us mapping with new indexes vs old indexes
17460
17550
  */
17461
- const { sourceWithGroups, depth, trimmed, oldNewIndexMap, } = gatherGrouping(source, ((_a = this.options) === null || _a === void 0 ? void 0 : _a.props) || [], expanded);
17551
+ const { sourceWithGroups, depth, trimmed, oldNewIndexMap, } = gatherGrouping(source, (_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.props) !== null && _b !== void 0 ? _b : [], expanded);
17462
17552
  const customRenderer = options === null || options === void 0 ? void 0 : options.groupLabelTemplate;
17553
+ const cellRenderer = options === null || options === void 0 ? void 0 : options.groupCellTemplate;
17463
17554
  // setup source
17464
- this.providers.data.setData(sourceWithGroups, GROUPING_ROW_TYPE, this.revogrid.disableVirtualY, { depth, customRenderer }, true);
17555
+ this.providers.data.setData(sourceWithGroups, GROUPING_ROW_TYPE, this.revogrid.disableVirtualY, { depth, customRenderer, cellRenderer }, true);
17465
17556
  this.updateTrimmed(trimmed, oldNewIndexes !== null && oldNewIndexes !== void 0 ? oldNewIndexes : {}, oldNewIndexMap, sourceWithGroups);
17466
17557
  }
17467
17558
  /**
@@ -17470,17 +17561,21 @@ class GroupingRowPlugin extends BasePlugin {
17470
17561
  * If source came from other plugin
17471
17562
  */
17472
17563
  onDataSet(data) {
17473
- var _a, _b;
17564
+ var _a, _b, _c;
17474
17565
  let preservedExpanded = {};
17475
17566
  if (((_a = this.options) === null || _a === void 0 ? void 0 : _a.preserveGroupingOnUpdate) !== false) {
17476
17567
  let { prevExpanded } = getSource(this.getStore().get('source'), this.getStore().get('proxyItems'), true);
17477
17568
  preservedExpanded = prevExpanded;
17478
17569
  }
17479
17570
  const source = data.source.filter(s => !isGrouping(s));
17480
- const options = Object.assign(Object.assign({}, (this.revogrid.grouping || {})), { prevExpanded: preservedExpanded });
17481
- const { sourceWithGroups, depth, trimmed, oldNewIndexMap, } = gatherGrouping(source, ((_b = this.options) === null || _b === void 0 ? void 0 : _b.props) || [], options);
17571
+ const options = Object.assign(Object.assign({}, this.options), { prevExpanded: preservedExpanded });
17572
+ const { sourceWithGroups, depth, trimmed, oldNewIndexMap, } = gatherGrouping(source, (_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.props) !== null && _c !== void 0 ? _c : [], options);
17482
17573
  data.source = sourceWithGroups;
17483
- this.providers.data.setGrouping({ depth });
17574
+ this.providers.data.setGrouping({
17575
+ depth,
17576
+ customRenderer: options.groupLabelTemplate,
17577
+ cellRenderer: options.groupCellTemplate,
17578
+ });
17484
17579
  this.updateTrimmed(trimmed, oldNewIndexMap, undefined, sourceWithGroups);
17485
17580
  }
17486
17581
  /**
@@ -20784,6 +20879,7 @@ class RevogrData {
20784
20879
  const rowsEls = [];
20785
20880
  const depth = this.dataStore.get('groupingDepth');
20786
20881
  const groupingCustomRenderer = this.dataStore.get('groupingCustomRenderer');
20882
+ const groupingCellRenderer = this.dataStore.get('groupingCellRenderer');
20787
20883
  const groupDepth = this.columnService.hasGrouping ? depth : 0;
20788
20884
  const rowRenderOffset = this.viewportRow.get('renderOffset') || 0;
20789
20885
  const colRenderOffset = this.viewportCol.get('renderOffset') || 0;
@@ -20792,6 +20888,7 @@ class RevogrData {
20792
20888
  // #region Grouping
20793
20889
  if (isGrouping(dataItem)) {
20794
20890
  const gmodel = Object.assign(Object.assign({}, rgRow), { start: rgRow.start - rowRenderOffset, index: rgRow.itemIndex, model: dataItem, groupingCustomRenderer,
20891
+ groupingCellRenderer, additionalData: this.additionalData,
20795
20892
  // Only show expand button if grouping is enabled and not in row headers
20796
20893
  hasExpand: this.columnService.hasGrouping && this.colType !== 'rowHeaders', columnItems: cols, providers: this.providers });
20797
20894
  rowsEls.push(hAsync(GroupingRowRenderer, Object.assign({}, gmodel)));