diff --git a/cmp/grid/impl/ColumnHeader.ts b/cmp/grid/impl/ColumnHeader.ts index 132f14fe43..711f9736f9 100644 --- a/cmp/grid/impl/ColumnHeader.ts +++ b/cmp/grid/impl/ColumnHeader.ts @@ -199,10 +199,7 @@ class ColumnHeaderModel extends HoistModel { this.availableSorts = this.parseAvailableSorts(); if (!XH.isMobileApp && xhColumn?.filterable && filterModel?.getFieldSpec(xhColumn.field)) { - this.columnHeaderFilterModel = new ColumnHeaderFilterModel({ - filterModel, - column: xhColumn - }); + this.columnHeaderFilterModel = new ColumnHeaderFilterModel(filterModel, xhColumn); this.enableFilter = true; } else { this.isAgFiltered = agColumn.isFilterActive(); diff --git a/desktop/cmp/grid/impl/filter/ColumnHeaderFilter.ts b/desktop/cmp/grid/impl/filter/ColumnHeaderFilter.ts index fde75fe118..363e15e3a7 100644 --- a/desktop/cmp/grid/impl/filter/ColumnHeaderFilter.ts +++ b/desktop/cmp/grid/impl/filter/ColumnHeaderFilter.ts @@ -5,18 +5,14 @@ * Copyright © 2024 Extremely Heavy Industries Inc. */ -import {div, filler} from '@xh/hoist/cmp/layout'; -import {tabContainer} from '@xh/hoist/cmp/tab'; +import {div, span} from '@xh/hoist/cmp/layout'; import {hoistCmp, uses} from '@xh/hoist/core'; -import {button, buttonGroup} from '@xh/hoist/desktop/cmp/button'; -import {panel} from '@xh/hoist/desktop/cmp/panel'; -import {toolbar} from '@xh/hoist/desktop/cmp/toolbar'; import {Icon} from '@xh/hoist/icon'; import {popover} from '@xh/hoist/kit/blueprint'; -import {stopPropagation} from '@xh/hoist/utils/js'; import './ColumnHeaderFilter.scss'; import classNames from 'classnames'; import {ColumnHeaderFilterModel} from './ColumnHeaderFilterModel'; +import {headerFilter} from './headerfilter/HeaderFilter'; /** * Component to manage column filters from header. Will appear as a "filter" icon if filters are @@ -41,83 +37,18 @@ export const columnHeaderFilter = hoistCmp.factory({ hasBackdrop: true, interactionKind: 'click', onInteraction: open => { - if (!open) model.closeMenu(); + if (!open) model.close(); }, item: div({ item: hasFilter ? Icon.filter() : Icon.columnMenu(), onClick: e => { e.stopPropagation(); - model.openMenu(); + model.open(); } }), targetTagName: 'div', - content: content() + // Force unmount on close + content: isOpen ? headerFilter() : span() }); } }); - -const content = hoistCmp.factory({ - render() { - return panel({ - title: `Filter`, - className: 'xh-column-header-filter', - compactHeader: true, - onClick: stopPropagation, - onDoubleClick: stopPropagation, - headerItems: [switcher()], - item: tabContainer(), - bbar: bbar() - }); - } -}); - -const bbar = hoistCmp.factory({ - render({model}) { - const {commitOnChange} = model; - return toolbar({ - compact: true, - items: [ - filler(), - button({ - icon: Icon.delete(), - text: 'Clear Filter', - intent: 'danger', - disabled: !model.hasFilter, - onClick: () => model.clear() - }), - button({ - omit: commitOnChange, - icon: Icon.check(), - text: 'Apply Filter', - intent: 'success', - disabled: !model.hasFilter && !model.hasPendingFilter, - onClick: () => model.commit() - }) - ] - }); - } -}); - -const switcher = hoistCmp.factory(({model}) => { - const {fieldType, enableValues} = model.fieldSpec, - {tabs} = model.tabContainerModel; - - return buttonGroup({ - omit: !enableValues || fieldType === 'bool', - className: 'xh-column-header-filter__tab-switcher', - items: tabs.map(it => switcherButton({...it})) - }); -}); - -const switcherButton = hoistCmp.factory(({model, id, title}) => { - const {tabContainerModel} = model, - {activeTabId} = tabContainerModel; - - return button({ - className: 'xh-column-header-filter__tab-switcher__button', - text: title, - active: activeTabId === id, - outlined: true, - onClick: () => tabContainerModel.activateTab(id) - }); -}); diff --git a/desktop/cmp/grid/impl/filter/ColumnHeaderFilterModel.ts b/desktop/cmp/grid/impl/filter/ColumnHeaderFilterModel.ts index 985be5acb3..e541e0301b 100644 --- a/desktop/cmp/grid/impl/filter/ColumnHeaderFilterModel.ts +++ b/desktop/cmp/grid/impl/filter/ColumnHeaderFilterModel.ts @@ -6,186 +6,38 @@ */ import {Column} from '@xh/hoist/cmp/grid'; -import {TabContainerModel} from '@xh/hoist/cmp/tab'; -import {HoistModel, managed} from '@xh/hoist/core'; -import {action, computed, makeObservable, observable} from '@xh/hoist/mobx'; -import {wait} from '@xh/hoist/promise'; +import {HoistModel} from '@xh/hoist/core'; +import {action, makeObservable, observable} from '@xh/hoist/mobx'; import {isEmpty} from 'lodash'; -import {GridFilterModel, GridFilterFieldSpec} from '@xh/hoist/cmp/grid'; -import {customTab} from './custom/CustomTab'; -import {CustomTabModel} from './custom/CustomTabModel'; -import {valuesTab} from './values/ValuesTab'; -import {ValuesTabModel} from './values/ValuesTabModel'; +import {GridFilterModel} from '@xh/hoist/cmp/grid'; export class ColumnHeaderFilterModel extends HoistModel { override xhImpl = true; - column: Column; - gridFilterModel: GridFilterModel; - fieldSpec: GridFilterFieldSpec; + readonly column: Column; + readonly filterModel: GridFilterModel; - @observable isOpen = false; - - @managed tabContainerModel: TabContainerModel; - @managed valuesTabModel: ValuesTabModel; - @managed customTabModel: CustomTabModel; - - get field() { - return this.fieldSpec.field; - } - - get store() { - return this.gridFilterModel.gridModel.store; - } - - get fieldType() { - return this.store.getField(this.field).type; - } - - get currentGridFilter() { - return this.gridFilterModel.filter; - } - - get columnFilters() { - return this.gridFilterModel.getColumnFilters(this.field); - } - - get columnCompoundFilter() { - return this.gridFilterModel.getColumnCompoundFilter(this.field); - } + @observable isOpen: boolean = false; get hasFilter() { - return !isEmpty(this.columnFilters); - } - - get hasPendingFilter() { - const {activeTabId} = this.tabContainerModel; - return activeTabId === 'valuesFilter' - ? !!this.valuesTabModel.filter - : !!this.customTabModel.filter; - } - - @computed - get isCustomFilter() { - const {columnCompoundFilter, columnFilters} = this; - if (columnCompoundFilter) return true; - if (isEmpty(columnFilters)) return false; - return columnFilters.some(it => !['=', '!=', 'includes'].includes(it.op)); - } - - get commitOnChange() { - return this.gridFilterModel.commitOnChange; + const filters = this.filterModel.getColumnFilters(this.column.field); + return !isEmpty(filters); } - constructor({filterModel, column}) { + constructor(filterModel: GridFilterModel, column: Column) { super(); makeObservable(this); - - this.gridFilterModel = filterModel; + this.filterModel = filterModel; this.column = column; - this.fieldSpec = filterModel.getFieldSpec(column.field); - - const {enableValues} = this.fieldSpec; - this.valuesTabModel = enableValues ? new ValuesTabModel(this) : null; - this.customTabModel = new CustomTabModel(this); - this.tabContainerModel = new TabContainerModel({ - switcher: false, - tabs: [ - { - id: 'valuesFilter', - title: 'Values', - content: valuesTab, - omit: !enableValues - }, - { - id: 'customFilter', - title: 'Custom', - content: customTab - } - ], - xhImpl: true - }); - - this.addReaction({ - track: () => this.valuesTabModel?.filter, - run: () => this.doCommitOnChange('valuesFilter'), - debounce: 100 - }); - - this.addReaction({ - track: () => this.customTabModel.filter, - run: () => this.doCommitOnChange('customFilter'), - debounce: 100 - }); - } - - @action - commit(close = true) { - const {tabContainerModel, customTabModel, valuesTabModel} = this, - {activeTabId} = tabContainerModel, - valuesIsActive = activeTabId === 'valuesFilter', - activeTabModel = valuesIsActive ? valuesTabModel : customTabModel, - otherTabModel = valuesIsActive ? customTabModel : valuesTabModel; - - this.setColumnFilters(activeTabModel.filter); - if (close) { - this.closeMenu(); - } else { - // We must wait before resetting as GridFilterModel.setFilter() is async - wait().then(() => otherTabModel?.reset()); - } } @action - clear(close = true) { - this.setColumnFilters(null); - if (close) { - this.closeMenu(); - } else { - // We must wait before resetting as GridFilterModel.setFilter() is async - wait().then(() => this.resetTabModels()); - } - } - - @action - openMenu() { + open() { this.isOpen = true; - this.syncWithFilter(); } @action - closeMenu() { + close() { this.isOpen = false; } - - //------------------- - // Implementation - //------------------- - @action - private syncWithFilter() { - const {isCustomFilter, valuesTabModel, customTabModel, tabContainerModel} = this, - useCustomTab = isCustomFilter || !valuesTabModel, - toTab = useCustomTab ? customTabModel : valuesTabModel, - toTabId = useCustomTab ? 'customFilter' : 'valuesFilter'; - - this.resetTabModels(); - toTab.syncWithFilter(); - - tabContainerModel.activateTab(toTabId); - } - - private setColumnFilters(filters) { - this.gridFilterModel.setColumnFilters(this.field, filters); - } - - private doCommitOnChange(tab) { - if (!this.commitOnChange) return; - if (this.tabContainerModel.activeTabId !== tab) return; - this.commit(false); - } - - private resetTabModels() { - this.customTabModel.reset(); - this.valuesTabModel?.reset(); - } } diff --git a/desktop/cmp/grid/impl/filter/headerfilter/HeaderFilter.ts b/desktop/cmp/grid/impl/filter/headerfilter/HeaderFilter.ts new file mode 100644 index 0000000000..e33efe220b --- /dev/null +++ b/desktop/cmp/grid/impl/filter/headerfilter/HeaderFilter.ts @@ -0,0 +1,88 @@ +/* + * This file belongs to Hoist, an application development toolkit + * developed by Extremely Heavy Industries (www.xh.io | info@xh.io) + * + * Copyright © 2024 Extremely Heavy Industries Inc. + */ + +import {filler} from '@xh/hoist/cmp/layout'; +import {tabContainer} from '@xh/hoist/cmp/tab'; +import {creates, hoistCmp} from '@xh/hoist/core'; +import {button, buttonGroup} from '@xh/hoist/desktop/cmp/button'; +import {panel} from '@xh/hoist/desktop/cmp/panel'; +import {toolbar} from '@xh/hoist/desktop/cmp/toolbar'; +import {Icon} from '@xh/hoist/icon'; +import {stopPropagation} from '@xh/hoist/utils/js'; +import {HeaderFilterModel} from './HeaderFilterModel'; + +/** + * Pop-up panel to display column specific filters + * + * @internal + */ +export const headerFilter = hoistCmp.factory({ + model: creates(HeaderFilterModel), + render() { + return panel({ + title: `Filter`, + className: 'xh-column-header-filter', + compactHeader: true, + onClick: stopPropagation, + onDoubleClick: stopPropagation, + headerItems: [switcher()], + item: tabContainer(), + bbar: bbar() + }); + } +}); + +const bbar = hoistCmp.factory({ + render({model}) { + const {commitOnChange} = model; + return toolbar({ + compact: true, + items: [ + filler(), + button({ + icon: Icon.delete(), + text: 'Clear Filter', + intent: 'danger', + disabled: !model.hasFilter, + onClick: () => model.clear() + }), + button({ + omit: commitOnChange, + icon: Icon.check(), + text: 'Apply Filter', + intent: 'success', + disabled: !model.hasFilter && !model.hasPendingFilter, + onClick: () => model.commit() + }) + ] + }); + } +}); + +const switcher = hoistCmp.factory(({model}) => { + const {fieldType, enableValues} = model.fieldSpec, + {tabs} = model.tabContainerModel; + + return buttonGroup({ + omit: !enableValues || fieldType === 'bool', + className: 'xh-column-header-filter__tab-switcher', + items: tabs.map(it => switcherButton({...it})) + }); +}); + +const switcherButton = hoistCmp.factory(({model, id, title}) => { + const {tabContainerModel} = model, + {activeTabId} = tabContainerModel; + + return button({ + className: 'xh-column-header-filter__tab-switcher__button', + text: title, + active: activeTabId === id, + outlined: true, + onClick: () => tabContainerModel.activateTab(id) + }); +}); diff --git a/desktop/cmp/grid/impl/filter/headerfilter/HeaderFilterModel.ts b/desktop/cmp/grid/impl/filter/headerfilter/HeaderFilterModel.ts new file mode 100644 index 0000000000..c0a9e78d7a --- /dev/null +++ b/desktop/cmp/grid/impl/filter/headerfilter/HeaderFilterModel.ts @@ -0,0 +1,181 @@ +/* + * This file belongs to Hoist, an application development toolkit + * developed by Extremely Heavy Industries (www.xh.io | info@xh.io) + * + * Copyright © 2024 Extremely Heavy Industries Inc. + */ + +import {TabContainerModel} from '@xh/hoist/cmp/tab'; +import {HoistModel, managed, lookup} from '@xh/hoist/core'; +import {action, computed} from '@xh/hoist/mobx'; +import {wait} from '@xh/hoist/promise'; +import {isEmpty} from 'lodash'; +import {GridFilterFieldSpec} from '@xh/hoist/cmp/grid'; +import {customTab} from './custom/CustomTab'; +import {CustomTabModel} from './custom/CustomTabModel'; +import {valuesTab} from './values/ValuesTab'; +import {ValuesTabModel} from './values/ValuesTabModel'; +import {ColumnHeaderFilterModel} from '../ColumnHeaderFilterModel'; + +export class HeaderFilterModel extends HoistModel { + override xhImpl = true; + + fieldSpec: GridFilterFieldSpec; + + @lookup(ColumnHeaderFilterModel) + parent: ColumnHeaderFilterModel; + + @managed tabContainerModel: TabContainerModel; + @managed valuesTabModel: ValuesTabModel; + @managed customTabModel: CustomTabModel; + + get filterModel() { + return this.parent.filterModel; + } + + get field() { + return this.fieldSpec.field; + } + + get store() { + return this.filterModel.gridModel.store; + } + + get fieldType() { + return this.store.getField(this.field).type; + } + + get currentGridFilter() { + return this.filterModel.filter; + } + + get columnFilters() { + return this.filterModel.getColumnFilters(this.field); + } + + get columnCompoundFilter() { + return this.filterModel.getColumnCompoundFilter(this.field); + } + + get hasFilter() { + return !isEmpty(this.columnFilters); + } + + get hasPendingFilter() { + const {activeTabId} = this.tabContainerModel; + return activeTabId === 'valuesFilter' + ? !!this.valuesTabModel.filter + : !!this.customTabModel.filter; + } + + @computed + get isCustomFilter() { + const {columnCompoundFilter, columnFilters} = this; + if (columnCompoundFilter) return true; + if (isEmpty(columnFilters)) return false; + return columnFilters.some(it => !['=', '!=', 'includes'].includes(it.op)); + } + + get commitOnChange() { + return this.filterModel.commitOnChange; + } + + override onLinked() { + super.onLinked(); + this.fieldSpec = this.filterModel.getFieldSpec(this.parent.column.field); + + const {enableValues} = this.fieldSpec; + this.valuesTabModel = enableValues ? new ValuesTabModel(this) : null; + this.customTabModel = new CustomTabModel(this); + this.tabContainerModel = new TabContainerModel({ + switcher: false, + tabs: [ + { + id: 'valuesFilter', + title: 'Values', + content: valuesTab, + omit: !enableValues + }, + { + id: 'customFilter', + title: 'Custom', + content: customTab + } + ], + xhImpl: true + }); + + this.addReaction({ + track: () => this.valuesTabModel?.filter, + run: () => this.doCommitOnChange('valuesFilter'), + debounce: 100 + }); + + this.addReaction({ + track: () => this.customTabModel.filter, + run: () => this.doCommitOnChange('customFilter'), + debounce: 100 + }); + + this.syncWithFilter(); + } + + @action + commit(close: boolean = true) { + const {tabContainerModel, customTabModel, valuesTabModel} = this, + {activeTabId} = tabContainerModel, + valuesIsActive = activeTabId === 'valuesFilter', + activeTabModel = valuesIsActive ? valuesTabModel : customTabModel, + otherTabModel = valuesIsActive ? customTabModel : valuesTabModel; + + this.setColumnFilters(activeTabModel.filter); + if (close) { + this.parent.close(); + } else { + // We must wait before resetting as GridFilterModel.setFilter() is async + wait().then(() => otherTabModel?.reset()); + } + } + + @action + clear(close: boolean = true) { + this.setColumnFilters(null); + if (close) { + this.parent.close(); + } else { + // We must wait before resetting as GridFilterModel.setFilter() is async + wait().then(() => this.resetTabModels()); + } + } + + //------------------- + // Implementation + //------------------- + @action + private syncWithFilter() { + const {isCustomFilter, valuesTabModel, customTabModel, tabContainerModel} = this, + useCustomTab = isCustomFilter || !valuesTabModel, + toTab = useCustomTab ? customTabModel : valuesTabModel, + toTabId = useCustomTab ? 'customFilter' : 'valuesFilter'; + + this.resetTabModels(); + toTab.syncWithFilter(); + + tabContainerModel.activateTab(toTabId); + } + + private setColumnFilters(filters) { + this.filterModel.setColumnFilters(this.field, filters); + } + + private doCommitOnChange(tab) { + if (!this.commitOnChange) return; + if (this.tabContainerModel.activeTabId !== tab) return; + this.commit(false); + } + + private resetTabModels() { + this.customTabModel.reset(); + this.valuesTabModel?.reset(); + } +} diff --git a/desktop/cmp/grid/impl/filter/custom/CustomRow.ts b/desktop/cmp/grid/impl/filter/headerfilter/custom/CustomRow.ts similarity index 100% rename from desktop/cmp/grid/impl/filter/custom/CustomRow.ts rename to desktop/cmp/grid/impl/filter/headerfilter/custom/CustomRow.ts diff --git a/desktop/cmp/grid/impl/filter/custom/CustomRowModel.ts b/desktop/cmp/grid/impl/filter/headerfilter/custom/CustomRowModel.ts similarity index 95% rename from desktop/cmp/grid/impl/filter/custom/CustomRowModel.ts rename to desktop/cmp/grid/impl/filter/headerfilter/custom/CustomRowModel.ts index 50b26b225e..f383222cd1 100644 --- a/desktop/cmp/grid/impl/filter/custom/CustomRowModel.ts +++ b/desktop/cmp/grid/impl/filter/headerfilter/custom/CustomRowModel.ts @@ -6,7 +6,7 @@ */ import {HoistModel} from '@xh/hoist/core'; import {FieldFilterOperator, FieldFilterSpec} from '@xh/hoist/data'; -import {ColumnHeaderFilterModel} from '@xh/hoist/desktop/cmp/grid/impl/filter/ColumnHeaderFilterModel'; +import {HeaderFilterModel} from '../HeaderFilterModel'; import {bindable, computed, makeObservable} from '@xh/hoist/mobx'; import {isArray, isNil} from 'lodash'; import {CustomTabModel} from './CustomTabModel'; @@ -20,7 +20,7 @@ export class CustomRowModel extends HoistModel { override xhImpl = true; parentModel: CustomTabModel; - headerFilterModel: ColumnHeaderFilterModel; + headerFilterModel: HeaderFilterModel; @bindable op: OperatorOptionValue; @bindable inputVal: any; diff --git a/desktop/cmp/grid/impl/filter/custom/CustomTab.scss b/desktop/cmp/grid/impl/filter/headerfilter/custom/CustomTab.scss similarity index 100% rename from desktop/cmp/grid/impl/filter/custom/CustomTab.scss rename to desktop/cmp/grid/impl/filter/headerfilter/custom/CustomTab.scss diff --git a/desktop/cmp/grid/impl/filter/custom/CustomTab.ts b/desktop/cmp/grid/impl/filter/headerfilter/custom/CustomTab.ts similarity index 100% rename from desktop/cmp/grid/impl/filter/custom/CustomTab.ts rename to desktop/cmp/grid/impl/filter/headerfilter/custom/CustomTab.ts diff --git a/desktop/cmp/grid/impl/filter/custom/CustomTabModel.ts b/desktop/cmp/grid/impl/filter/headerfilter/custom/CustomTabModel.ts similarity index 93% rename from desktop/cmp/grid/impl/filter/custom/CustomTabModel.ts rename to desktop/cmp/grid/impl/filter/headerfilter/custom/CustomTabModel.ts index 9d7b9b3915..4570b2290c 100644 --- a/desktop/cmp/grid/impl/filter/custom/CustomTabModel.ts +++ b/desktop/cmp/grid/impl/filter/headerfilter/custom/CustomTabModel.ts @@ -8,14 +8,14 @@ import {HoistModel, XH} from '@xh/hoist/core'; import {CompoundFilterOperator, FilterLike} from '@xh/hoist/data'; import {action, bindable, computed, makeObservable, observable} from '@xh/hoist/mobx'; import {compact, isEmpty} from 'lodash'; -import {ColumnHeaderFilterModel} from '../ColumnHeaderFilterModel'; +import {HeaderFilterModel} from '../HeaderFilterModel'; import {CustomRowModel} from './CustomRowModel'; export class CustomTabModel extends HoistModel { override xhImpl = true; - headerFilterModel: ColumnHeaderFilterModel; + headerFilterModel: HeaderFilterModel; @bindable op: CompoundFilterOperator = 'AND'; @observable.ref rowModels: CustomRowModel[] = []; @@ -42,7 +42,7 @@ export class CustomTabModel extends HoistModel { return this.headerFilterModel.columnFilters; } - constructor(headerFilterModel: ColumnHeaderFilterModel) { + constructor(headerFilterModel: HeaderFilterModel) { super(); makeObservable(this); this.headerFilterModel = headerFilterModel; diff --git a/desktop/cmp/grid/impl/filter/values/ValuesTab.scss b/desktop/cmp/grid/impl/filter/headerfilter/values/ValuesTab.scss similarity index 100% rename from desktop/cmp/grid/impl/filter/values/ValuesTab.scss rename to desktop/cmp/grid/impl/filter/headerfilter/values/ValuesTab.scss diff --git a/desktop/cmp/grid/impl/filter/values/ValuesTab.ts b/desktop/cmp/grid/impl/filter/headerfilter/values/ValuesTab.ts similarity index 100% rename from desktop/cmp/grid/impl/filter/values/ValuesTab.ts rename to desktop/cmp/grid/impl/filter/headerfilter/values/ValuesTab.ts diff --git a/desktop/cmp/grid/impl/filter/values/ValuesTabModel.ts b/desktop/cmp/grid/impl/filter/headerfilter/values/ValuesTabModel.ts similarity index 95% rename from desktop/cmp/grid/impl/filter/values/ValuesTabModel.ts rename to desktop/cmp/grid/impl/filter/headerfilter/values/ValuesTabModel.ts index 6902d45baa..259d84ff7d 100644 --- a/desktop/cmp/grid/impl/filter/values/ValuesTabModel.ts +++ b/desktop/cmp/grid/impl/filter/headerfilter/values/ValuesTabModel.ts @@ -7,7 +7,7 @@ import {GridFilterModel, GridModel} from '@xh/hoist/cmp/grid'; import {HoistModel, managed} from '@xh/hoist/core'; import {FieldFilterSpec} from '@xh/hoist/data'; -import {ColumnHeaderFilterModel} from '../ColumnHeaderFilterModel'; +import {HeaderFilterModel} from '../HeaderFilterModel'; import {checkbox} from '@xh/hoist/desktop/cmp/input'; import {action, bindable, computed, makeObservable, observable} from '@xh/hoist/mobx'; import {castArray, difference, isEmpty, partition, uniq, without} from 'lodash'; @@ -15,7 +15,7 @@ import {castArray, difference, isEmpty, partition, uniq, without} from 'lodash'; export class ValuesTabModel extends HoistModel { override xhImpl = true; - headerFilterModel: ColumnHeaderFilterModel; + headerFilterModel: HeaderFilterModel; /** Checkbox grid to display enumerated set of values */ @managed @observable.ref gridModel: GridModel; @@ -59,7 +59,7 @@ export class ValuesTabModel extends HoistModel { } get gridFilterModel() { - return this.headerFilterModel.gridFilterModel; + return this.headerFilterModel.filterModel; } get values() { @@ -74,7 +74,7 @@ export class ValuesTabModel extends HoistModel { return this.values.length < this.valueCount; } - constructor(headerFilterModel: ColumnHeaderFilterModel) { + constructor(headerFilterModel: HeaderFilterModel) { super(); makeObservable(this); @@ -83,7 +83,8 @@ export class ValuesTabModel extends HoistModel { this.addReaction({ track: () => this.pendingValues, - run: () => this.syncGrid() + run: () => this.syncGrid(), + fireImmediately: true }); } @@ -193,7 +194,7 @@ export class ValuesTabModel extends HoistModel { {fieldType} = headerFilterModel, renderer = fieldSpec.renderer ?? - (fieldType !== 'tags' ? this.headerFilterModel.column.renderer : null); + (fieldType !== 'tags' ? this.headerFilterModel.parent.column.renderer : null); return new GridModel({ store: {