+
+
+
diff --git a/libs/barista-components/experimental/quick-filter/src/quick-filter-group.scss b/libs/barista-components/experimental/quick-filter/src/quick-filter-group.scss
new file mode 100644
index 0000000000..b7e9db03b3
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/src/quick-filter-group.scss
@@ -0,0 +1,22 @@
+@import '../../../core/src/style/variables';
+
+:host {
+ display: block;
+ padding: 8px 0;
+}
+
+.dt-quick-filter-group-headline {
+ margin: 0 0 8px;
+ font-size: 18px;
+ font-weight: normal;
+ color: $gray-700;
+}
+
+.dt-quick-filter-group-items {
+ display: flex;
+ flex-flow: column;
+
+ > * {
+ margin-bottom: 8px;
+ }
+}
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
new file mode 100644
index 0000000000..aec0160295
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/src/quick-filter-group.ts
@@ -0,0 +1,140 @@
+/**
+ * @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,
+ ChangeDetectionStrategy,
+ Input,
+ Output,
+ EventEmitter,
+ ChangeDetectorRef,
+ ViewEncapsulation,
+} from '@angular/core';
+import {
+ DtNodeDef,
+ isDtOptionDef,
+ isDtRenderType,
+} from '@dynatrace/barista-components/filter-field';
+import { DtRadioChange } from '@dynatrace/barista-components/radio';
+import { DtCheckboxChange } from '../../../checkbox';
+import {
+ addFilter,
+ removeFilter,
+ updateFilter,
+ Action,
+ unsetFilterGroup,
+} from './state/actions';
+import { buildIdPathsFromFilters } from './quick-filter-utils';
+
+/** @internal */
+@Component({
+ selector: 'dt-quick-filter-group',
+ templateUrl: './quick-filter-group.html',
+ styleUrls: ['./quick-filter-group.scss'],
+ encapsulation: ViewEncapsulation.Emulated,
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ preserveWhitespaces: false,
+ host: {
+ class: 'dt-quick-filter-group',
+ },
+})
+export class DtQuickFilterGroup {
+ /** @internal The nodeDef of the autocomplete that should be rendered */
+ @Input('nodeDef') _nodeDef: DtNodeDef;
+
+ /** @internal The list of all active filters */
+ @Input()
+ set activeFilters(filters: any[][]) {
+ this._activeFilterPaths = buildIdPathsFromFilters(filters || []);
+ this._changeDetectorRef.markForCheck();
+ }
+
+ /** @internal Emits a new action that changes the filter */
+ @Output() readonly filterChange = new EventEmitter();
+
+ /** A list of active filter ids */
+ private _activeFilterPaths: string[] = [];
+
+ constructor(private _changeDetectorRef: ChangeDetectorRef) {}
+
+ _unsetGroup(): void {
+ this.filterChange.emit(unsetFilterGroup(this._nodeDef));
+ }
+
+ /** @internal Updates a radio box */
+ _selectOption(change: DtRadioChange): void {
+ if (change.value) {
+ this.filterChange.emit(updateFilter(change.value));
+ }
+ }
+
+ /** @internal Select or de select a checkbox */
+ _selectCheckBox(change: DtCheckboxChange): void {
+ const action = change.checked
+ ? addFilter(change.source.value)
+ : removeFilter(change.source.value);
+ this.filterChange.emit(action);
+ }
+
+ /** @internal Helper function that checks if nothing is selected inside a group */
+ _isNothingSelected(): boolean {
+ if (this._nodeDef.option && this._nodeDef.option.uid) {
+ const index = this._activeFilterPaths.findIndex(path =>
+ path.startsWith(this._nodeDef.option!.uid!),
+ );
+ return index === -1;
+ }
+ return false;
+ }
+
+ /** @internal Helper function that checks if an options is active */
+ _isActive(node: DtNodeDef): boolean {
+ return !!(
+ node.option && this._activeFilterPaths.includes(node.option.uid || '')
+ );
+ }
+
+ /**
+ * @internal
+ * Helper function that checks if the nodeDef of the autocomplete is distinct.
+ * Needed to differentiate between radios or checkboxes.
+ */
+ _isDistinct(): boolean {
+ return !!(
+ this._nodeDef.autocomplete && this._nodeDef.autocomplete.distinct
+ );
+ }
+
+ /** @internal Helper function that returns safely the viewValue of a nodeDef */
+ _getViewValue(nodeDef: DtNodeDef): string {
+ return nodeDef && nodeDef.option ? nodeDef.option.viewValue : '';
+ }
+
+ /**
+ * @internal
+ * Helper function that returns all options that can be displayed.
+ * They can only be displayed if it is an option of an autocomplete that
+ * is not a render type so only have a text.
+ */
+ _getOptions(): DtNodeDef[] {
+ if (this._nodeDef && this._nodeDef.autocomplete) {
+ return this._nodeDef.autocomplete.optionsOrGroups.filter(
+ def => isDtOptionDef(def) && !isDtRenderType(def),
+ );
+ }
+ return [];
+ }
+}
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
new file mode 100644
index 0000000000..35a931723e
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/src/quick-filter-utils.ts
@@ -0,0 +1,26 @@
+/**
+ * @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 { DELIMITER } from '../../../filter-field/src/filter-field-util';
+
+export function buildIdPathsFromFilters(filters: any[][]): string[] {
+ return filters.map(path =>
+ path.reduce(
+ (previousValue, currentValue) =>
+ `${previousValue.name}${DELIMITER}${currentValue.name}${DELIMITER}`,
+ ),
+ );
+}
diff --git a/libs/barista-components/experimental/quick-filter/src/quick-filter.html b/libs/barista-components/experimental/quick-filter/src/quick-filter.html
new file mode 100644
index 0000000000..0d9fb95939
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/src/quick-filter.html
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/barista-components/experimental/quick-filter/src/quick-filter.module.ts b/libs/barista-components/experimental/quick-filter/src/quick-filter.module.ts
new file mode 100644
index 0000000000..baaa361c34
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/src/quick-filter.module.ts
@@ -0,0 +1,43 @@
+/**
+ * @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 { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { DtCheckboxModule } from '@dynatrace/barista-components/checkbox';
+import { DtDrawerModule } from '@dynatrace/barista-components/drawer';
+import { DtFilterFieldModule } from '@dynatrace/barista-components/filter-field';
+import { DtRadioModule } from '@dynatrace/barista-components/radio';
+import {
+ DtQuckFilterSubTitle,
+ DtQuckFilterTitle,
+ DtQuickFilter,
+} from './quick-filter';
+import { DtQuickFilterGroup } from './quick-filter-group';
+
+const COMPONENTS = [DtQuickFilter, DtQuckFilterSubTitle, DtQuckFilterTitle];
+
+@NgModule({
+ imports: [
+ CommonModule,
+ DtDrawerModule,
+ DtFilterFieldModule,
+ DtCheckboxModule,
+ DtRadioModule,
+ ],
+ exports: COMPONENTS,
+ declarations: [...COMPONENTS, DtQuickFilterGroup],
+})
+export class DtQuickFilterModule {}
diff --git a/libs/barista-components/experimental/quick-filter/src/quick-filter.scss b/libs/barista-components/experimental/quick-filter/src/quick-filter.scss
new file mode 100644
index 0000000000..6ef02c51bd
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/src/quick-filter.scss
@@ -0,0 +1,67 @@
+@import '../../../core/src/style/variables';
+@import '../../../core/src/style/interactive-common';
+
+:host {
+ display: block;
+ background-color: $gray-130;
+ padding: 20px;
+}
+
+.dt-quick-filter-drawer {
+ margin-top: 12px;
+}
+
+.dt-quick-filter-content {
+ position: relative;
+ display: block;
+ padding: 12px 12px 12px 26px;
+ height: 100%;
+ background-color: white;
+ border-radius: 3px;
+}
+
+.dt-drawer {
+ background-color: $gray-130;
+ position: relative;
+ padding-right: 26px;
+}
+
+.dt-quick-filter-title {
+ font-size: 20px;
+ color: $gray-700;
+ margin: 0;
+}
+
+.dt-quick-filter-sub-title {
+ font-size: 12px;
+ color: $gray-500;
+ margin: 0;
+}
+
+.dt-quick-filter-group + .dt-quick-filter-group {
+ border-top: 1px solid $gray-200;
+}
+
+.dt-quick-filter-open,
+.dt-quick-filter-close {
+ top: 8px;
+ background: white;
+ border-radius: 3px;
+ position: absolute;
+ color: $turquoise-600;
+ font-size: 1.2em;
+ cursor: pointer;
+}
+
+.dt-quick-filter-open {
+ left: -4px;
+ padding: 6px 6px 6px 0;
+ border-left: none;
+ background-color: $gray-130;
+}
+
+.dt-quick-filter-close {
+ right: -2px;
+ padding: 6px 0 6px 6px;
+ border-right: none;
+}
diff --git a/libs/barista-components/experimental/quick-filter/src/quick-filter.spec.ts b/libs/barista-components/experimental/quick-filter/src/quick-filter.spec.ts
new file mode 100644
index 0000000000..9060e7731a
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/src/quick-filter.spec.ts
@@ -0,0 +1,165 @@
+/**
+ * @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.
+ */
+
+// tslint:disable no-lifecycle-call no-use-before-declare no-magic-numbers
+// tslint:disable no-any max-file-line-count no-unbound-method use-component-selector
+
+import { Component, DebugElement } from '@angular/core';
+import { NoopAnimationsModule } from '@angular/platform-browser/animations';
+import { TestBed, ComponentFixture } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
+
+import {
+ DtQuickFilter,
+ DtQuickFilterModule,
+} from '@dynatrace/barista-components/experimental/quick-filter';
+
+import {
+ mockIconTestingModule,
+ createComponent,
+} from '@dynatrace/testing/browser';
+import { DtFilterFieldDefaultDataSource } from '@dynatrace/barista-components/filter-field';
+
+describe('dt-quick-filter', () => {
+ let instanceDebugElement: DebugElement;
+ let quickFilterInstance: DtQuickFilter;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ DtQuickFilterModule,
+ NoopAnimationsModule,
+ mockIconTestingModule(),
+ ],
+ declarations: [QuickFilterSimpleComponent, QuickFilterDefaultComponent],
+ });
+ TestBed.compileComponents();
+ });
+
+ describe('Simple QuickFilter without dataSource', () => {
+ let fixture: ComponentFixture;
+ beforeEach(() => {
+ fixture = createComponent(QuickFilterSimpleComponent);
+ instanceDebugElement = fixture.debugElement.query(
+ By.directive(DtQuickFilter),
+ );
+ quickFilterInstance = instanceDebugElement.injector.get(
+ DtQuickFilter,
+ );
+ });
+
+ it('should have an empty filters array if no dataSource is set', () => {
+ expect(quickFilterInstance.filters).toHaveLength(0);
+ });
+ });
+
+ describe('Normal QuickFilter with mixed dataSource', () => {
+ let fixture: ComponentFixture;
+ // let filterFieldDebugElement: DebugElement;
+ // let filterFieldInstance: DtFilterField;
+ beforeEach(() => {
+ fixture = createComponent(QuickFilterDefaultComponent);
+ instanceDebugElement = fixture.debugElement.query(
+ By.directive(DtQuickFilter),
+ );
+ quickFilterInstance = instanceDebugElement.injector.get(
+ DtQuickFilter,
+ );
+
+ // filterFieldDebugElement = fixture.debugElement.query(
+ // By.directive(DtFilterField),
+ // );
+ // filterFieldInstance = filterFieldDebugElement.injector.get(
+ // DtFilterField,
+ // );
+ });
+
+ it('should have an empty filters array if no dataSource is set', () => {
+ expect(quickFilterInstance.filters).toHaveLength(0);
+ quickFilterInstance.filters = [
+ [DATA.autocomplete[0], DATA.autocomplete[0].autocomplete![0]],
+ ];
+
+ fixture.detectChanges();
+
+ // expect(filterFieldDebugElement).toMatchSnapshot();
+ });
+ });
+});
+
+@Component({
+ selector: 'dt-quick-filter-simple',
+ template: `
+
+ `,
+})
+class QuickFilterSimpleComponent {}
+
+@Component({
+ selector: 'dt-quick-filter-simple',
+ template: `
+
+ Quick-filter
+
+ All options in the filter field above
+
+
+ my content
+
+ `,
+})
+class QuickFilterDefaultComponent {
+ _dataSource = new DtFilterFieldDefaultDataSource(DATA);
+}
+
+const DATA = {
+ autocomplete: [
+ {
+ name: 'AUT',
+ distinct: true,
+ autocomplete: [{ name: 'Linz' }, { name: 'Vienna' }, { name: 'Graz' }],
+ },
+ {
+ name: 'USA',
+ autocomplete: [
+ { name: 'San Francisco' },
+ { name: 'Los Angeles' },
+ { name: 'New York' },
+ { name: 'Custom', suggestions: [] },
+ ],
+ },
+ {
+ name: 'Requests per minute',
+ range: {
+ operators: {
+ range: true,
+ equal: true,
+ greaterThanEqual: true,
+ lessThanEqual: true,
+ },
+ unit: 's',
+ },
+ },
+ {
+ name: 'Not in Quickfilter',
+ autocomplete: [
+ { name: 'Option1' },
+ { name: 'Option2' },
+ { name: 'Option3' },
+ ],
+ },
+ ],
+};
diff --git a/libs/barista-components/experimental/quick-filter/src/quick-filter.ts b/libs/barista-components/experimental/quick-filter/src/quick-filter.ts
new file mode 100644
index 0000000000..d6af66cc0c
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/src/quick-filter.ts
@@ -0,0 +1,131 @@
+/**
+ * @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 {
+ AfterViewInit,
+ ChangeDetectionStrategy,
+ Component,
+ Directive,
+ EventEmitter,
+ Input,
+ OnDestroy,
+ Output,
+ ViewChild,
+ ViewEncapsulation,
+} from '@angular/core';
+import {
+ DtFilterField,
+ DtFilterFieldChangeEvent,
+} from '@dynatrace/barista-components/filter-field';
+import { Subject } from 'rxjs';
+import { takeUntil } from 'rxjs/operators';
+import { DtQuickFilterDataSource } from './quick-filter-data-source';
+import { Action, setFilters, switchDataSource } from './state/actions';
+import { quickFilterReducer } from './state/reducer';
+import { getAutocompletes, getDataSource, getFilters } from './state/selectors';
+import { createQuickFilterStore } from './state/store';
+
+@Directive({
+ selector: 'dt-quick-filter-title',
+ exportAs: 'dtQuickFilterTitle',
+ host: {
+ class: 'dt-quick-filter-title',
+ },
+})
+export class DtQuckFilterTitle {}
+
+@Directive({
+ selector: 'dt-quick-filter-sub-title',
+ exportAs: 'dtQuickFilterSubTitle',
+ host: {
+ class: 'dt-quick-filter-sub-title',
+ },
+})
+export class DtQuckFilterSubTitle {}
+
+@Component({
+ selector: 'dt-quick-filter',
+ exportAs: 'dtQuickFilter',
+ templateUrl: 'quick-filter.html',
+ styleUrls: ['quick-filter.scss'],
+ host: {
+ class: 'dt-quick-filter',
+ },
+ preserveWhitespaces: false,
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ encapsulation: ViewEncapsulation.Emulated,
+})
+export class DtQuickFilter implements AfterViewInit, OnDestroy {
+ /** Emits when a new filter has been added or removed. */
+ @Output() readonly filterChanges = new EventEmitter<
+ DtFilterFieldChangeEvent
+ >();
+
+ /** instance of the filter field that will be orchestrated by the quick filter */
+ @ViewChild(DtFilterField, { static: true })
+ private _filterField: DtFilterField;
+
+ /** The data source instance that should be connected to the filter field. */
+ @Input()
+ set dataSource(dataSource: DtQuickFilterDataSource) {
+ this._store.dispatch(switchDataSource(dataSource));
+ }
+
+ /** The currently applied filters */
+ @Input()
+ get filters(): T[][] {
+ return this._filterField.filters;
+ }
+ set filters(filters: T[][]) {
+ this._store.dispatch(setFilters(filters));
+ }
+
+ /** The store where the data flow is managed */
+ private _store = createQuickFilterStore(quickFilterReducer);
+
+ /** @internal the autocomplete fields that should be rendered by the quick filter */
+ readonly _autocompleteData$ = this._store.select(getAutocompletes);
+ /** @internal the dataSource that gets passed to the filter field */
+ readonly _filterFieldDataSource$ = this._store.select(getDataSource);
+ /** @internal the list of all current active filters */
+ readonly _activeFilters$ = this._store.select(getFilters);
+
+ private _destroy$ = new Subject();
+
+ ngAfterViewInit(): void {
+ // When the filters changes apply them to the filter field
+ this._activeFilters$.pipe(takeUntil(this._destroy$)).subscribe(filters => {
+ if (this._filterField.filters !== filters) {
+ this._filterField.filters = filters;
+ }
+ });
+ }
+
+ ngOnDestroy(): void {
+ this._destroy$.next();
+ this._destroy$.complete();
+ }
+
+ _changeFilter(action: Action): void {
+ this._store.dispatch(action);
+ }
+
+ /** @internal Bubble the filter field change event through */
+ _filterFiledChanged(change: DtFilterFieldChangeEvent): void {
+ this._store.dispatch(setFilters(change.filters));
+ 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
new file mode 100644
index 0000000000..eaaef35e37
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/src/state/actions.ts
@@ -0,0 +1,62 @@
+/**
+ * @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 {
+ DtNodeDef,
+ DtFilterFieldDataSource,
+} from '@dynatrace/barista-components/filter-field';
+
+export enum ActionType {
+ INIT = '@@actions init',
+ ADD_FILTER = '@@actions add filter',
+ REMOVE_FILTER = '@@actions remove filter',
+ UPDATE_FILTER = '@@actions update filter',
+ SET_FILTERS = '@@actions set filters',
+ UNSET_FILTER_GROUP = '@@actions unset filter group',
+ SWITCH_DATA_SOURCE = '@@actions switch dataSource',
+ UPDATE_DATA_SOURCE = '@@actions update dataSource',
+}
+
+/** Interface for an action */
+export interface Action {
+ readonly type: ActionType;
+ payload?: T;
+}
+/** Function which helps to create actions without mistakes */
+export const action = (type: ActionType, payload?: T): Action => ({
+ type,
+ payload,
+});
+
+export const setFilters = (filters: any[][]) =>
+ action(ActionType.SET_FILTERS, filters);
+
+export const unsetFilterGroup = (group: DtNodeDef) =>
+ action(ActionType.UNSET_FILTER_GROUP, group);
+
+export const addFilter = (item: DtNodeDef) =>
+ action(ActionType.ADD_FILTER, item);
+
+export const removeFilter = (item: DtNodeDef) =>
+ action(ActionType.REMOVE_FILTER, item);
+
+export const updateFilter = (item: DtNodeDef) =>
+ action(ActionType.UPDATE_FILTER, item);
+
+export const switchDataSource = (item: DtFilterFieldDataSource) =>
+ action(ActionType.SWITCH_DATA_SOURCE, item);
+
+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
new file mode 100644
index 0000000000..b4a72725d1
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/src/state/effects.ts
@@ -0,0 +1,43 @@
+/**
+ * @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 { MonoTypeOperatorFunction, Observable } from 'rxjs';
+import { filter, switchMap, map } from 'rxjs/operators';
+import { DtFilterFieldDataSource, DtNodeDef } from '../../../../filter-field';
+import { Action, ActionType, updateDataSource } from './actions';
+import { QuickFilterState } from './store';
+
+/** Type for an effect */
+export type Effect = (
+ action$: Observable,
+ state$?: Observable,
+) => Observable;
+
+/** Operator to filter actions */
+export const ofType = (
+ ...types: ActionType[]
+): MonoTypeOperatorFunction> =>
+ filter((action: Action) => types.indexOf(action.type) > -1);
+
+/** Connects to a new Data dataSource */
+export const switchDataSourceEffect: Effect = (action$: Observable) =>
+ action$.pipe(
+ ofType(ActionType.SWITCH_DATA_SOURCE),
+ switchMap(action => {
+ return action.payload!.connect();
+ }),
+ 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
new file mode 100644
index 0000000000..4e0c264fb9
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/src/state/reducer.spec.ts
@@ -0,0 +1,54 @@
+/**
+ * @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.
+ */
+
+describe('QuickFilter Reducer', () => {
+ test('', () => {});
+});
+
+// import { dtAutocompleteDef } from '@dynatrace/barista-components/filter-field';
+
+// const createDistinctNode = dtAutocompleteDef(
+// data,
+// null,
+// [],
+// !!data.distinct,
+// !!data.async,
+// );
+
+// const createOption = dtOptionDef(
+// data,
+// existingDef,
+// data.name,
+// null,
+// parentAutocomplete,
+// parentGroup,
+// );
+
+// /** Transforms the provided data into a DtNodeDef which contains a DtOptionDef. */
+// transformOption(
+// data: DtFilterFieldDefaultDataSourceOption,
+// parentAutocompleteOrOption: DtNodeDef | null = null,
+// existingDef: DtNodeDef | null = null,
+// ): DtNodeDef {
+// const parentGroup = isDtGroupDef(parentAutocompleteOrOption)
+// ? parentAutocompleteOrOption
+// : null;
+// const parentAutocomplete =
+// parentGroup !== null
+// ? parentGroup.group.parentAutocomplete
+// : isDtAutocompleteDef(parentAutocompleteOrOption)
+// ? (parentAutocompleteOrOption as DtNodeDef)
+// : null;
diff --git a/libs/barista-components/experimental/quick-filter/src/state/reducer.ts b/libs/barista-components/experimental/quick-filter/src/state/reducer.ts
new file mode 100644
index 0000000000..2c8db19e53
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/src/state/reducer.ts
@@ -0,0 +1,154 @@
+/**
+ * @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 {
+ DtNodeDef,
+ DELIMITER,
+} from '@dynatrace/barista-components/filter-field';
+import { Action, ActionType } from './actions';
+import { QuickFilterState, initialState } from './store';
+
+/** @internal Type of a reducer */
+export type Reducer = (
+ state: QuickFilterState,
+ action: Action,
+) => QuickFilterState;
+
+/**
+ * @internal
+ * The Quick Filter reducer is the place where we handle all the state updates
+ * To have a single entry point. Every action can trigger an update of the state.
+ * It has to be a immutable function that always returns a new object of the state.
+ * @param state The state that should be modified.
+ * @param action The current action that should be handled.
+ */
+export function quickFilterReducer(
+ state: QuickFilterState,
+ action: Action,
+): QuickFilterState {
+ console.info(
+ `%c Reducer <${action.type}> `,
+ ' background-color: lightblue; color: black; font-size: 1.2em; padding: 5px; border-radius: 1em',
+ action,
+ );
+
+ switch (action.type) {
+ case ActionType.SWITCH_DATA_SOURCE:
+ if (state.dataSource) {
+ state.dataSource.disconnect();
+ }
+ return { ...initialState, dataSource: action.payload };
+ case ActionType.UPDATE_DATA_SOURCE:
+ return { ...state, nodeDef: action.payload };
+ case ActionType.SET_FILTERS:
+ return { ...state, filters: action.payload };
+ case ActionType.UNSET_FILTER_GROUP:
+ return {
+ ...state,
+ filters: unsetFilterGroup(state.filters, action.payload),
+ };
+ case ActionType.ADD_FILTER:
+ return { ...state, filters: addFilter(state.filters, action.payload) };
+ case ActionType.UPDATE_FILTER:
+ return { ...state, filters: updateFilter(state.filters, action.payload) };
+ case ActionType.REMOVE_FILTER:
+ return { ...state, filters: removeFilter(state.filters, action.payload) };
+ default:
+ // Default return the same state as it was passed so don't modify anything
+ return state;
+ }
+}
+
+// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+// #
+// # HELPER functions for modifying the filters
+// #
+// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+/** @internal Add a filter to the filters array */
+export function addFilter(filters: any[][], item: DtNodeDef): any[][] {
+ return [...filters, buildData(item)];
+}
+
+/** @internal Remove a filter from the filters array */
+export function removeFilter(filters: any[][], item: DtNodeDef): any[][] {
+ const index = findSelectedOption(filters, item, false);
+ const updatedState = [...filters];
+
+ if (index > -1) {
+ delete updatedState[index];
+ }
+
+ return updatedState.filter(Boolean);
+}
+
+/** @internal Update a filter inside the filters array */
+export function updateFilter(filters: any[][], item: DtNodeDef): any[][] {
+ const index = findSelectedOption(filters, item, true);
+
+ if (index < 0) {
+ return addFilter(filters, item);
+ }
+
+ filters[index] = buildData(item);
+
+ 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 Add a filter to the filters array */
+export function buildData(item: DtNodeDef): any[] {
+ const data = [item.data];
+
+ if (item.option && item.option.parentAutocomplete) {
+ data.unshift(item.option.parentAutocomplete.data);
+ }
+ return data;
+}
+
+/** @internal Find a filter inside the filters array based on a NodeDef */
+export function findSelectedOption(
+ filters: any[][],
+ item: DtNodeDef,
+ distinct: boolean = false,
+): number {
+ return filters.findIndex(path => {
+ if (item.option && item.option.uid) {
+ const parts = item.option.uid.split(DELIMITER);
+
+ if (distinct && parts[0] === path[0].name) {
+ return true;
+ }
+
+ const dataPath = path.reduce(
+ (previousValue, currentValue) =>
+ `${previousValue.name}${DELIMITER}${currentValue.name}${DELIMITER}`,
+ );
+
+ if (item.option.uid === dataPath) {
+ return true;
+ }
+ }
+
+ return false;
+ });
+}
diff --git a/libs/barista-components/experimental/quick-filter/src/state/selectors.ts b/libs/barista-components/experimental/quick-filter/src/state/selectors.ts
new file mode 100644
index 0000000000..8401daca02
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/src/state/selectors.ts
@@ -0,0 +1,53 @@
+/**
+ * @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 {
+ applyDtOptionIds,
+ DtNodeDef,
+ isDtAutocompleteDef,
+} from '@dynatrace/barista-components/filter-field';
+import { Observable } from 'rxjs';
+import { filter, map, pluck, tap, withLatestFrom } from 'rxjs/operators';
+import { QuickFilterState } from './store';
+import { DtQuickFilterDataSource } from '../quick-filter-data-source';
+
+/** @internal Select all autocompletes from the root Node Def out of the store */
+export const getAutocompletes = (
+ state$: Observable,
+): Observable =>
+ state$.pipe(
+ tap(state => {
+ // apply the ids to the node to identify them later on
+ if (state.nodeDef) {
+ applyDtOptionIds(state.nodeDef);
+ }
+ }),
+ pluck('nodeDef'),
+ filter(isDtAutocompleteDef),
+ withLatestFrom(getDataSource(state$)),
+ map(([{ autocomplete }, { showInSidebarFunction }]) =>
+ autocomplete.optionsOrGroups.filter(
+ node => isDtAutocompleteDef(node) && showInSidebarFunction(node.data),
+ ),
+ ),
+ );
+
+/** @internal Select the data Source from the store */
+export const getDataSource = (state$: Observable) =>
+ state$.pipe(pluck('dataSource'), filter(Boolean));
+
+/** @internal Select the actual applied filters */
+export const getFilters = (state$: Observable) =>
+ state$.pipe(pluck('filters'));
diff --git a/libs/barista-components/experimental/quick-filter/src/state/store.ts b/libs/barista-components/experimental/quick-filter/src/state/store.ts
new file mode 100644
index 0000000000..e5fc193d07
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/src/state/store.ts
@@ -0,0 +1,106 @@
+/**
+ * @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 { Observable, merge, BehaviorSubject } from 'rxjs';
+import { shareReplay, map, withLatestFrom } from 'rxjs/operators';
+import { Reducer } from './reducer';
+import { Action, ActionType } from './actions';
+import { Effect, switchDataSourceEffect } from './effects';
+import { DtNodeDef } from '@dynatrace/barista-components/filter-field';
+import { DtQuickFilterDataSource } from '../quick-filter-data-source';
+
+/** @internal Interface that describes the QuickFilter state */
+export interface QuickFilterState {
+ /** The root NodeDef of the dataSource */
+ nodeDef?: DtNodeDef;
+ /** The dataSource that is connected with the QuickFilter */
+ dataSource?: DtQuickFilterDataSource;
+ /** Array of all active filters */
+ filters: any[][];
+}
+
+/** @internal The initial QuickFilter state */
+export const initialState: QuickFilterState = {
+ filters: [],
+};
+
+/** Array of side effects */
+const effects: Effect[] = [switchDataSourceEffect];
+
+/**
+ * The Quick Filter Store is one place where the state is handled.
+ * It is a minimal implementation of a redux like architecture to handle
+ * state in an immutable and on-directional way.
+ *
+ * This makes testing and debugging way easier, because there is always a
+ * clear state that can only be modified through actions.
+ *
+ * 1. Action gets dispatched (An action indicates a change in the store)
+ * 2. The reducer gets an action and the current state and according to the action
+ * modifies the state.
+ * 3. A Selector can always read the latest value from the store and displays it in
+ * a template. So the only way to modify the state is dispatching an action.
+ * 4. If some async work has to be done the effect is responsible for that.
+ * Effects are listening for actions then doing some async work and dispatching some
+ * Other actions with the payload of the async stuff.
+ */
+class QuickFilterStore {
+ /** The current action that got dispatched */
+ private readonly action$ = new BehaviorSubject({
+ type: ActionType.INIT,
+ });
+
+ /** The current state that is present */
+ private readonly state$: BehaviorSubject;
+
+ constructor(reducer: Reducer, initialStoreState: QuickFilterState) {
+ this.state$ = new BehaviorSubject(initialStoreState);
+
+ this.action$
+ .pipe(
+ shareReplay(),
+ withLatestFrom(this.state$),
+ map(([action, state]) => reducer(state, action)),
+ )
+ .subscribe(state => {
+ // Here the state gets modified through the outcome of the reducer
+ this.state$.next(state);
+ });
+
+ // Each effect will get the stream of actions and will dispatch other actions in return
+ // The emitted actions will be immediately dispatched through the normal store.dispatch()
+ merge(...effects.map(epic => epic(this.action$, this.state$))).subscribe(
+ (action: Action) => {
+ this.dispatch(action);
+ },
+ );
+ }
+
+ /** Dispatch a new Action that modifies the store */
+ dispatch(action: Action): void {
+ this.action$.next(action);
+ }
+
+ /** Use a provided selector function to get a State out of the store */
+ select(selector: (state$: Observable) => T): T {
+ return selector(this.state$);
+ }
+}
+
+/** @internal This function creates the store for the quick filter */
+export function createQuickFilterStore(reducer: Reducer): QuickFilterStore {
+ return new QuickFilterStore(reducer, initialState);
+}
diff --git a/libs/barista-components/experimental/quick-filter/src/test-setup.ts b/libs/barista-components/experimental/quick-filter/src/test-setup.ts
new file mode 100644
index 0000000000..3c66e43d72
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/src/test-setup.ts
@@ -0,0 +1,17 @@
+/**
+ * @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 'jest-preset-angular';
diff --git a/libs/barista-components/experimental/quick-filter/tsconfig.json b/libs/barista-components/experimental/quick-filter/tsconfig.json
new file mode 100644
index 0000000000..a6233e13a0
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "extends": "../../../../tsconfig.json",
+ "compilerOptions": {
+ "types": ["node", "jest"]
+ },
+ "include": ["**/*.ts"]
+}
diff --git a/libs/barista-components/experimental/quick-filter/tsconfig.lib.json b/libs/barista-components/experimental/quick-filter/tsconfig.lib.json
new file mode 100644
index 0000000000..b639cbf40a
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/tsconfig.lib.json
@@ -0,0 +1,20 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../../../../dist/out-tsc",
+ "target": "es2015",
+ "declaration": true,
+ "inlineSources": true,
+ "types": [],
+ "lib": ["dom", "es2018"]
+ },
+ "angularCompilerOptions": {
+ "annotateForClosureCompiler": true,
+ "skipTemplateCodegen": true,
+ "strictMetadataEmit": true,
+ "fullTemplateTypeCheck": true,
+ "strictInjectionParameters": true,
+ "enableResourceInlining": true
+ },
+ "exclude": ["src/test-setup.ts", "**/*.spec.ts"]
+}
diff --git a/libs/barista-components/experimental/quick-filter/tsconfig.spec.json b/libs/barista-components/experimental/quick-filter/tsconfig.spec.json
new file mode 100644
index 0000000000..aed68bc6bf
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/tsconfig.spec.json
@@ -0,0 +1,10 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../../../../dist/out-tsc",
+ "module": "commonjs",
+ "types": ["jest", "node"]
+ },
+ "files": ["src/test-setup.ts"],
+ "include": ["**/*.spec.ts", "**/*.d.ts"]
+}
diff --git a/libs/barista-components/experimental/quick-filter/tslint.json b/libs/barista-components/experimental/quick-filter/tslint.json
new file mode 100644
index 0000000000..b20a356378
--- /dev/null
+++ b/libs/barista-components/experimental/quick-filter/tslint.json
@@ -0,0 +1,4 @@
+{
+ "extends": "../../../../tslint.json",
+ "rules": {}
+}
diff --git a/libs/barista-components/filter-field/index.ts b/libs/barista-components/filter-field/index.ts
index 4f9b0f832f..30986293e2 100644
--- a/libs/barista-components/filter-field/index.ts
+++ b/libs/barista-components/filter-field/index.ts
@@ -22,7 +22,7 @@ export * from './src/filter-field-range/filter-field-range-trigger';
export * from './src/filter-field-data-source';
export * from './src/filter-field-default-data-source';
export * from './src/filter-field-errors';
-
+export { applyDtOptionIds, DELIMITER } from './src/filter-field-util';
export {
DtNodeFlags,
DtNodeDef,
@@ -43,4 +43,5 @@ export {
isDtOptionDef,
dtGroupDef,
isDtGroupDef,
+ isDtRenderType,
} from './src/types';
diff --git a/libs/barista-components/filter-field/src/filter-field.ts b/libs/barista-components/filter-field/src/filter-field.ts
index 92b05d169a..657ef6a085 100644
--- a/libs/barista-components/filter-field/src/filter-field.ts
+++ b/libs/barista-components/filter-field/src/filter-field.ts
@@ -177,7 +177,7 @@ export const DT_FILTER_FIELD_TYPING_DEBOUNCE = 200;
]),
],
})
-export class DtFilterField
+export class DtFilterField
implements CanDisable, AfterViewInit, OnDestroy, OnChanges {
/** Label for the filter field (e.g. "Filter by"). Will be placed next to the filter icon. */
@Input() label = '';
diff --git a/libs/examples/src/examples.module.ts b/libs/examples/src/examples.module.ts
index 46fd9a7118..848e5503c5 100644
--- a/libs/examples/src/examples.module.ts
+++ b/libs/examples/src/examples.module.ts
@@ -60,6 +60,7 @@ import { DtOverlayExamplesModule } from './overlay/overlay-examples.module';
import { DtPaginationExamplesModule } from './pagination/pagination-examples.module';
import { DtProgressBarExamplesModule } from './progress-bar/progress-bar-examples.module';
import { DtProgressCircleExamplesModule } from './progress-circle/progress-circle-examples.module';
+import { DtQuickFilterExamplesModule } from './quick-filter/quick-filter-examples.module';
import { DtRadialChartExamplesModule } from './radial-chart/radial-chart-examples.module';
import { DtRadioExamplesModule } from './radio/radio-examples.module';
import { DtExamplesSecondaryNAvModule } from './secondary-nav/secondary-nav-examples.module';
@@ -122,6 +123,7 @@ import { DtExamplesTreeTableModule } from './tree-table/tree-table-examples.modu
DtPaginationExamplesModule,
DtProgressBarExamplesModule,
DtProgressCircleExamplesModule,
+ DtQuickFilterExamplesModule,
DtRadialChartExamplesModule,
DtRadioExamplesModule,
DtExamplesSecondaryNAvModule,
@@ -138,7 +140,7 @@ import { DtExamplesTreeTableModule } from './tree-table/tree-table-examples.modu
DtToastExamplesModule,
DtToggleButtonGroupExamplesModule,
DtExamplesTopBarNavigationModule,
- DtExamplesTreeTableModule,
- ],
+ DtExamplesTreeTableModule
+ ]
})
-export class DtExamplesModule {}
+export class DtExamplesModule { }
diff --git a/libs/examples/src/index.ts b/libs/examples/src/index.ts
index 759773ae32..77d9d1ad5e 100644
--- a/libs/examples/src/index.ts
+++ b/libs/examples/src/index.ts
@@ -115,7 +115,7 @@ import { DtExampleDrawerNested } from './drawer/drawer-nested-example/drawer-nes
import { DtExampleDrawerOver } from './drawer/drawer-over-example/drawer-over-example';
import {
DtExampleCustomEmptyStateTable,
- DtExampleCustomEmptyState,
+ DtExampleCustomEmptyState
} from './empty-state/empty-state-custom-empty-state-table-example/empty-state-custom-empty-state-table-example';
import { DtExampleEmptyStateDefault } from './empty-state/empty-state-default-example/empty-state-default-example';
import { DtExampleEmptyStateInCard } from './empty-state/empty-state-in-card-example/empty-state-in-card-example';
@@ -221,6 +221,7 @@ import { DtExampleProgressCircleDefault } from './progress-circle/progress-circl
import { DtExampleProgressCircleWithColor } from './progress-circle/progress-circle-with-color-example/progress-circle-with-color-example';
import { DtExampleProgressCircleWithIcon } from './progress-circle/progress-circle-with-icon-example/progress-circle-with-icon-example';
import { DtExampleProgressCircleWithText } from './progress-circle/progress-circle-with-text-example/progress-circle-with-text-example';
+import { DtExampleQuickFilterDefault } from './quick-filter/quick-filter-default-example/quick-filter-default-example';
import { DtExampleRadialChartCustomColors } from './radial-chart/radial-chart-custom-colors-example/radial-chart-custom-colors-example';
import { DtExampleRadialChartDefaultDonut } from './radial-chart/radial-chart-default-donut-example/radial-chart-default-donut-example';
import { DtExampleRadialChartDefaultPie } from './radial-chart/radial-chart-default-pie-example/radial-chart-default-pie-example';
@@ -347,6 +348,7 @@ export { DtOverlayExamplesModule } from './overlay/overlay-examples.module';
export { DtPaginationExamplesModule } from './pagination/pagination-examples.module';
export { DtProgressBarExamplesModule } from './progress-bar/progress-bar-examples.module';
export { DtProgressCircleExamplesModule } from './progress-circle/progress-circle-examples.module';
+export { DtQuickFilterExamplesModule } from './quick-filter/quick-filter-examples.module';
export { DtRadialChartExamplesModule } from './radial-chart/radial-chart-examples.module';
export { DtRadioExamplesModule } from './radio/radio-examples.module';
export { DtExamplesSecondaryNAvModule } from './secondary-nav/secondary-nav-examples.module';
@@ -562,6 +564,7 @@ export {
DtExampleProgressCircleWithColor,
DtExampleProgressCircleWithIcon,
DtExampleProgressCircleWithText,
+ DtExampleQuickFilterDefault,
DtExampleRadialChartCustomColors,
DtExampleRadialChartDefaultDonut,
DtExampleRadialChartDefaultPie,
@@ -646,7 +649,7 @@ export {
DtExampleTreeTableAsyncShowMore,
DtExampleTreeTableDefault,
DtExampleTreeTableProblemIndicator,
- DtExampleTreeTableSimple,
+ DtExampleTreeTableSimple
};
export const EXAMPLES_MAP = new Map>([
@@ -655,18 +658,12 @@ export const EXAMPLES_MAP = new Map>([
['DtExampleAlertError', DtExampleAlertError],
['DtExampleAlertInteractive', DtExampleAlertInteractive],
['DtExampleAlertWarning', DtExampleAlertWarning],
- [
- 'DtExampleAutocompleteAttachDifferentElement',
- DtExampleAutocompleteAttachDifferentElement,
- ],
+ ['DtExampleAutocompleteAttachDifferentElement', DtExampleAutocompleteAttachDifferentElement],
['DtExampleAutocompleteControlValues', DtExampleAutocompleteControlValues],
['DtExampleAutocompleteCustomFilter', DtExampleAutocompleteCustomFilter],
['DtExampleAutocompleteDefault', DtExampleAutocompleteDefault],
['DtExampleAutocompleteGroups', DtExampleAutocompleteGroups],
- [
- 'DtExampleAutocompleteHighlightFirstOption',
- DtExampleAutocompleteHighlightFirstOption,
- ],
+ ['DtExampleAutocompleteHighlightFirstOption', DtExampleAutocompleteHighlightFirstOption],
['DtExampleBarIndicatorAlignment', DtExampleBarIndicatorAlignment],
['DtExampleBarIndicatorColor', DtExampleBarIndicatorColor],
['DtExampleBarIndicatorDefault', DtExampleBarIndicatorDefault],
@@ -719,25 +716,13 @@ export const EXAMPLES_MAP = new Map>([
['DtExampleCheckboxIndeterminate', DtExampleCheckboxIndeterminate],
['DtExampleCheckboxResponsive', DtExampleCheckboxResponsive],
['DtExampleConfirmationDialogDefault', DtExampleConfirmationDialogDefault],
- [
- 'DtExampleConfirmationDialogShowBackdrop',
- DtExampleConfirmationDialogShowBackdrop,
- ],
+ ['DtExampleConfirmationDialogShowBackdrop', DtExampleConfirmationDialogShowBackdrop],
['DtExampleConsumptionDefault', DtExampleConsumptionDefault],
['DtExampleConsumptionError', DtExampleConsumptionError],
['DtExampleConsumptionWarning', DtExampleConsumptionWarning],
- [
- 'DtExampleContainerBreakpointObserverDefault',
- DtExampleContainerBreakpointObserverDefault,
- ],
- [
- 'DtExampleContainerBreakpointObserverIfElse',
- DtExampleContainerBreakpointObserverIfElse,
- ],
- [
- 'DtExampleContainerBreakpointObserverIf',
- DtExampleContainerBreakpointObserverIf,
- ],
+ ['DtExampleContainerBreakpointObserverDefault', DtExampleContainerBreakpointObserverDefault],
+ ['DtExampleContainerBreakpointObserverIfElse', DtExampleContainerBreakpointObserverIfElse],
+ ['DtExampleContainerBreakpointObserverIf', DtExampleContainerBreakpointObserverIf],
['DtExampleContextDialogActions', DtExampleContextDialogActions],
['DtExampleContextDialogCustomIcon', DtExampleContextDialogCustomIcon],
['DtExampleContextDialogDark', DtExampleContextDialogDark],
@@ -751,10 +736,7 @@ export const EXAMPLES_MAP = new Map>([
['DtExampleCopyToClipboardDark', DtExampleCopyToClipboardDark],
['DtExampleCopyToClipboardDefault', DtExampleCopyToClipboardDefault],
['DtExampleCopyToClipboardError', DtExampleCopyToClipboardError],
- [
- 'DtExampleCopyToClipboardSecondaryButton',
- DtExampleCopyToClipboardSecondaryButton,
- ],
+ ['DtExampleCopyToClipboardSecondaryButton', DtExampleCopyToClipboardSecondaryButton],
['DtExampleCopyToClipboardTextarea', DtExampleCopyToClipboardTextarea],
['DtExampleCtaCardClosable', DtExampleCtaCardClosable],
['DtExampleCtaCardDefault', DtExampleCtaCardDefault],
@@ -767,10 +749,7 @@ export const EXAMPLES_MAP = new Map>([
['DtExampleEmptyStateDefault', DtExampleEmptyStateDefault],
['DtExampleEmptyStateInCard', DtExampleEmptyStateInCard],
['DtExampleEmptyStateMultipleItems', DtExampleEmptyStateMultipleItems],
- [
- 'DtExampleEmptyStateMultipleItemsInCard',
- DtExampleEmptyStateMultipleItemsInCard,
- ],
+ ['DtExampleEmptyStateMultipleItemsInCard', DtExampleEmptyStateMultipleItemsInCard],
['DtExampleEventChartComplexSelection', DtExampleEventChartComplexSelection],
['DtExampleEventChartCustomColor', DtExampleEventChartCustomColor],
['DtExampleEventChartDefault', DtExampleEventChartDefault],
@@ -781,21 +760,12 @@ export const EXAMPLES_MAP = new Map>([
['DtExampleEventChartSessionReplay', DtExampleEventChartSessionReplay],
['DtExampleExpandablePanelDefault', DtExampleExpandablePanelDefault],
['DtExampleExpandablePanelDisabled', DtExampleExpandablePanelDisabled],
- [
- 'DtExampleExpandablePanelDynamicTrigger',
- DtExampleExpandablePanelDynamicTrigger,
- ],
- [
- 'DtExampleExpandablePanelProgrammatic',
- DtExampleExpandablePanelProgrammatic,
- ],
+ ['DtExampleExpandablePanelDynamicTrigger', DtExampleExpandablePanelDynamicTrigger],
+ ['DtExampleExpandablePanelProgrammatic', DtExampleExpandablePanelProgrammatic],
['DtExampleExpandableSectionDark', DtExampleExpandableSectionDark],
['DtExampleExpandableSectionDefault', DtExampleExpandableSectionDefault],
['DtExampleExpandableSectionDisabled', DtExampleExpandableSectionDisabled],
- [
- 'DtExampleExpandableSectionInteractive',
- DtExampleExpandableSectionInteractive,
- ],
+ ['DtExampleExpandableSectionInteractive', DtExampleExpandableSectionInteractive],
['DtExampleExpandableSectionOpen', DtExampleExpandableSectionOpen],
['DtExampleExpandableTextDefault', DtExampleExpandableTextDefault],
['DtExampleFilterFieldAsync', DtExampleFilterFieldAsync],
@@ -803,17 +773,11 @@ export const EXAMPLES_MAP = new Map>([
['DtExampleFilterFieldDefault', DtExampleFilterFieldDefault],
['DtExampleFilterFieldDisabled', DtExampleFilterFieldDisabled],
['DtExampleFilterFieldDistinct', DtExampleFilterFieldDistinct],
- [
- 'DtExampleFilterFieldProgrammaticFilters',
- DtExampleFilterFieldProgrammaticFilters,
- ],
+ ['DtExampleFilterFieldProgrammaticFilters', DtExampleFilterFieldProgrammaticFilters],
['DtExampleFilterFieldReadOnlyTags', DtExampleFilterFieldReadOnlyTags],
['DtExampleFilterFieldUnique', DtExampleFilterFieldUnique],
['DtExampleFormFieldDefault', DtExampleFormFieldDefault],
- [
- 'DtExampleFormFieldErrorCustomValidator',
- DtExampleFormFieldErrorCustomValidator,
- ],
+ ['DtExampleFormFieldErrorCustomValidator', DtExampleFormFieldErrorCustomValidator],
['DtExampleFormFieldError', DtExampleFormFieldError],
['DtExampleFormFieldHint', DtExampleFormFieldHint],
['DtExampleFormFieldPrefixSuffix', DtExampleFormFieldPrefixSuffix],
@@ -860,10 +824,7 @@ export const EXAMPLES_MAP = new Map>([
['DtExampleMenuWithinContextDialog', DtExampleMenuWithinContextDialog],
['DtExampleMenuWithinDrawer', DtExampleMenuWithinDrawer],
['DtExampleMicroChartColumns', DtExampleMicroChartColumns],
- [
- 'DtExampleMicroChartColumnsInterpolated',
- DtExampleMicroChartColumnsInterpolated,
- ],
+ ['DtExampleMicroChartColumnsInterpolated', DtExampleMicroChartColumnsInterpolated],
['DtExampleMicroChartDefault', DtExampleMicroChartDefault],
['DtExampleMicroChartInterpolated', DtExampleMicroChartInterpolated],
['DtExampleMicroChartStream', DtExampleMicroChartStream],
@@ -880,14 +841,8 @@ export const EXAMPLES_MAP = new Map>([
['DtExampleProgressBarDefault', DtExampleProgressBarDefault],
['DtExampleProgressBarRightAligned', DtExampleProgressBarRightAligned],
['DtExampleProgressBarWithColor', DtExampleProgressBarWithColor],
- [
- 'DtExampleProgressBarWithCountAndDescription',
- DtExampleProgressBarWithCountAndDescription,
- ],
- [
- 'DtExampleProgressBarWithCountAndDescriptionIndicator',
- DtExampleProgressBarWithCountAndDescriptionIndicator,
- ],
+ ['DtExampleProgressBarWithCountAndDescription', DtExampleProgressBarWithCountAndDescription],
+ ['DtExampleProgressBarWithCountAndDescriptionIndicator', DtExampleProgressBarWithCountAndDescriptionIndicator],
['DtExampleProgressBarWithCount', DtExampleProgressBarWithCount],
['DtExampleProgressBarWithDescription', DtExampleProgressBarWithDescription],
['DtExampleProgressCircleChange', DtExampleProgressCircleChange],
@@ -895,6 +850,7 @@ export const EXAMPLES_MAP = new Map>([
['DtExampleProgressCircleWithColor', DtExampleProgressCircleWithColor],
['DtExampleProgressCircleWithIcon', DtExampleProgressCircleWithIcon],
['DtExampleProgressCircleWithText', DtExampleProgressCircleWithText],
+ ['DtExampleQuickFilterDefault', DtExampleQuickFilterDefault],
['DtExampleRadialChartCustomColors', DtExampleRadialChartCustomColors],
['DtExampleRadialChartDefaultDonut', DtExampleRadialChartDefaultDonut],
['DtExampleRadialChartDefaultPie', DtExampleRadialChartDefaultPie],
@@ -940,10 +896,7 @@ export const EXAMPLES_MAP = new Map>([
['DtExampleTableEmptyState', DtExampleTableEmptyState],
['DtExampleTableExpandableRows', DtExampleTableExpandableRows],
['DtExampleTableFavoriteColumn', DtExampleTableFavoriteColumn],
- [
- 'DtExampleTableFavoriteColumnNoHeader',
- DtExampleTableFavoriteColumnNoHeader,
- ],
+ ['DtExampleTableFavoriteColumnNoHeader', DtExampleTableFavoriteColumnNoHeader],
['DtExampleTableInteractiveRows', DtExampleTableInteractiveRows],
['DtExampleTableLoading', DtExampleTableLoading],
['DtExampleTableObservable', DtExampleTableObservable],
@@ -975,15 +928,12 @@ export const EXAMPLES_MAP = new Map>([
['DtExampleToastDefault', DtExampleToastDefault],
['DtExampleToastDynamicMsg', DtExampleToastDynamicMsg],
['DtExampleToggleButtonGroupDefault', DtExampleToggleButtonGroupDefault],
- [
- 'DtExampleToggleButtonGroupDynamicItems',
- DtExampleToggleButtonGroupDynamicItems,
- ],
+ ['DtExampleToggleButtonGroupDynamicItems', DtExampleToggleButtonGroupDynamicItems],
['DtExampleToggleButtonGroupShowMore', DtExampleToggleButtonGroupShowMore],
['DtExampleTopBarNavigationDefault', DtExampleTopBarNavigationDefault],
['DtExampleTopBarNavigationDrawer', DtExampleTopBarNavigationDrawer],
['DtExampleTreeTableAsyncShowMore', DtExampleTreeTableAsyncShowMore],
['DtExampleTreeTableDefault', DtExampleTreeTableDefault],
['DtExampleTreeTableProblemIndicator', DtExampleTreeTableProblemIndicator],
- ['DtExampleTreeTableSimple', DtExampleTreeTableSimple],
+ ['DtExampleTreeTableSimple', DtExampleTreeTableSimple]
]);
diff --git a/libs/examples/src/quick-filter/quick-filter-default-example/quick-filter-default-example.html b/libs/examples/src/quick-filter/quick-filter-default-example/quick-filter-default-example.html
new file mode 100644
index 0000000000..0bbed7a230
--- /dev/null
+++ b/libs/examples/src/quick-filter/quick-filter-default-example/quick-filter-default-example.html
@@ -0,0 +1,8 @@
+
+ Quick-filter
+
+ All options in the filter field above
+
+
+ my content
+
diff --git a/libs/examples/src/quick-filter/quick-filter-default-example/quick-filter-default-example.ts b/libs/examples/src/quick-filter/quick-filter-default-example/quick-filter-default-example.ts
new file mode 100644
index 0000000000..5bb770a01f
--- /dev/null
+++ b/libs/examples/src/quick-filter/quick-filter-default-example/quick-filter-default-example.ts
@@ -0,0 +1,41 @@
+/**
+ * @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,
+} from '@dynatrace/barista-components/experimental/quick-filter';
+import { FILTER_FIELD_TEST_DATA as filterFieldData } from '@dynatrace/testing/fixtures';
+
+@Component({
+ selector: 'dt-example-quick-filter-default',
+ templateUrl: 'quick-filter-default-example.html',
+})
+export class DtExampleQuickFilterDefault {
+ /** 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 !== 'Not in Quickfilter',
+ };
+
+ _dataSource = new DtQuickFilterDefaultDataSource(
+ filterFieldData,
+ this._config,
+ );
+}
diff --git a/libs/examples/src/quick-filter/quick-filter-examples.module.ts b/libs/examples/src/quick-filter/quick-filter-examples.module.ts
new file mode 100644
index 0000000000..8c2417e457
--- /dev/null
+++ b/libs/examples/src/quick-filter/quick-filter-examples.module.ts
@@ -0,0 +1,28 @@
+/**
+ * @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 { NgModule } from '@angular/core';
+import { DtQuickFilterModule } from '@dynatrace/barista-components/experimental/quick-filter';
+import { DtExampleQuickFilterDefault } from './quick-filter-default-example/quick-filter-default-example';
+
+export const DT_QUICK_FILTER_EXAMPLES = [DtExampleQuickFilterDefault];
+
+@NgModule({
+ imports: [DtQuickFilterModule],
+ declarations: [...DT_QUICK_FILTER_EXAMPLES],
+ entryComponents: [...DT_QUICK_FILTER_EXAMPLES],
+})
+export class DtQuickFilterExamplesModule {}
diff --git a/libs/testing/browser/src/index.ts b/libs/testing/browser/src/index.ts
index c646f782d6..9bb9d7ee0d 100644
--- a/libs/testing/browser/src/index.ts
+++ b/libs/testing/browser/src/index.ts
@@ -19,6 +19,7 @@ export * from './lib/dispatch-events';
export * from './lib/event-objects';
export * from './lib/mock-component';
export * from './lib/mock-ng-zone';
+export * from './lib/mock-icon-testing-module';
export * from './lib/request-animation-frame';
export * from './lib/type-in-element';
export * from './lib/wrapped-error-message';
diff --git a/libs/testing/browser/src/lib/mock-icon-testing-module.ts b/libs/testing/browser/src/lib/mock-icon-testing-module.ts
new file mode 100644
index 0000000000..ef66ada67d
--- /dev/null
+++ b/libs/testing/browser/src/lib/mock-icon-testing-module.ts
@@ -0,0 +1,54 @@
+/**
+ * @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 { NgModule, Type } from '@angular/core';
+import { TestModuleMetadata } from '@angular/core/testing';
+import { DtIconModule } from '@dynatrace/barista-components/icon';
+import { HttpClient } from '@angular/common/http';
+import { of } from 'rxjs';
+
+/**
+ * Creates a mock icon testing module without trying to fetch any svg.
+ * Returns an empty svg tag for unit testing.
+ */
+export function mockIconTestingModule(
+ config: TestModuleMetadata = {
+ imports: [],
+ providers: [],
+ declarations: [],
+ },
+): Type {
+ @NgModule({
+ imports: [
+ DtIconModule.forRoot({ svgIconLocation: '{{name}}.svg' }),
+ ...config.imports!,
+ ],
+ providers: [
+ {
+ provide: HttpClient,
+ useValue: {
+ get: jest.fn().mockReturnValue(of('')),
+ },
+ },
+ ...config.providers!,
+ ],
+ declarations: config.declarations,
+ exports: [DtIconModule],
+ })
+ class IconTestingModule {}
+
+ return IconTestingModule;
+}
diff --git a/libs/testing/fixtures/src/index.ts b/libs/testing/fixtures/src/index.ts
index f1795bf364..de85075447 100644
--- a/libs/testing/fixtures/src/index.ts
+++ b/libs/testing/fixtures/src/index.ts
@@ -15,3 +15,6 @@
*/
export * from './lib/chart';
+export * from './lib/filter-field/test-data';
+export * from './lib/filter-field/test-data-validators';
+export * from './lib/tree-table/test-data';
diff --git a/libs/testing/fixtures/src/lib/filter-field/test-data-validators.ts b/libs/testing/fixtures/src/lib/filter-field/test-data-validators.ts
new file mode 100644
index 0000000000..139661e641
--- /dev/null
+++ b/libs/testing/fixtures/src/lib/filter-field/test-data-validators.ts
@@ -0,0 +1,61 @@
+/**
+ * @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 { Validators } from '@angular/forms';
+
+export const FILTER_FIELD_TEST_DATA_VALIDATORS = {
+ autocomplete: [
+ {
+ name: 'custom normal',
+ suggestions: [],
+ },
+ {
+ name: 'custom required',
+ suggestions: [],
+ validators: [
+ { validatorFn: Validators.required, error: 'field is required' },
+ ],
+ },
+ {
+ name: 'custom with multiple',
+ suggestions: [],
+ validators: [
+ { validatorFn: Validators.required, error: 'field is required' },
+ { validatorFn: Validators.minLength(3), error: 'min 3 characters' },
+ ],
+ },
+ {
+ name: 'outer-option',
+ autocomplete: [
+ {
+ name: 'inner-option',
+ },
+ ],
+ },
+ {
+ name: 'Autocomplete with free text options',
+ autocomplete: [
+ { name: 'Autocomplete option 1' },
+ { name: 'Autocomplete option 2' },
+ { name: 'Autocomplete option 3' },
+ {
+ name: 'Autocomplete free text',
+ suggestions: ['Suggestion 1', 'Suggestion 2', 'Suggestion 3'],
+ validators: [],
+ },
+ ],
+ },
+ ],
+};
diff --git a/libs/testing/fixtures/src/lib/filter-field/test-data.ts b/libs/testing/fixtures/src/lib/filter-field/test-data.ts
new file mode 100644
index 0000000000..013c02cde3
--- /dev/null
+++ b/libs/testing/fixtures/src/lib/filter-field/test-data.ts
@@ -0,0 +1,54 @@
+/**
+ * @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.
+ */
+
+export const FILTER_FIELD_TEST_DATA = {
+ autocomplete: [
+ {
+ name: 'AUT',
+ distinct: true,
+ autocomplete: [{ name: 'Linz' }, { name: 'Vienna' }, { name: 'Graz' }],
+ },
+ {
+ name: 'USA',
+ autocomplete: [
+ { name: 'San Francisco' },
+ { name: 'Los Angeles' },
+ { name: 'New York' },
+ { name: 'Custom', suggestions: [] },
+ ],
+ },
+ {
+ name: 'Requests per minute',
+ range: {
+ operators: {
+ range: true,
+ equal: true,
+ greaterThanEqual: true,
+ lessThanEqual: true,
+ },
+ },
+ unit: 's',
+ },
+ {
+ name: 'Not in Quickfilter',
+ autocomplete: [
+ { name: 'Option1' },
+ { name: 'Option2' },
+ { name: 'Option3' },
+ ],
+ },
+ ],
+};
diff --git a/libs/testing/fixtures/src/lib/tree-table/test-data.ts b/libs/testing/fixtures/src/lib/tree-table/test-data.ts
new file mode 100644
index 0000000000..713cc5fbec
--- /dev/null
+++ b/libs/testing/fixtures/src/lib/tree-table/test-data.ts
@@ -0,0 +1,121 @@
+/**
+ * @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 { DtIconType } from '@dynatrace/barista-icons';
+
+// tslint:disable: dt-document-public-fields
+
+export const TREE_TABLE_TEST_DATA: ThreadNode[] = [
+ {
+ name: 'hz.hzInstance_1_cluster.thread',
+ icon: 'airplane',
+ threadlevel: 'S0',
+ totalTimeConsumption: 150,
+ waiting: 123,
+ running: 20,
+ blocked: 0,
+ children: [
+ {
+ name:
+ 'hz.hzInstance_1_cluster.thread_1_hz.hzInstance_1_cluster.thread-1',
+ icon: 'airplane',
+ threadlevel: 'S1',
+ totalTimeConsumption: 150,
+ waiting: 123,
+ running: 20,
+ blocked: 0,
+ },
+ {
+ name: 'hz.hzInstance_1_cluster.thread-2',
+ icon: 'airplane',
+ threadlevel: 'S1',
+ totalTimeConsumption: 150,
+ waiting: 130,
+ running: 0,
+ blocked: 0,
+ },
+ ],
+ },
+ {
+ name: 'jetty',
+ icon: 'airplane',
+ threadlevel: 'S0',
+ totalTimeConsumption: 150,
+ waiting: 123,
+ running: 20,
+ blocked: 0,
+ children: [
+ {
+ name: 'jetty-422',
+ icon: 'airplane',
+ threadlevel: 'S1',
+ totalTimeConsumption: 150,
+ waiting: 123,
+ running: 20,
+ blocked: 0,
+ },
+ {
+ name: 'jetty-423',
+ icon: 'airplane',
+ threadlevel: 'S1',
+ totalTimeConsumption: 150,
+ waiting: 130,
+ running: 0,
+ blocked: 0,
+ },
+ {
+ name: 'jetty-424',
+ icon: 'airplane',
+ threadlevel: 'S1',
+ totalTimeConsumption: 150,
+ waiting: 130,
+ running: 0,
+ blocked: 0,
+ },
+ ],
+ },
+ {
+ name: 'Downtime timer',
+ icon: 'airplane',
+ threadlevel: 'S0',
+ totalTimeConsumption: 150,
+ waiting: 123,
+ running: 20,
+ blocked: 0,
+ },
+];
+
+export class ThreadNode {
+ name: string;
+ threadlevel: string;
+ totalTimeConsumption: number;
+ blocked: number;
+ running: number;
+ waiting: number;
+ icon: DtIconType;
+ children?: ThreadNode[];
+}
+
+export class ThreadFlatNode {
+ name: string;
+ threadlevel: string;
+ totalTimeConsumption: number;
+ blocked: number;
+ running: number;
+ waiting: number;
+ icon: DtIconType;
+ level: number;
+ expandable: boolean;
+}
diff --git a/nx.json b/nx.json
index f26dd02371..02f1d1aeac 100644
--- a/nx.json
+++ b/nx.json
@@ -242,6 +242,9 @@
"progress-circle": {
"tags": ["scope:components", "type:library"]
},
+ "quick-filter": {
+ "tags": ["scope:components", "type:library"]
+ },
"radial-chart": {
"tags": ["scope:components", "type:library"]
},
diff --git a/tsconfig.json b/tsconfig.json
index 0bff269c2a..86dc245651 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -86,6 +86,9 @@
"@dynatrace/barista-components/expandable-text": [
"libs/barista-components/expandable-text/index.ts"
],
+ "@dynatrace/barista-components/experimental/quick-filter": [
+ "libs/barista-components/experimental/quick-filter/index.ts"
+ ],
"@dynatrace/barista-components/filter-field": [
"libs/barista-components/filter-field/index.ts"
],
diff --git a/tslint.json b/tslint.json
index 4b948bd320..268e90d063 100644
--- a/tslint.json
+++ b/tslint.json
@@ -76,6 +76,10 @@
"sourceTag": "type:app",
"onlyDependOnLibsWithTags": ["type:library"]
},
+ {
+ "sourceTag": "type:e2e",
+ "onlyDependOnLibsWithTags": ["type:library"]
+ },
{
"sourceTag": "scope:examples",
"onlyDependOnLibsWithTags": ["scope:components"]