diff --git a/apps/components-e2e/src/components/filter-field/filter-field.module.ts b/apps/components-e2e/src/components/filter-field/filter-field.module.ts index e2be60b4f0..052c459374 100644 --- a/apps/components-e2e/src/components/filter-field/filter-field.module.ts +++ b/apps/components-e2e/src/components/filter-field/filter-field.module.ts @@ -19,12 +19,24 @@ import { NgModule } from '@angular/core'; import { Route, RouterModule } from '@angular/router'; import { DtFilterFieldModule } from '@dynatrace/barista-components/filter-field'; import { DtE2EFilterField } from './filter-field'; +import { + DtExampleFilterFieldAsync, + DtFilterFieldExamplesModule, +} from '@dynatrace/examples/filter-field'; -const routes: Route[] = [{ path: '', component: DtE2EFilterField }]; +const routes: Route[] = [ + { path: '', component: DtE2EFilterField }, + { path: 'async', component: DtExampleFilterFieldAsync }, +]; @NgModule({ declarations: [DtE2EFilterField], - imports: [CommonModule, RouterModule.forChild(routes), DtFilterFieldModule], + imports: [ + CommonModule, + DtFilterFieldExamplesModule, + RouterModule.forChild(routes), + DtFilterFieldModule, + ], exports: [], providers: [], }) diff --git a/apps/components-e2e/src/components/quick-filter/quick-filter-async/quick-filter-async.html b/apps/components-e2e/src/components/quick-filter/quick-filter-async/quick-filter-async.html new file mode 100644 index 0000000000..04fd3e8ecc --- /dev/null +++ b/apps/components-e2e/src/components/quick-filter/quick-filter-async/quick-filter-async.html @@ -0,0 +1,14 @@ + + Quick-filter + + All options in the filter field above + + + Quick-filter async example + diff --git a/apps/components-e2e/src/components/quick-filter/quick-filter-async/quick-filter-async.ts b/apps/components-e2e/src/components/quick-filter/quick-filter-async/quick-filter-async.ts new file mode 100644 index 0000000000..4415936339 --- /dev/null +++ b/apps/components-e2e/src/components/quick-filter/quick-filter-async/quick-filter-async.ts @@ -0,0 +1,77 @@ +/** + * @license + * Copyright 2020 Dynatrace LLC + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component } from '@angular/core'; +import { isObject } from '@dynatrace/barista-components/core'; +import { + DtQuickFilterDefaultDataSource, + DtQuickFilterDefaultDataSourceConfig, + DtQuickFilterCurrentFilterChangeEvent, + DtQuickFilterDefaultDataSourceType, +} from '@dynatrace/barista-components/experimental/quick-filter'; + +const filterFieldData = { + autocomplete: [ + { + name: 'AUT (async)', + async: true, + autocomplete: [], + }, + { + name: 'USA', + autocomplete: [ + { name: 'San Francisco' }, + { name: 'Los Angeles' }, + { name: 'New York' }, + ], + }, + ], +}; + +const asyncData = { + name: 'AUT (async)', + autocomplete: [{ name: 'Linz' }, { name: 'Vienna' }, { name: 'Graz' }], +}; + +@Component({ + selector: 'dt-e2e-quick-filter-async', + templateUrl: './quick-filter-async.html', + // template: '' +}) +export class DtE2EQuickFilterAsync { + /** configuration for the quick filter */ + private _config: DtQuickFilterDefaultDataSourceConfig = { + // Method to decide if a node should be displayed in the quick filter + showInSidebar: (node) => + isObject(node) && node.name && node.name !== 'AUT (async)', + }; + + _dataSource = new DtQuickFilterDefaultDataSource< + DtQuickFilterDefaultDataSourceType + >(filterFieldData, this._config); + + currentFilterChanges( + event: DtQuickFilterCurrentFilterChangeEvent< + DtQuickFilterDefaultDataSourceType + >, + ): void { + if (event.added[0] === filterFieldData.autocomplete[0]) { + setTimeout(() => { + this._dataSource.data = asyncData; + }, 1000); + } + } +} diff --git a/apps/components-e2e/src/components/quick-filter/quick-filter.module.ts b/apps/components-e2e/src/components/quick-filter/quick-filter.module.ts index 9949a31d66..c34239b836 100644 --- a/apps/components-e2e/src/components/quick-filter/quick-filter.module.ts +++ b/apps/components-e2e/src/components/quick-filter/quick-filter.module.ts @@ -20,15 +20,21 @@ import { Route, RouterModule } from '@angular/router'; import { DtQuickFilterModule } from '@dynatrace/barista-components/experimental/quick-filter'; import { DtE2EQuickFilter } from './quick-filter/quick-filter'; import { DtE2EQuickFilterInitialData } from './quick-filter-initial-data/quick-filter-initial-data'; +import { DtE2EQuickFilterAsync } from './quick-filter-async/quick-filter-async'; const routes: Route[] = [ { path: '', component: DtE2EQuickFilter }, { path: 'initial-data', component: DtE2EQuickFilterInitialData }, + { path: 'async', component: DtE2EQuickFilterAsync }, ]; @NgModule({ - declarations: [DtE2EQuickFilter, DtE2EQuickFilterInitialData], - imports: [CommonModule, RouterModule.forChild(routes), DtQuickFilterModule], + declarations: [ + DtE2EQuickFilter, + DtE2EQuickFilterInitialData, + DtE2EQuickFilterAsync, + ], + imports: [CommonModule, DtQuickFilterModule, RouterModule.forChild(routes)], exports: [], providers: [], }) diff --git a/libs/barista-components/experimental/quick-filter/src/quick-filter-group.html b/libs/barista-components/experimental/quick-filter/src/quick-filter-group.html index a755e18d9a..22d397af93 100644 --- a/libs/barista-components/experimental/quick-filter/src/quick-filter-group.html +++ b/libs/barista-components/experimental/quick-filter/src/quick-filter-group.html @@ -9,7 +9,7 @@ Any @@ -30,7 +30,7 @@ *ngFor="let item of _getOptions()" [value]="item" [checked]="_isActive(item)" - (change)="_selectCheckBox($event)" + (change)="_selectCheckBox($event, _nodeDef)" > {{ _getViewValue(item) }} diff --git a/libs/barista-components/experimental/quick-filter/src/quick-filter-group.ts b/libs/barista-components/experimental/quick-filter/src/quick-filter-group.ts index ac13c0868d..ec0b98898a 100644 --- a/libs/barista-components/experimental/quick-filter/src/quick-filter-group.ts +++ b/libs/barista-components/experimental/quick-filter/src/quick-filter-group.ts @@ -25,6 +25,7 @@ import { } from '@angular/core'; import { DtCheckboxChange } from '@dynatrace/barista-components/checkbox'; import { + DtAutocompleteValue, DtNodeDef, isDtOptionDef, isDtRenderType, @@ -51,7 +52,7 @@ import { class: 'dt-quick-filter-group', }, }) -export class DtQuickFilterGroup { +export class DtQuickFilterGroup { /** * @internal * The aria-level of the group headlines for the document outline. @@ -63,7 +64,7 @@ export class DtQuickFilterGroup { /** @internal The list of all active filters */ @Input() - set activeFilters(filters: any[][]) { + set activeFilters(filters: DtAutocompleteValue[][]) { this._activeFilterPaths = buildIdPathsFromFilters(filters || []); this._changeDetectorRef.markForCheck(); } @@ -82,17 +83,17 @@ export class DtQuickFilterGroup { } /** @internal Updates a radio box */ - _selectOption(change: DtRadioChange): void { + _selectOption(change: DtRadioChange, group: DtNodeDef): void { if (change.value) { - this.filterChange.emit(updateFilter(change.value)); + this.filterChange.emit(updateFilter([group, change.value])); } } /** @internal Select or deselect a checkbox */ - _selectCheckBox(change: DtCheckboxChange): void { + _selectCheckBox(change: DtCheckboxChange, group: DtNodeDef): void { const action = change.checked - ? addFilter(change.source.value) - : removeFilter(change.source.value); + ? addFilter([group, change.source.value]) + : removeFilter(change.source.value.option!.uid!); this.filterChange.emit(action); } diff --git a/libs/barista-components/experimental/quick-filter/src/quick-filter-utils.ts b/libs/barista-components/experimental/quick-filter/src/quick-filter-utils.ts index 9e635ad8a4..491c5c3038 100644 --- a/libs/barista-components/experimental/quick-filter/src/quick-filter-utils.ts +++ b/libs/barista-components/experimental/quick-filter/src/quick-filter-utils.ts @@ -14,13 +14,11 @@ * limitations under the License. */ -import { DELIMITER } from '@dynatrace/barista-components/filter-field'; +import { DtAutocompleteValue } from '@dynatrace/barista-components/filter-field'; -export function buildIdPathsFromFilters(filters: any[][]): string[] { - return filters.map((path) => - path.reduce( - (previousValue, currentValue) => - `${previousValue.name}${DELIMITER}${currentValue.name}${DELIMITER}`, - ), - ); +/** @internal Build an array of uids from the options without the groups */ +export function buildIdPathsFromFilters( + filters: DtAutocompleteValue[][], +): string[] { + return filters.map((group) => group[group.length - 1].option.uid || ''); } diff --git a/libs/barista-components/experimental/quick-filter/src/quick-filter.ts b/libs/barista-components/experimental/quick-filter/src/quick-filter.ts index 94d943c9e9..a46c737cfe 100644 --- a/libs/barista-components/experimental/quick-filter/src/quick-filter.ts +++ b/libs/barista-components/experimental/quick-filter/src/quick-filter.ts @@ -31,9 +31,12 @@ import { DtFilterField, DtFilterFieldChangeEvent, DtFilterFieldCurrentFilterChangeEvent, + isDtAutocompleteValue, + isDtOptionDef, } from '@dynatrace/barista-components/filter-field'; import { BehaviorSubject, Subject, Observable } from 'rxjs'; import { switchMap, take, takeUntil } from 'rxjs/operators'; +import { _getSourcesOfDtFilterValues } from '../../../filter-field/src/types'; import { DtQuickFilterDataSource } from './quick-filter-data-source'; import { Action, setFilters, switchDataSource } from './state/actions'; import { quickFilterReducer } from './state/reducer'; @@ -143,7 +146,9 @@ export class DtQuickFilter implements AfterViewInit, OnDestroy { return this._filterField.filters; } set filters(filters: T[][]) { - this._store.dispatch(setFilters(filters)); + this._filterField.filters = filters; + // TODO: lukas.holzer convert them to devs + // this._store.dispatch(setFilters(filters)); } /** @@ -169,7 +174,7 @@ export class DtQuickFilter implements AfterViewInit, OnDestroy { /** Angular life-cycle hook that will be called after the view is initialized */ ngAfterViewInit(): void { // We need to wait for the first on stable call, otherwise the - // underlying filterfield will thow an expression changed after checked + // underlying filter field will throw an expression changed after checked // error. Deferring the first filter setting. // Relates to a very weird and hard to reproduce bug described in // https://github.com/dynatrace-oss/barista/issues/1305 @@ -181,9 +186,9 @@ export class DtQuickFilter implements AfterViewInit, OnDestroy { ) // When the filters changes apply them to the filter field .subscribe((filters) => { - if (this._filterField.filters !== filters) { - this._filterField.filters = filters; - } + this._filterField.filters = filters.map((values) => + _getSourcesOfDtFilterValues(values), + ); }); } @@ -212,7 +217,12 @@ export class DtQuickFilter implements AfterViewInit, OnDestroy { /** @internal Bubble the filter field change event through */ _filterFieldChanged(change: DtFilterFieldChangeEvent): void { - this._store.dispatch(setFilters(change.filters)); + // Filter only autocomplete filters as we don't use free-text and range in the quick-filter + const filteredFilters = this._filterField._filterValues.filter((group) => + group.every((value) => isDtAutocompleteValue(value)), + ); + + this._store.dispatch(setFilters(filteredFilters)); this.filterChanges.emit(change); } } diff --git a/libs/barista-components/experimental/quick-filter/src/state/actions.ts b/libs/barista-components/experimental/quick-filter/src/state/actions.ts index 75301aac02..de7deee72e 100644 --- a/libs/barista-components/experimental/quick-filter/src/state/actions.ts +++ b/libs/barista-components/experimental/quick-filter/src/state/actions.ts @@ -15,10 +15,11 @@ */ import { DtFilterFieldDataSource, + DtFilterValue, DtNodeDef, } from '@dynatrace/barista-components/filter-field'; -/** Enum for all the possible action types */ +/** @internal Enum for all the possible action types */ export enum ActionType { INIT = '@@actions init', ADD_FILTER = '@@actions add filter', @@ -30,41 +31,41 @@ export enum ActionType { UPDATE_DATA_SOURCE = '@@actions update dataSource', } -/** Interface for an action */ +/** @internal Interface for an action */ export interface Action { readonly type: ActionType; payload?: T; } -/** Function which helps to create actions without mistakes */ +/** @internal Function which helps to create actions without mistakes */ export const action = (type: ActionType, payload?: T): Action => ({ type, payload, }); -/** Action that sets filters (Bulk operation for addFilter) */ -export const setFilters = (filters: any[][]) => +/** @internal Action that sets filters (Bulk operation for addFilter) */ +export const setFilters = (filters: DtFilterValue[][]) => action(ActionType.SET_FILTERS, filters); -/** Action that unsets a filter group */ +/** @internal Action that unsets a filter group */ export const unsetFilterGroup = (group: DtNodeDef) => action(ActionType.UNSET_FILTER_GROUP, group); -/** Action that adds a filter */ -export const addFilter = (item: DtNodeDef) => - action(ActionType.ADD_FILTER, item); +/** @internal Action that adds a filter */ +export const addFilter = (filter: DtNodeDef[]) => + action(ActionType.ADD_FILTER, filter); -/** Action that removes a filter */ -export const removeFilter = (item: DtNodeDef) => - action(ActionType.REMOVE_FILTER, item); +/** @internal Action that removes a filter */ +export const removeFilter = (uid: string) => + action(ActionType.REMOVE_FILTER, uid); -/** Action that updates a filter */ -export const updateFilter = (item: DtNodeDef) => - action(ActionType.UPDATE_FILTER, item); +/** @internal Action that updates a filter */ +export const updateFilter = (filter: DtNodeDef[]) => + action(ActionType.UPDATE_FILTER, filter); -/** Action that subscribes to a new data source */ +/** @internal Action that subscribes to a new data source */ export const switchDataSource = (item: DtFilterFieldDataSource) => action>(ActionType.SWITCH_DATA_SOURCE, item); -/** Action that updates the data source */ +/** @internal Action that updates the data source */ export const updateDataSource = (nodeDef: DtNodeDef) => action(ActionType.UPDATE_DATA_SOURCE, nodeDef); diff --git a/libs/barista-components/experimental/quick-filter/src/state/effects.ts b/libs/barista-components/experimental/quick-filter/src/state/effects.ts index 6219d31479..9daa685703 100644 --- a/libs/barista-components/experimental/quick-filter/src/state/effects.ts +++ b/libs/barista-components/experimental/quick-filter/src/state/effects.ts @@ -19,26 +19,26 @@ import { DtNodeDef, } from '@dynatrace/barista-components/filter-field'; import { MonoTypeOperatorFunction, Observable } from 'rxjs'; -import { filter, map, switchMap } from 'rxjs/operators'; +import { filter, map, switchMap, take } from 'rxjs/operators'; import { Action, ActionType, updateDataSource } from './actions'; import { QuickFilterState } from './store'; -/** Type for an effect */ +/** @internal Type for an effect */ export type Effect = ( action$: Observable, state$?: Observable, ) => Observable; -/** Operator to filter actions */ +/** @internal Operator to filter actions */ export const ofType = ( ...types: ActionType[] ): MonoTypeOperatorFunction> => filter((action: Action) => types.indexOf(action.type) > -1); -/** Connects to a new Data dataSource */ +/** @internal Connects to a new Data dataSource */ export const switchDataSourceEffect: Effect = (action$: Observable) => action$.pipe( ofType>(ActionType.SWITCH_DATA_SOURCE), - switchMap((action) => action.payload!.connect()), + switchMap((action) => action.payload!.connect().pipe(take(1))), map((nodeDef: DtNodeDef) => updateDataSource(nodeDef)), ); diff --git a/libs/barista-components/experimental/quick-filter/src/state/reducer.spec.ts b/libs/barista-components/experimental/quick-filter/src/state/reducer.spec.ts deleted file mode 100644 index e72639e769..0000000000 --- a/libs/barista-components/experimental/quick-filter/src/state/reducer.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @license - * Copyright 2020 Dynatrace LLC - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { dtAutocompleteDef } from '@dynatrace/barista-components/filter-field'; -import { buildData } from './reducer'; - -test('should build the data with an object', () => { - const data = { name: 'Linz' }; - const autocomplete = dtAutocompleteDef(data, null, [], false, false, false); - expect(buildData(autocomplete)).toMatchObject([data]); -}); - -test('should build the data with undefined', () => { - const data = undefined; - const autocomplete = dtAutocompleteDef(data, null, [], false, false, false); - - expect(buildData(autocomplete)).toMatchObject([data]); -}); diff --git a/libs/barista-components/experimental/quick-filter/src/state/reducer.ts b/libs/barista-components/experimental/quick-filter/src/state/reducer.ts index 761d82eb4d..b359ed15b7 100644 --- a/libs/barista-components/experimental/quick-filter/src/state/reducer.ts +++ b/libs/barista-components/experimental/quick-filter/src/state/reducer.ts @@ -14,10 +14,7 @@ * limitations under the License. */ import { DtLogger, DtLoggerFactory } from '@dynatrace/barista-components/core'; -import { - DELIMITER, - DtNodeDef, -} from '@dynatrace/barista-components/filter-field'; +import { DtAutocompleteValue } from '@dynatrace/barista-components/filter-field'; import { Action, ActionType } from './actions'; import { initialState, QuickFilterState } from './store'; @@ -42,6 +39,7 @@ export function quickFilterReducer( action: Action, ): QuickFilterState { logger.debug(`Reducer <${action.type}> `, action); + console.debug(`Reducer <${action.type}> `, action); switch (action.type) { case ActionType.SWITCH_DATA_SOURCE: @@ -77,13 +75,19 @@ export function quickFilterReducer( // # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /** @internal Add a filter to the filters array */ -export function addFilter(filters: any[][], item: DtNodeDef): any[][] { - return [...filters, buildData(item)]; +export function addFilter( + filters: DtAutocompleteValue[][], + filter: DtAutocompleteValue[], +): DtAutocompleteValue[][] { + return [...filters, filter]; } /** @internal Remove a filter from the filters array */ -export function removeFilter(filters: any[][], item: DtNodeDef): any[][] { - const index = findSelectedOption(filters, item, false); +export function removeFilter( + filters: DtAutocompleteValue[][], + uid: string, +): DtAutocompleteValue[][] { + const index = findSelectedOption(filters, uid, false); const updatedState = [...filters]; if (index > -1) { @@ -94,70 +98,48 @@ export function removeFilter(filters: any[][], item: DtNodeDef): any[][] { } /** @internal Update a filter inside the filters array */ -export function updateFilter(filters: any[][], item: DtNodeDef): any[][] { - const index = findSelectedOption(filters, item, true); - +export function updateFilter( + filters: DtAutocompleteValue[][], + filter: DtAutocompleteValue[], +): DtAutocompleteValue[][] { + const uid = filter[filter.length - 1].option.uid; + const index = findSelectedOption(filters, uid, true); + // if the filter is not in the filters list add it if (index < 0) { - return addFilter(filters, item); + return addFilter(filters, filter); } - - filters[index] = buildData(item); - + // replace the existing filter + filters[index] = filter; return filters; } /** @internal Remove a group from the filters array */ -export function unsetFilterGroup(filters: any[][], group: DtNodeDef): any[][] { - if (group.option && group.option.viewValue) { - return filters.filter( - (filter) => filter[0].name !== group.option!.viewValue, - ); - } - return filters; -} - -/** @internal Build the quick filter data out of a node definition */ -export function buildData(item: DtNodeDef): any[] { - const data = [item.data]; - - if (item.option && item.option.parentAutocomplete) { - data.unshift(item.option.parentAutocomplete.data); - } - return data; +export function unsetFilterGroup( + filters: DtAutocompleteValue[][], + group: DtAutocompleteValue, +): DtAutocompleteValue[][] { + const index = findSelectedOption(filters, group.option.uid, true); + return filters.filter((_, i) => i !== index); } /** @internal Find a filter inside the filters array based on a NodeDef */ export function findSelectedOption( - filters: any[][], - item: DtNodeDef, + filters: DtAutocompleteValue[][], + uid: string | null, distinct: boolean = false, ): number { return filters.findIndex((path) => { - if (item.option && item.option.uid) { - // split the uid in the parts that define the path - // (like the user clicked through in the filter field) - const parts = item.option.uid.split(DELIMITER); - - // if the option is distinct we only have to check for the groups name because - // there can only be one distinct option selected so we know immediately if it is selected - if (distinct && parts[0] === path[0].name) { - return true; - } - - // if it is not distinct we have to build the full path out of the current filters to check - // wether the path matches them provided node definition - const dataPath = path.reduce( - (previousValue, currentValue) => - `${previousValue.name}${DELIMITER}${currentValue.name}${DELIMITER}`, - ); - - // if the built path for the filters inside the array is equal to the option - // in the provided nodeDef then we found our selected option - if (item.option.uid === dataPath) { - return true; - } + if (!uid) { + return false; + } + // if the option is distinct we only have to check for the groups name because + // there can only be one distinct option selected so we know immediately if it is selected + if (distinct && uid.startsWith(path[0].option.uid!)) { + return true; + } + // if the last items uid in the path is equal to the uid, then we found our option. + if (uid === path[path.length - 1].option.uid) { + return true; } - - return false; }); } diff --git a/libs/barista-components/experimental/quick-filter/src/state/store.ts b/libs/barista-components/experimental/quick-filter/src/state/store.ts index 723e10cc3f..64699f7f95 100644 --- a/libs/barista-components/experimental/quick-filter/src/state/store.ts +++ b/libs/barista-components/experimental/quick-filter/src/state/store.ts @@ -14,9 +14,12 @@ * limitations under the License. */ -import { DtNodeDef } from '@dynatrace/barista-components/filter-field'; +import { + DtAutocompleteValue, + DtNodeDef, +} from '@dynatrace/barista-components/filter-field'; import { BehaviorSubject, merge, Observable } from 'rxjs'; -import { map, shareReplay, withLatestFrom } from 'rxjs/operators'; +import { map, shareReplay, tap, withLatestFrom } from 'rxjs/operators'; import { DtQuickFilterDataSource } from '../quick-filter-data-source'; import { Action, ActionType } from './actions'; import { Effect, switchDataSourceEffect } from './effects'; @@ -29,7 +32,7 @@ export interface QuickFilterState { /** The dataSource that is connected with the QuickFilter */ dataSource?: DtQuickFilterDataSource; /** Array of all active filters */ - filters: any[][]; + filters: DtAutocompleteValue[][]; } /** @internal The initial QuickFilter state */ @@ -74,6 +77,7 @@ class QuickFilterStore { shareReplay(), withLatestFrom(this.state$), map(([action, state]) => reducer(state, action)), + tap(console.log), ) .subscribe((state) => { // Here the state gets modified through the outcome of the reducer diff --git a/libs/barista-components/filter-field/index.ts b/libs/barista-components/filter-field/index.ts index 01c80ff7e2..c97e215340 100644 --- a/libs/barista-components/filter-field/index.ts +++ b/libs/barista-components/filter-field/index.ts @@ -53,5 +53,6 @@ export { isDtAutocompleteValue, isDtFreeTextValue, isDtRangeValue, + DtAutocompleteValue, } from './src/types'; export { DT_FILTER_VALUES_PARSER_CONFIG } from './src/filter-field-config'; diff --git a/libs/barista-components/filter-field/src/filter-field.ts b/libs/barista-components/filter-field/src/filter-field.ts index d4c5afbc1a..4bb0bafdc4 100644 --- a/libs/barista-components/filter-field/src/filter-field.ts +++ b/libs/barista-components/filter-field/src/filter-field.ts @@ -261,6 +261,14 @@ export class DtFilterField this._tryApplyFilters(value); this._changeDetectorRef.markForCheck(); } + /** @internal */ + get _filterValues(): DtFilterValue[][] { + return this._filters; + } + set _filterValues(value: DtFilterValue[][]) { + this._tryApplyFilters(value); + this._changeDetectorRef.markForCheck(); + } private _filters: DtFilterValue[][] = []; /** Set the Aria-Label attribute */