@revolist/revogrid 4.24.2 → 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.
@@ -108,6 +108,10 @@ const FilterPanel = class {
108
108
  * If true, closes the filter panel when clicking outside
109
109
  */
110
110
  this.closeOnOutsideClick = true;
111
+ /**
112
+ * Whether the filter panel allows the same operator more than once per column.
113
+ */
114
+ this.allowDuplicateOperators = true;
111
115
  this.debouncedApplyFilter = debounce(() => {
112
116
  this.filterChange.emit(this.filterItems);
113
117
  }, 400);
@@ -421,11 +425,15 @@ const FilterPanel = class {
421
425
  }
422
426
  }
423
427
  renderSelectOptions(type, isDefaultTypeRemoved = false) {
428
+ var _a;
424
429
  if (!this.changes) {
425
430
  return;
426
431
  }
427
432
  const options = [];
428
433
  const prop = this.changes.prop;
434
+ if (prop === undefined) {
435
+ return;
436
+ }
429
437
  const hidden = new Set();
430
438
  Object.keys(this.filterItems).forEach((prop) => {
431
439
  const values = this.filterItems[prop];
@@ -435,6 +443,9 @@ const FilterPanel = class {
435
443
  }
436
444
  });
437
445
  });
446
+ const selectedTypes = new Set(((_a = this.filterItems[prop]) !== null && _a !== void 0 ? _a : [])
447
+ .filter(filter => !filter.hidden)
448
+ .map(filter => filter.type));
438
449
  if (!isDefaultTypeRemoved) {
439
450
  const capts = Object.assign(Object.assign({}, this.filterCaptionsInternal), this.filterCaptions);
440
451
  options.push(h("option", { selected: this.currentFilterType === defaultType, value: defaultType }, prop && this.filterItems[prop] && this.filterItems[prop].length > 0
@@ -442,7 +453,9 @@ const FilterPanel = class {
442
453
  : this.filterNames[defaultType]));
443
454
  }
444
455
  for (let gIndex in this.changes.filterTypes) {
445
- const group = this.changes.filterTypes[gIndex].filter(k => !hidden.has(k));
456
+ const group = this.changes.filterTypes[gIndex].filter(k => !hidden.has(k) && (this.allowDuplicateOperators ||
457
+ !selectedTypes.has(k) ||
458
+ (isDefaultTypeRemoved && type === k)));
446
459
  if (group.length) {
447
460
  options.push(...group.map(k => (h("option", { value: k, selected: type === k }, this.filterNames[k]))));
448
461
  options.push(h("option", { disabled: true }));
@@ -537,7 +550,7 @@ const FilterPanel = class {
537
550
  top: `${(_d = (_c = this.changes) === null || _c === void 0 ? void 0 : _c.y) !== null && _d !== void 0 ? _d : 0}px`,
538
551
  };
539
552
  const capts = Object.assign(Object.assign({}, this.filterCaptionsInternal), this.filterCaptions);
540
- return (h(Host, { key: '2a19b35adb56fb7d23385fffebc768838edee162' }, h("dialog", { key: '94386d7cbc4bd9c631f72928938b1d1550a3de82', class: "filter-panel-dialog", style: style, ref: el => (this.dialog = el), onCancel: e => {
553
+ return (h(Host, { key: '8859c452eb08838f65f18efecbdde7f65fda2b49' }, h("dialog", { key: 'f603067ff0986a9f344cbbf816388d2bbac198bb', class: "filter-panel-dialog", style: style, ref: el => (this.dialog = el), onCancel: e => {
541
554
  e.preventDefault();
542
555
  this.onCancel();
543
556
  } }, this.changes && [
@@ -546,7 +559,7 @@ const FilterPanel = class {
546
559
  ((_g = this.changes) === null || _g === void 0 ? void 0 : _g.hideDefaultFilters) !== true && [
547
560
  h("label", { key: "filter-title" }, capts.title),
548
561
  h("div", { key: "filter-holder", class: "filter-holder" }, this.getFilterItemsList()),
549
- h("div", { key: "add-filter", class: "add-filter" }, h("select", { key: '4f7354e39d8e5cf9ae7b735290eff18d105ab87e', id: FILTER_ID, class: "select-css", onChange: e => this.onAddNewFilter(e) }, this.renderSelectOptions(this.currentFilterType))),
562
+ h("div", { key: "add-filter", class: "add-filter" }, h("select", { key: '2ec0a66918edf91bdde3962b6ec84c89f6f1c8f1', id: FILTER_ID, class: "select-css", onChange: e => this.onAddNewFilter(e) }, this.renderSelectOptions(this.currentFilterType))),
550
563
  ],
551
564
  h("slot", { key: "default-slot" }),
552
565
  ((_j = (_h = this.changes).extraBottomContent) === null || _j === void 0 ? void 0 : _j.call(_h, this.changes)) || '',
@@ -1274,13 +1274,14 @@ class FilterPlugin extends BasePlugin {
1274
1274
  this.filterNameIndexByType = Object.assign({}, filterNames);
1275
1275
  this.filterFunctionsIndexedByType = Object.assign({}, filterCoreFunctionsIndexedByType);
1276
1276
  this.filterProp = FILTER_PROP;
1277
+ this.allowDuplicateOperators = true;
1277
1278
  if (config) {
1278
1279
  this.initConfig(config);
1279
1280
  }
1280
1281
  const existingNodes = this.revogrid.registerVNode.filter(n => typeof n === 'object' && n.$tag$ !== FILTE_PANEL);
1281
1282
  this.revogrid.registerVNode = [
1282
1283
  ...existingNodes,
1283
- 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, ref: e => (this.pop = e) }, ' ', this.extraContent()),
1284
+ 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()),
1284
1285
  ];
1285
1286
  const aftersourceset = async () => {
1286
1287
  const filterCollectionProps = Object.keys(this.filterCollection);
@@ -1307,15 +1308,24 @@ class FilterPlugin extends BasePlugin {
1307
1308
  };
1308
1309
  this.addEventListener('headerclick', e => this.headerclick(e));
1309
1310
  this.addEventListener(FILTER_CONFIG_CHANGED_EVENT, ({ detail }) => {
1310
- if (!detail ||
1311
- (typeof detail === 'object' &&
1312
- (!detail.multiFilterItems ||
1313
- !Object.keys(detail.multiFilterItems).length))) {
1311
+ if (!detail) {
1314
1312
  this.clearFiltering();
1315
1313
  return;
1316
1314
  }
1317
1315
  if (typeof detail === 'object') {
1318
- this.initConfig(detail);
1316
+ const detailKeys = Object.keys(detail);
1317
+ const preserveCurrentFilters = !detailKeys.includes('multiFilterItems') &&
1318
+ detailKeys.includes('allowDuplicateOperators');
1319
+ this.initConfig(preserveCurrentFilters
1320
+ ? Object.assign(Object.assign({}, detail), { multiFilterItems: this.multiFilterItems }) : detail);
1321
+ if (!detail.multiFilterItems || !Object.keys(detail.multiFilterItems).length) {
1322
+ if (preserveCurrentFilters) {
1323
+ aftersourceset();
1324
+ return;
1325
+ }
1326
+ this.clearFiltering();
1327
+ return;
1328
+ }
1319
1329
  }
1320
1330
  aftersourceset();
1321
1331
  });
@@ -1329,6 +1339,11 @@ class FilterPlugin extends BasePlugin {
1329
1339
  return null;
1330
1340
  }
1331
1341
  initConfig(config) {
1342
+ var _a;
1343
+ this.allowDuplicateOperators = (_a = config.allowDuplicateOperators) !== null && _a !== void 0 ? _a : true;
1344
+ if (this.pop) {
1345
+ this.pop.allowDuplicateOperators = this.allowDuplicateOperators;
1346
+ }
1332
1347
  if (config.multiFilterItems) {
1333
1348
  this.multiFilterItems = Object.assign({}, config.multiFilterItems);
1334
1349
  }
@@ -2,8 +2,8 @@
2
2
  * Built by Revolist OU ❤️
3
3
  */
4
4
  export { o as GROUPING_ROW_TYPE, j as GROUP_COLUMN_PROP, G as GROUP_DEPTH, h as GROUP_EXPANDED, l as GROUP_EXPAND_BTN, m as GROUP_EXPAND_EVENT, k as GROUP_ORIGINAL_INDEX, f as PSEUDO_GROUP_COLUMN, P as PSEUDO_GROUP_ITEM, d as PSEUDO_GROUP_ITEM_ID, e as PSEUDO_GROUP_ITEM_VALUE, c as columnTypes, a as cropCellToMax, H as gatherGroup, s as gatherGrouping, z as getCellData, B as getCellDataParsed, A as getCellRaw, I as getColumnByProp, D as getColumnSizes, C as getColumnType, F as getColumns, q as getExpanded, t as getGroupingName, x as getParsedGroup, g as getRange, p as getSource, E as isColGrouping, u as isGrouping, v as isGroupingColumn, b as isRangeSingleCell, i as isRowType, y as isSameGroup, w as measureEqualDepth, n as nextCell, r as rowTypes } from './column.service-BnFqXqQG.js';
5
- import { B as BasePlugin } from './column.drag.plugin-Cf9DYdQj.js';
6
- export { A as AutoSizeColumnPlugin, n as BEFORE_COLUMN_DRAG_END_EVENT, m as COLUMN_DRAG_END_EVENT, l as COLUMN_DRAG_MOVE_EVENT, o as COLUMN_DRAG_START_EVENT, C as ColumnAutoSizeMode, p as ColumnMovePlugin, D as DimensionStore, b as ExportCsv, E as ExportFilePlugin, c as FILTER_CONFIG_CHANGED_EVENT, F as FILTER_TRIMMED_TYPE, d as FILTE_PANEL, e as FilterPlugin, G as GroupingRowPlugin, S as SelectionStore, s as SortingPlugin, a as StretchColumn, w as defaultCellCompare, x as descCellCompare, j as doCollapse, k as doExpand, f as filterCoreFunctionsIndexedByType, h as filterNames, g as filterTypes, r as getColumnDragPosition, z as getComparer, q as getLeftRelative, y as getNextOrder, u as getSortingIndex, t as hasActiveSorting, i as isStretchPlugin, v as sortIndexByItems } from './column.drag.plugin-Cf9DYdQj.js';
5
+ import { B as BasePlugin } from './column.drag.plugin-K0lXn2G3.js';
6
+ export { A as AutoSizeColumnPlugin, n as BEFORE_COLUMN_DRAG_END_EVENT, m as COLUMN_DRAG_END_EVENT, l as COLUMN_DRAG_MOVE_EVENT, o as COLUMN_DRAG_START_EVENT, C as ColumnAutoSizeMode, p as ColumnMovePlugin, D as DimensionStore, b as ExportCsv, E as ExportFilePlugin, c as FILTER_CONFIG_CHANGED_EVENT, F as FILTER_TRIMMED_TYPE, d as FILTE_PANEL, e as FilterPlugin, G as GroupingRowPlugin, S as SelectionStore, s as SortingPlugin, a as StretchColumn, w as defaultCellCompare, x as descCellCompare, j as doCollapse, k as doExpand, f as filterCoreFunctionsIndexedByType, h as filterNames, g as filterTypes, r as getColumnDragPosition, z as getComparer, q as getLeftRelative, y as getNextOrder, u as getSortingIndex, t as hasActiveSorting, i as isStretchPlugin, v as sortIndexByItems } from './column.drag.plugin-K0lXn2G3.js';
7
7
  export { d as dispatch, a as dispatchByEvent } from './header-cell-renderer-B3mYpZD3.js';
8
8
  export { C as CellRenderer, G as GroupingRowRenderer, S as SortingSign, e as expandEvent, a as expandSvgIconVNode, r as renderGroupCells } from './cell-renderer-BQjko1zB.js';
9
9
  export { a as applyMixins, f as findPositionInArray, g as getScrollbarSize, m as mergeSortedArray, p as pushSorted, r as range, s as scaleValue, t as timeout } from './index-DBqlJITb.js';
@@ -6,7 +6,7 @@ import { c as columnTypes, J as reduce, C as getColumnType, r as rowTypes, i as
6
6
  import { D as DataStore, b as getSourceItem, f as getSourceItemVirtualIndexByProp, d as setSourceByPhysicalIndex, s as setSourceByVirtualIndex, a as getVisibleSourceItem, h as gatherTrimmedItems, k as getItemByIndex, R as RESIZE_INTERVAL } from './dimension.helpers-CXrsUc6f.js';
7
7
  import { d as debounce } from './debounce-PCRWZliA.js';
8
8
  import { g as getScrollDimension, v as viewportDataPartition, F as FOOTER_SLOT, C as CONTENT_SLOT, H as HEADER_SLOT, D as DATA_SLOT } from './viewport.helpers-CoCAvmZs.js';
9
- import { D as DimensionStore, S as SelectionStore, B as BasePlugin, G as GroupingRowPlugin, a as StretchColumn, i as isStretchPlugin, A as AutoSizeColumnPlugin, e as FilterPlugin, E as ExportFilePlugin, s as SortingPlugin, p as ColumnMovePlugin } from './column.drag.plugin-Cf9DYdQj.js';
9
+ import { D as DimensionStore, S as SelectionStore, B as BasePlugin, G as GroupingRowPlugin, a as StretchColumn, i as isStretchPlugin, A as AutoSizeColumnPlugin, e as FilterPlugin, E as ExportFilePlugin, s as SortingPlugin, p as ColumnMovePlugin } from './column.drag.plugin-K0lXn2G3.js';
10
10
  import { V as ViewportStore } from './viewport.store-D5jEuhLq.js';
11
11
  import { T as ThemeService } from './theme.service-BmnDvr6P.js';
12
12
  import { t as timeout } from './index-DBqlJITb.js';
@@ -48,5 +48,5 @@ var patchCloneNodeFix = (HTMLElementPrototype) => {
48
48
 
49
49
  patchBrowser().then(async (options) => {
50
50
  await globalScripts();
51
- return bootstrapLazy([["revo-grid",[[260,"revo-grid",{"rowHeaders":[4,"row-headers"],"frameSize":[2,"frame-size"],"rowSize":[2,"row-size"],"colSize":[2,"col-size"],"range":[4],"readonly":[4],"resize":[4],"noHorizontalScrollTransfer":[4,"no-horizontal-scroll-transfer"],"canFocus":[4,"can-focus"],"useClipboard":[4,"use-clipboard"],"columns":[16],"source":[16],"pinnedTopSource":[16],"pinnedBottomSource":[16],"rowDefinitions":[16],"editors":[16],"applyOnClose":[4,"apply-on-close"],"plugins":[16],"columnTypes":[16],"theme":[1537],"rowClass":[513,"row-class"],"autoSizeColumn":[4,"auto-size-column"],"filter":[4],"sorting":[16],"focusTemplate":[16],"canMoveColumns":[4,"can-move-columns"],"trimmedRows":[16],"exporting":[4],"grouping":[16],"stretch":[8],"additionalData":[16],"disableVirtualX":[4,"disable-virtual-x"],"virtualX":[16],"disableVirtualY":[4,"disable-virtual-y"],"hideAttribution":[4,"hide-attribution"],"jobsBeforeRender":[16],"registerVNode":[16],"accessible":[4],"rtl":[4],"canDrag":[4,"can-drag"],"refresh":[64],"setDataAt":[64],"scrollToRow":[64],"scrollToColumnIndex":[64],"scrollToColumnProp":[64],"updateColumns":[64],"addTrimmed":[64],"scrollToCoordinate":[64],"setCellEdit":[64],"setCellsFocus":[64],"getSource":[64],"getVisibleSource":[64],"getSourceStore":[64],"getColumnStore":[64],"updateColumnSorting":[64],"clearSorting":[64],"getColumns":[64],"clearFocus":[64],"getPlugins":[64],"getFocused":[64],"getContentSize":[64],"getSelectedRange":[64],"refreshExtraElements":[64],"getProviders":[64]},[[5,"touchstart","mousedownHandle"],[5,"mousedown","mousedownHandle"],[5,"touchend","mouseupHandle"],[5,"mouseup","mouseupHandle"],[0,"rowdragstartinit","onRowDragStarted"],[0,"rowdragendinit","onRowDragEnd"],[0,"roworderchange","onRowOrderChange"],[0,"rowdragmoveinit","onRowDrag"],[0,"rowdragmousemove","onRowMouseMove"],[0,"celleditapply","onCellEdit"],[0,"rangeeditapply","onRangeEdit"],[0,"selectionchangeinit","onRangeChanged"],[0,"rowdropinit","onRowDropped"],[0,"beforeheaderclick","onHeaderClick"],[0,"beforecellfocusinit","onCellFocus"]],{"columnTypes":[{"columnTypesChanged":0}],"columns":[{"columnChanged":0}],"disableVirtualX":[{"disableVirtualXChanged":0}],"virtualX":[{"virtualXChanged":0}],"rowSize":[{"rowSizeChanged":0}],"theme":[{"themeChanged":0}],"source":[{"dataSourceChanged":0}],"pinnedBottomSource":[{"dataSourceChanged":0}],"pinnedTopSource":[{"dataSourceChanged":0}],"disableVirtualY":[{"disableVirtualYChanged":0}],"rowDefinitions":[{"rowDefChanged":0}],"trimmedRows":[{"trimmedRowsChanged":0}],"grouping":[{"groupingChanged":0}],"stretch":[{"applyStretch":0}],"filter":[{"applyFilter":0}],"sorting":[{"applySorting":0}],"rowHeaders":[{"rowHeadersChange":0}],"registerVNode":[{"registerOutsideVNodes":0}],"additionalData":[{"additionalDataChanged":0}],"rtl":[{"rtlChanged":0}],"plugins":[{"pluginsChanged":0}]}]]],["revogr-filter-panel",[[260,"revogr-filter-panel",{"filterNames":[16],"filterEntities":[16],"filterCaptions":[16],"disableDynamicFiltering":[4,"disable-dynamic-filtering"],"closeOnOutsideClick":[4,"close-on-outside-click"],"isFilterIdSet":[32],"filterId":[32],"currentFilterId":[32],"currentFilterType":[32],"changes":[32],"filterItems":[32],"draggedFilterId":[32],"dragOverFilterId":[32],"show":[64],"getChanges":[64]},[[5,"mousedown","onMouseDown"]]]]],["revogr-clipboard_3",[[0,"revogr-clipboard",{"readonly":[4],"doCopy":[64]},[[4,"paste","onPaste"],[4,"copy","copyStarted"],[4,"cut","cutStarted"]]],[0,"revogr-edit",{"editCell":[16],"column":[16],"editor":[16],"saveOnClose":[4,"save-on-close"],"additionalData":[8,"additional-data"],"cancelChanges":[64],"beforeDisconnect":[64]}],[0,"revogr-order-editor",{"parent":[16],"dimensionRow":[16],"dimensionCol":[16],"dataStore":[16],"rowType":[1,"row-type"],"dragStart":[64],"endOrder":[64],"clearOrder":[64]}]]],["revogr-data_4",[[260,"revogr-data",{"readonly":[4],"range":[4],"rowClass":[1,"row-class"],"additionalData":[8,"additional-data"],"rowSelectionStore":[16],"viewportRow":[16],"viewportCol":[16],"dimensionRow":[16],"colData":[16],"dataStore":[16],"type":[513],"colType":[513,"col-type"],"jobsBeforeRender":[16],"providers":[32],"updateCell":[64]},null,{"dataStore":[{"onDataStoreChange":0}],"colData":[{"onColDataChange":0}]}],[0,"revogr-header",{"viewportCol":[16],"dimensionCol":[16],"selectionStore":[16],"groups":[16],"groupingDepth":[2,"grouping-depth"],"readonly":[4],"canResize":[4,"can-resize"],"resizeHandler":[16],"colData":[16],"columnFilter":[4,"column-filter"],"type":[1],"additionalData":[8,"additional-data"]}],[260,"revogr-viewport-scroll",{"rowHeader":[4,"row-header"],"contentWidth":[2,"content-width"],"contentHeight":[2,"content-height"],"colType":[1,"col-type"],"noHorizontalScrollTransfer":[4,"no-horizontal-scroll-transfer"],"setScroll":[64],"changeScroll":[64],"applyScroll":[64]},[[0,"mousewheel-vertical","mousewheelVertical"],[0,"mousewheel-horizontal","mousewheelHorizontal"],[0,"scroll-coordinate","scrollApply"]]],[0,"vnode-html",{"redraw":[16]}]]],["revogr-attribution_7",[[0,"revogr-row-headers",{"height":[2],"dataPorts":[16],"headerProp":[16],"rowClass":[1,"row-class"],"resize":[4],"rowHeaderColumn":[16],"additionalData":[8,"additional-data"],"jobsBeforeRender":[16]}],[260,"revogr-overlay-selection",{"readonly":[4],"range":[4],"canDrag":[4,"can-drag"],"useClipboard":[4,"use-clipboard"],"selectionStore":[16],"dimensionRow":[16],"dimensionCol":[16],"dataStore":[16],"colData":[16],"lastCell":[16],"editors":[16],"applyChangesOnClose":[4,"apply-changes-on-close"],"additionalData":[8,"additional-data"],"isMobileDevice":[4,"is-mobile-device"]},[[5,"touchmove","onMouseMove"],[5,"mousemove","onMouseMove"],[5,"touchend","onMouseUp"],[5,"mouseup","onMouseUp"],[5,"mouseleave","onMouseUp"],[0,"dragstartcell","onCellDrag"],[4,"keyup","onKeyUp"],[4,"keydown","onKeyDown"]],{"selectionStore":[{"selectionServiceSet":0}],"dimensionRow":[{"createAutoFillService":0}],"dimensionCol":[{"createAutoFillService":0}],"dataStore":[{"columnServiceSet":0}],"colData":[{"columnServiceSet":0}]}],[0,"revogr-attribution"],[260,"revogr-focus",{"colType":[1,"col-type"],"rowType":[1,"row-type"],"selectionStore":[16],"dimensionRow":[16],"dimensionCol":[16],"dataStore":[16],"colData":[16],"focusTemplate":[16]}],[0,"revogr-scroll-virtual",{"dimension":[1],"realSize":[2,"real-size"],"virtualSize":[2,"virtual-size"],"clientSize":[2,"client-size"],"setScroll":[64],"changeScroll":[64]}],[0,"revogr-temp-range",{"selectionStore":[16],"dimensionRow":[16],"dimensionCol":[16]}],[0,"revogr-extra",{"nodes":[16],"update":[32],"refresh":[64]}]]]], options);
51
+ return bootstrapLazy([["revo-grid",[[260,"revo-grid",{"rowHeaders":[4,"row-headers"],"frameSize":[2,"frame-size"],"rowSize":[2,"row-size"],"colSize":[2,"col-size"],"range":[4],"readonly":[4],"resize":[4],"noHorizontalScrollTransfer":[4,"no-horizontal-scroll-transfer"],"canFocus":[4,"can-focus"],"useClipboard":[4,"use-clipboard"],"columns":[16],"source":[16],"pinnedTopSource":[16],"pinnedBottomSource":[16],"rowDefinitions":[16],"editors":[16],"applyOnClose":[4,"apply-on-close"],"plugins":[16],"columnTypes":[16],"theme":[1537],"rowClass":[513,"row-class"],"autoSizeColumn":[4,"auto-size-column"],"filter":[4],"sorting":[16],"focusTemplate":[16],"canMoveColumns":[4,"can-move-columns"],"trimmedRows":[16],"exporting":[4],"grouping":[16],"stretch":[8],"additionalData":[16],"disableVirtualX":[4,"disable-virtual-x"],"virtualX":[16],"disableVirtualY":[4,"disable-virtual-y"],"hideAttribution":[4,"hide-attribution"],"jobsBeforeRender":[16],"registerVNode":[16],"accessible":[4],"rtl":[4],"canDrag":[4,"can-drag"],"refresh":[64],"setDataAt":[64],"scrollToRow":[64],"scrollToColumnIndex":[64],"scrollToColumnProp":[64],"updateColumns":[64],"addTrimmed":[64],"scrollToCoordinate":[64],"setCellEdit":[64],"setCellsFocus":[64],"getSource":[64],"getVisibleSource":[64],"getSourceStore":[64],"getColumnStore":[64],"updateColumnSorting":[64],"clearSorting":[64],"getColumns":[64],"clearFocus":[64],"getPlugins":[64],"getFocused":[64],"getContentSize":[64],"getSelectedRange":[64],"refreshExtraElements":[64],"getProviders":[64]},[[5,"touchstart","mousedownHandle"],[5,"mousedown","mousedownHandle"],[5,"touchend","mouseupHandle"],[5,"mouseup","mouseupHandle"],[0,"rowdragstartinit","onRowDragStarted"],[0,"rowdragendinit","onRowDragEnd"],[0,"roworderchange","onRowOrderChange"],[0,"rowdragmoveinit","onRowDrag"],[0,"rowdragmousemove","onRowMouseMove"],[0,"celleditapply","onCellEdit"],[0,"rangeeditapply","onRangeEdit"],[0,"selectionchangeinit","onRangeChanged"],[0,"rowdropinit","onRowDropped"],[0,"beforeheaderclick","onHeaderClick"],[0,"beforecellfocusinit","onCellFocus"]],{"columnTypes":[{"columnTypesChanged":0}],"columns":[{"columnChanged":0}],"disableVirtualX":[{"disableVirtualXChanged":0}],"virtualX":[{"virtualXChanged":0}],"rowSize":[{"rowSizeChanged":0}],"theme":[{"themeChanged":0}],"source":[{"dataSourceChanged":0}],"pinnedBottomSource":[{"dataSourceChanged":0}],"pinnedTopSource":[{"dataSourceChanged":0}],"disableVirtualY":[{"disableVirtualYChanged":0}],"rowDefinitions":[{"rowDefChanged":0}],"trimmedRows":[{"trimmedRowsChanged":0}],"grouping":[{"groupingChanged":0}],"stretch":[{"applyStretch":0}],"filter":[{"applyFilter":0}],"sorting":[{"applySorting":0}],"rowHeaders":[{"rowHeadersChange":0}],"registerVNode":[{"registerOutsideVNodes":0}],"additionalData":[{"additionalDataChanged":0}],"rtl":[{"rtlChanged":0}],"plugins":[{"pluginsChanged":0}]}]]],["revogr-filter-panel",[[260,"revogr-filter-panel",{"filterNames":[16],"filterEntities":[16],"filterCaptions":[16],"disableDynamicFiltering":[4,"disable-dynamic-filtering"],"closeOnOutsideClick":[4,"close-on-outside-click"],"allowDuplicateOperators":[4,"allow-duplicate-operators"],"isFilterIdSet":[32],"filterId":[32],"currentFilterId":[32],"currentFilterType":[32],"changes":[32],"filterItems":[32],"draggedFilterId":[32],"dragOverFilterId":[32],"show":[64],"getChanges":[64]},[[5,"mousedown","onMouseDown"]]]]],["revogr-clipboard_3",[[0,"revogr-clipboard",{"readonly":[4],"doCopy":[64]},[[4,"paste","onPaste"],[4,"copy","copyStarted"],[4,"cut","cutStarted"]]],[0,"revogr-edit",{"editCell":[16],"column":[16],"editor":[16],"saveOnClose":[4,"save-on-close"],"additionalData":[8,"additional-data"],"cancelChanges":[64],"beforeDisconnect":[64]}],[0,"revogr-order-editor",{"parent":[16],"dimensionRow":[16],"dimensionCol":[16],"dataStore":[16],"rowType":[1,"row-type"],"dragStart":[64],"endOrder":[64],"clearOrder":[64]}]]],["revogr-data_4",[[260,"revogr-data",{"readonly":[4],"range":[4],"rowClass":[1,"row-class"],"additionalData":[8,"additional-data"],"rowSelectionStore":[16],"viewportRow":[16],"viewportCol":[16],"dimensionRow":[16],"colData":[16],"dataStore":[16],"type":[513],"colType":[513,"col-type"],"jobsBeforeRender":[16],"providers":[32],"updateCell":[64]},null,{"dataStore":[{"onDataStoreChange":0}],"colData":[{"onColDataChange":0}]}],[0,"revogr-header",{"viewportCol":[16],"dimensionCol":[16],"selectionStore":[16],"groups":[16],"groupingDepth":[2,"grouping-depth"],"readonly":[4],"canResize":[4,"can-resize"],"resizeHandler":[16],"colData":[16],"columnFilter":[4,"column-filter"],"type":[1],"additionalData":[8,"additional-data"]}],[260,"revogr-viewport-scroll",{"rowHeader":[4,"row-header"],"contentWidth":[2,"content-width"],"contentHeight":[2,"content-height"],"colType":[1,"col-type"],"noHorizontalScrollTransfer":[4,"no-horizontal-scroll-transfer"],"setScroll":[64],"changeScroll":[64],"applyScroll":[64]},[[0,"mousewheel-vertical","mousewheelVertical"],[0,"mousewheel-horizontal","mousewheelHorizontal"],[0,"scroll-coordinate","scrollApply"]]],[0,"vnode-html",{"redraw":[16]}]]],["revogr-attribution_7",[[0,"revogr-row-headers",{"height":[2],"dataPorts":[16],"headerProp":[16],"rowClass":[1,"row-class"],"resize":[4],"rowHeaderColumn":[16],"additionalData":[8,"additional-data"],"jobsBeforeRender":[16]}],[260,"revogr-overlay-selection",{"readonly":[4],"range":[4],"canDrag":[4,"can-drag"],"useClipboard":[4,"use-clipboard"],"selectionStore":[16],"dimensionRow":[16],"dimensionCol":[16],"dataStore":[16],"colData":[16],"lastCell":[16],"editors":[16],"applyChangesOnClose":[4,"apply-changes-on-close"],"additionalData":[8,"additional-data"],"isMobileDevice":[4,"is-mobile-device"]},[[5,"touchmove","onMouseMove"],[5,"mousemove","onMouseMove"],[5,"touchend","onMouseUp"],[5,"mouseup","onMouseUp"],[5,"mouseleave","onMouseUp"],[0,"dragstartcell","onCellDrag"],[4,"keyup","onKeyUp"],[4,"keydown","onKeyDown"]],{"selectionStore":[{"selectionServiceSet":0}],"dimensionRow":[{"createAutoFillService":0}],"dimensionCol":[{"createAutoFillService":0}],"dataStore":[{"columnServiceSet":0}],"colData":[{"columnServiceSet":0}]}],[0,"revogr-attribution"],[260,"revogr-focus",{"colType":[1,"col-type"],"rowType":[1,"row-type"],"selectionStore":[16],"dimensionRow":[16],"dimensionCol":[16],"dataStore":[16],"colData":[16],"focusTemplate":[16]}],[0,"revogr-scroll-virtual",{"dimension":[1],"realSize":[2,"real-size"],"virtualSize":[2,"virtual-size"],"clientSize":[2,"client-size"],"setScroll":[64],"changeScroll":[64]}],[0,"revogr-temp-range",{"selectionStore":[16],"dimensionRow":[16],"dimensionCol":[16]}],[0,"revogr-extra",{"nodes":[16],"update":[32],"refresh":[64]}]]]], options);
52
52
  });
@@ -108,6 +108,10 @@ const FilterPanel = class {
108
108
  * If true, closes the filter panel when clicking outside
109
109
  */
110
110
  this.closeOnOutsideClick = true;
111
+ /**
112
+ * Whether the filter panel allows the same operator more than once per column.
113
+ */
114
+ this.allowDuplicateOperators = true;
111
115
  this.debouncedApplyFilter = debounce(() => {
112
116
  this.filterChange.emit(this.filterItems);
113
117
  }, 400);
@@ -421,11 +425,15 @@ const FilterPanel = class {
421
425
  }
422
426
  }
423
427
  renderSelectOptions(type, isDefaultTypeRemoved = false) {
428
+ var _a;
424
429
  if (!this.changes) {
425
430
  return;
426
431
  }
427
432
  const options = [];
428
433
  const prop = this.changes.prop;
434
+ if (prop === undefined) {
435
+ return;
436
+ }
429
437
  const hidden = new Set();
430
438
  Object.keys(this.filterItems).forEach((prop) => {
431
439
  const values = this.filterItems[prop];
@@ -435,6 +443,9 @@ const FilterPanel = class {
435
443
  }
436
444
  });
437
445
  });
446
+ const selectedTypes = new Set(((_a = this.filterItems[prop]) !== null && _a !== void 0 ? _a : [])
447
+ .filter(filter => !filter.hidden)
448
+ .map(filter => filter.type));
438
449
  if (!isDefaultTypeRemoved) {
439
450
  const capts = Object.assign(Object.assign({}, this.filterCaptionsInternal), this.filterCaptions);
440
451
  options.push(h("option", { selected: this.currentFilterType === defaultType, value: defaultType }, prop && this.filterItems[prop] && this.filterItems[prop].length > 0
@@ -442,7 +453,9 @@ const FilterPanel = class {
442
453
  : this.filterNames[defaultType]));
443
454
  }
444
455
  for (let gIndex in this.changes.filterTypes) {
445
- const group = this.changes.filterTypes[gIndex].filter(k => !hidden.has(k));
456
+ const group = this.changes.filterTypes[gIndex].filter(k => !hidden.has(k) && (this.allowDuplicateOperators ||
457
+ !selectedTypes.has(k) ||
458
+ (isDefaultTypeRemoved && type === k)));
446
459
  if (group.length) {
447
460
  options.push(...group.map(k => (h("option", { value: k, selected: type === k }, this.filterNames[k]))));
448
461
  options.push(h("option", { disabled: true }));
@@ -537,7 +550,7 @@ const FilterPanel = class {
537
550
  top: `${(_d = (_c = this.changes) === null || _c === void 0 ? void 0 : _c.y) !== null && _d !== void 0 ? _d : 0}px`,
538
551
  };
539
552
  const capts = Object.assign(Object.assign({}, this.filterCaptionsInternal), this.filterCaptions);
540
- return (h(Host, { key: '2a19b35adb56fb7d23385fffebc768838edee162' }, h("dialog", { key: '94386d7cbc4bd9c631f72928938b1d1550a3de82', class: "filter-panel-dialog", style: style, ref: el => (this.dialog = el), onCancel: e => {
553
+ return (h(Host, { key: '8859c452eb08838f65f18efecbdde7f65fda2b49' }, h("dialog", { key: 'f603067ff0986a9f344cbbf816388d2bbac198bb', class: "filter-panel-dialog", style: style, ref: el => (this.dialog = el), onCancel: e => {
541
554
  e.preventDefault();
542
555
  this.onCancel();
543
556
  } }, this.changes && [
@@ -546,7 +559,7 @@ const FilterPanel = class {
546
559
  ((_g = this.changes) === null || _g === void 0 ? void 0 : _g.hideDefaultFilters) !== true && [
547
560
  h("label", { key: "filter-title" }, capts.title),
548
561
  h("div", { key: "filter-holder", class: "filter-holder" }, this.getFilterItemsList()),
549
- h("div", { key: "add-filter", class: "add-filter" }, h("select", { key: '4f7354e39d8e5cf9ae7b735290eff18d105ab87e', id: FILTER_ID, class: "select-css", onChange: e => this.onAddNewFilter(e) }, this.renderSelectOptions(this.currentFilterType))),
562
+ h("div", { key: "add-filter", class: "add-filter" }, h("select", { key: '2ec0a66918edf91bdde3962b6ec84c89f6f1c8f1', id: FILTER_ID, class: "select-css", onChange: e => this.onAddNewFilter(e) }, this.renderSelectOptions(this.currentFilterType))),
550
563
  ],
551
564
  h("slot", { key: "default-slot" }),
552
565
  ((_j = (_h = this.changes).extraBottomContent) === null || _j === void 0 ? void 0 : _j.call(_h, this.changes)) || '',
@@ -494,6 +494,11 @@ export namespace Components {
494
494
  "refresh": () => Promise<void>;
495
495
  }
496
496
  interface RevogrFilterPanel {
497
+ /**
498
+ * Whether the filter panel allows the same operator more than once per column.
499
+ * @default true
500
+ */
501
+ "allowDuplicateOperators": boolean;
497
502
  /**
498
503
  * If true, closes the filter panel when clicking outside
499
504
  * @default true
@@ -1989,6 +1994,11 @@ declare namespace LocalJSX {
1989
1994
  )[];
1990
1995
  }
1991
1996
  interface RevogrFilterPanel {
1997
+ /**
1998
+ * Whether the filter panel allows the same operator more than once per column.
1999
+ * @default true
2000
+ */
2001
+ "allowDuplicateOperators"?: boolean;
1992
2002
  /**
1993
2003
  * If true, closes the filter panel when clicking outside
1994
2004
  * @default true
@@ -2547,6 +2557,7 @@ declare namespace LocalJSX {
2547
2557
  interface RevogrFilterPanelAttributes {
2548
2558
  "disableDynamicFiltering": boolean;
2549
2559
  "closeOnOutsideClick": boolean;
2560
+ "allowDuplicateOperators": boolean;
2550
2561
  }
2551
2562
  interface RevogrFocusAttributes {
2552
2563
  "colType": DimensionCols;
@@ -32,6 +32,10 @@ export declare class FilterPanel {
32
32
  * If true, closes the filter panel when clicking outside
33
33
  */
34
34
  closeOnOutsideClick: boolean;
35
+ /**
36
+ * Whether the filter panel allows the same operator more than once per column.
37
+ */
38
+ allowDuplicateOperators: boolean;
35
39
  filterChange: EventEmitter<MultiFilterItem>;
36
40
  resetChange: EventEmitter<ColumnProp>;
37
41
  onMouseDown(e: MouseEvent): void;
@@ -46,6 +46,7 @@ export declare class FilterPlugin extends BasePlugin {
46
46
  filterNameIndexByType: Record<string, string>;
47
47
  filterFunctionsIndexedByType: Record<string, LogicFunction>;
48
48
  filterProp: string;
49
+ private allowDuplicateOperators;
49
50
  extraHyperContent?: (data: ShowData) => VNode | VNode[];
50
51
  extraBottomHyperContent?: (data: ShowData) => VNode | VNode[];
51
52
  constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders, config?: ColumnFilterConfig | undefined);
@@ -86,6 +86,11 @@ export interface ColumnFilterConfig {
86
86
  * Whether or not to close the filter panel when clicking outside
87
87
  */
88
88
  closeFilterPanelOnOutsideClick?: boolean;
89
+ /**
90
+ * Whether the filter panel allows the same operator more than once per column.
91
+ * Defaults to true to preserve support for repeated conditions in multi-filter expressions.
92
+ */
93
+ allowDuplicateOperators?: boolean;
89
94
  }
90
95
  export type FilterCollectionItem = {
91
96
  type: FilterType;
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],
@@ -15869,13 +15883,14 @@ class FilterPlugin extends BasePlugin {
15869
15883
  this.filterNameIndexByType = Object.assign({}, filterNames);
15870
15884
  this.filterFunctionsIndexedByType = Object.assign({}, filterCoreFunctionsIndexedByType);
15871
15885
  this.filterProp = FILTER_PROP;
15886
+ this.allowDuplicateOperators = true;
15872
15887
  if (config) {
15873
15888
  this.initConfig(config);
15874
15889
  }
15875
15890
  const existingNodes = this.revogrid.registerVNode.filter(n => typeof n === 'object' && n.$tag$ !== FILTE_PANEL);
15876
15891
  this.revogrid.registerVNode = [
15877
15892
  ...existingNodes,
15878
- 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()),
15879
15894
  ];
15880
15895
  const aftersourceset = async () => {
15881
15896
  const filterCollectionProps = Object.keys(this.filterCollection);
@@ -15902,15 +15917,24 @@ class FilterPlugin extends BasePlugin {
15902
15917
  };
15903
15918
  this.addEventListener('headerclick', e => this.headerclick(e));
15904
15919
  this.addEventListener(FILTER_CONFIG_CHANGED_EVENT, ({ detail }) => {
15905
- if (!detail ||
15906
- (typeof detail === 'object' &&
15907
- (!detail.multiFilterItems ||
15908
- !Object.keys(detail.multiFilterItems).length))) {
15920
+ if (!detail) {
15909
15921
  this.clearFiltering();
15910
15922
  return;
15911
15923
  }
15912
15924
  if (typeof detail === 'object') {
15913
- 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
+ }
15914
15938
  }
15915
15939
  aftersourceset();
15916
15940
  });
@@ -15924,6 +15948,11 @@ class FilterPlugin extends BasePlugin {
15924
15948
  return null;
15925
15949
  }
15926
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
+ }
15927
15956
  if (config.multiFilterItems) {
15928
15957
  this.multiFilterItems = Object.assign({}, config.multiFilterItems);
15929
15958
  }
package/hydrate/index.mjs CHANGED
@@ -7493,6 +7493,10 @@ class FilterPanel {
7493
7493
  * If true, closes the filter panel when clicking outside
7494
7494
  */
7495
7495
  this.closeOnOutsideClick = true;
7496
+ /**
7497
+ * Whether the filter panel allows the same operator more than once per column.
7498
+ */
7499
+ this.allowDuplicateOperators = true;
7496
7500
  this.debouncedApplyFilter = debounce$1(() => {
7497
7501
  this.filterChange.emit(this.filterItems);
7498
7502
  }, 400);
@@ -7806,11 +7810,15 @@ class FilterPanel {
7806
7810
  }
7807
7811
  }
7808
7812
  renderSelectOptions(type, isDefaultTypeRemoved = false) {
7813
+ var _a;
7809
7814
  if (!this.changes) {
7810
7815
  return;
7811
7816
  }
7812
7817
  const options = [];
7813
7818
  const prop = this.changes.prop;
7819
+ if (prop === undefined) {
7820
+ return;
7821
+ }
7814
7822
  const hidden = new Set();
7815
7823
  Object.keys(this.filterItems).forEach((prop) => {
7816
7824
  const values = this.filterItems[prop];
@@ -7820,6 +7828,9 @@ class FilterPanel {
7820
7828
  }
7821
7829
  });
7822
7830
  });
7831
+ const selectedTypes = new Set(((_a = this.filterItems[prop]) !== null && _a !== void 0 ? _a : [])
7832
+ .filter(filter => !filter.hidden)
7833
+ .map(filter => filter.type));
7823
7834
  if (!isDefaultTypeRemoved) {
7824
7835
  const capts = Object.assign(Object.assign({}, this.filterCaptionsInternal), this.filterCaptions);
7825
7836
  options.push(hAsync("option", { selected: this.currentFilterType === defaultType, value: defaultType }, prop && this.filterItems[prop] && this.filterItems[prop].length > 0
@@ -7827,7 +7838,9 @@ class FilterPanel {
7827
7838
  : this.filterNames[defaultType]));
7828
7839
  }
7829
7840
  for (let gIndex in this.changes.filterTypes) {
7830
- const group = this.changes.filterTypes[gIndex].filter(k => !hidden.has(k));
7841
+ const group = this.changes.filterTypes[gIndex].filter(k => !hidden.has(k) && (this.allowDuplicateOperators ||
7842
+ !selectedTypes.has(k) ||
7843
+ (isDefaultTypeRemoved && type === k)));
7831
7844
  if (group.length) {
7832
7845
  options.push(...group.map(k => (hAsync("option", { value: k, selected: type === k }, this.filterNames[k]))));
7833
7846
  options.push(hAsync("option", { disabled: true }));
@@ -7922,7 +7935,7 @@ class FilterPanel {
7922
7935
  top: `${(_d = (_c = this.changes) === null || _c === void 0 ? void 0 : _c.y) !== null && _d !== void 0 ? _d : 0}px`,
7923
7936
  };
7924
7937
  const capts = Object.assign(Object.assign({}, this.filterCaptionsInternal), this.filterCaptions);
7925
- return (hAsync(Host, { key: '2a19b35adb56fb7d23385fffebc768838edee162' }, hAsync("dialog", { key: '94386d7cbc4bd9c631f72928938b1d1550a3de82', class: "filter-panel-dialog", style: style, ref: el => (this.dialog = el), onCancel: e => {
7938
+ return (hAsync(Host, { key: '8859c452eb08838f65f18efecbdde7f65fda2b49' }, hAsync("dialog", { key: 'f603067ff0986a9f344cbbf816388d2bbac198bb', class: "filter-panel-dialog", style: style, ref: el => (this.dialog = el), onCancel: e => {
7926
7939
  e.preventDefault();
7927
7940
  this.onCancel();
7928
7941
  } }, this.changes && [
@@ -7931,7 +7944,7 @@ class FilterPanel {
7931
7944
  ((_g = this.changes) === null || _g === void 0 ? void 0 : _g.hideDefaultFilters) !== true && [
7932
7945
  hAsync("label", { key: "filter-title" }, capts.title),
7933
7946
  hAsync("div", { key: "filter-holder", class: "filter-holder" }, this.getFilterItemsList()),
7934
- 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))),
7947
+ 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))),
7935
7948
  ],
7936
7949
  hAsync("slot", { key: "default-slot" }),
7937
7950
  ((_j = (_h = this.changes).extraBottomContent) === null || _j === void 0 ? void 0 : _j.call(_h, this.changes)) || '',
@@ -7956,6 +7969,7 @@ class FilterPanel {
7956
7969
  "filterCaptions": [16],
7957
7970
  "disableDynamicFiltering": [4, "disable-dynamic-filtering"],
7958
7971
  "closeOnOutsideClick": [4, "close-on-outside-click"],
7972
+ "allowDuplicateOperators": [4, "allow-duplicate-operators"],
7959
7973
  "isFilterIdSet": [32],
7960
7974
  "filterId": [32],
7961
7975
  "currentFilterId": [32],
@@ -15867,13 +15881,14 @@ class FilterPlugin extends BasePlugin {
15867
15881
  this.filterNameIndexByType = Object.assign({}, filterNames);
15868
15882
  this.filterFunctionsIndexedByType = Object.assign({}, filterCoreFunctionsIndexedByType);
15869
15883
  this.filterProp = FILTER_PROP;
15884
+ this.allowDuplicateOperators = true;
15870
15885
  if (config) {
15871
15886
  this.initConfig(config);
15872
15887
  }
15873
15888
  const existingNodes = this.revogrid.registerVNode.filter(n => typeof n === 'object' && n.$tag$ !== FILTE_PANEL);
15874
15889
  this.revogrid.registerVNode = [
15875
15890
  ...existingNodes,
15876
- 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()),
15891
+ 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()),
15877
15892
  ];
15878
15893
  const aftersourceset = async () => {
15879
15894
  const filterCollectionProps = Object.keys(this.filterCollection);
@@ -15900,15 +15915,24 @@ class FilterPlugin extends BasePlugin {
15900
15915
  };
15901
15916
  this.addEventListener('headerclick', e => this.headerclick(e));
15902
15917
  this.addEventListener(FILTER_CONFIG_CHANGED_EVENT, ({ detail }) => {
15903
- if (!detail ||
15904
- (typeof detail === 'object' &&
15905
- (!detail.multiFilterItems ||
15906
- !Object.keys(detail.multiFilterItems).length))) {
15918
+ if (!detail) {
15907
15919
  this.clearFiltering();
15908
15920
  return;
15909
15921
  }
15910
15922
  if (typeof detail === 'object') {
15911
- this.initConfig(detail);
15923
+ const detailKeys = Object.keys(detail);
15924
+ const preserveCurrentFilters = !detailKeys.includes('multiFilterItems') &&
15925
+ detailKeys.includes('allowDuplicateOperators');
15926
+ this.initConfig(preserveCurrentFilters
15927
+ ? Object.assign(Object.assign({}, detail), { multiFilterItems: this.multiFilterItems }) : detail);
15928
+ if (!detail.multiFilterItems || !Object.keys(detail.multiFilterItems).length) {
15929
+ if (preserveCurrentFilters) {
15930
+ aftersourceset();
15931
+ return;
15932
+ }
15933
+ this.clearFiltering();
15934
+ return;
15935
+ }
15912
15936
  }
15913
15937
  aftersourceset();
15914
15938
  });
@@ -15922,6 +15946,11 @@ class FilterPlugin extends BasePlugin {
15922
15946
  return null;
15923
15947
  }
15924
15948
  initConfig(config) {
15949
+ var _a;
15950
+ this.allowDuplicateOperators = (_a = config.allowDuplicateOperators) !== null && _a !== void 0 ? _a : true;
15951
+ if (this.pop) {
15952
+ this.pop.allowDuplicateOperators = this.allowDuplicateOperators;
15953
+ }
15925
15954
  if (config.multiFilterItems) {
15926
15955
  this.multiFilterItems = Object.assign({}, config.multiFilterItems);
15927
15956
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@revolist/revogrid",
3
- "version": "4.24.2",
3
+ "version": "4.24.3",
4
4
  "type": "module",
5
5
  "description": "Virtual reactive data grid spreadsheet component - RevoGrid.",
6
6
  "license": "MIT",