From fe8bc8826dcaaabd6dd074f3fa577cac2c520201 Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Thu, 1 Jul 2021 19:12:36 +0300 Subject: [PATCH] wip page header component --- .../screens/trash/trash-screen.component.html | 12 +- .../screens/trash/trash-screen.component.scss | 4 - .../dossier-listing-screen.component.html | 58 +------ .../dossier-listing-screen.component.ts | 78 ++++++--- .../dossier-overview-screen.component.html | 157 +++++++++--------- .../dossier-overview-screen.component.ts | 63 +++++-- .../shared/base/base-listing.component.ts | 33 +--- .../popup-filter/popup-filter.component.html | 49 +++--- .../popup-filter/popup-filter.component.ts | 60 +++---- .../quick-filters/quick-filters.component.ts | 8 +- .../page-header/page-header.component.html | 61 +++++++ .../page-header/page-header.component.scss | 3 + .../page-header/page-header.component.ts | 92 ++++++++++ .../src/app/modules/shared/shared.module.ts | 2 + 14 files changed, 412 insertions(+), 268 deletions(-) create mode 100644 apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.html create mode 100644 apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.scss create mode 100644 apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.ts diff --git a/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.html index d7977a9ea..92a0e7c2e 100644 --- a/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.html @@ -1,17 +1,7 @@
- +
diff --git a/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.scss b/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.scss index e602d688d..db5f61403 100644 --- a/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.scss +++ b/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.scss @@ -38,7 +38,3 @@ redaction-table-col-name::ng-deep { } } } - -.page-header .actions > *:not(:last-child) { - margin-right: 16px; -} diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-listing-screen/dossier-listing-screen.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-listing-screen/dossier-listing-screen.component.html index 756c7e49c..1dcc66ff5 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-listing-screen/dossier-listing-screen.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-listing-screen/dossier-listing-screen.component.html @@ -1,53 +1,11 @@
- +
@@ -135,7 +93,7 @@
- {{ documentCount(dw) }} + {{ filesCount(dw) }}
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-listing-screen/dossier-listing-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-listing-screen/dossier-listing-screen.component.ts index e10a43e3b..1a62be189 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-listing-screen/dossier-listing-screen.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-listing-screen/dossier-listing-screen.component.ts @@ -1,12 +1,4 @@ -import { - Component, - Injector, - OnDestroy, - OnInit, - QueryList, - ViewChild, - ViewChildren -} from '@angular/core'; +import { Component, Injector, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { Dossier, DossierTemplateModel } from '@redaction/red-ui-http'; import { AppStateService } from '@state/app-state.service'; import { UserService } from '@services/user.service'; @@ -25,7 +17,6 @@ import { DossiersDialogService } from '../../services/dossiers-dialog.service'; import { BaseListingComponent } from '@shared/base/base-listing.component'; import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy'; import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model'; -import { PopupFilterComponent } from '@shared/components/filters/popup-filter/popup-filter.component'; import { annotationFilterChecker, dossierMemberChecker, @@ -33,11 +24,11 @@ import { dossierTemplateChecker, processFilters } from '@shared/components/filters/popup-filter/utils/filter-utils'; -import { QuickFiltersComponent } from '../../../shared/components/filters/quick-filters/quick-filters.component'; +import { QuickFiltersComponent } from '@shared/components/filters/quick-filters/quick-filters.component'; import { UserPreferenceService } from '../../../../services/user-preference.service'; +import { ButtonConfig, FilterConfig } from '@shared/components/page-header/page-header.component'; @Component({ - selector: 'redaction-dossier-listing-screen', templateUrl: './dossier-listing-screen.component.html', styleUrls: ['./dossier-listing-screen.component.scss'] }) @@ -58,6 +49,16 @@ export class DossierListingScreenComponent }; quickFilters: FilterModel[]; readonly itemSize = 85; + filterConfigs: FilterConfig[]; + buttonConfigs: ButtonConfig[] = [ + { + label: 'dossier-listing.add-new', + action: () => this.openAddDossierDialog(), + hide: !this.permissionsService.isManager(), + icon: 'red:plus', + type: 'primary' + } + ]; protected readonly _searchKey = 'name'; protected readonly _sortKey = 'dossier-listing'; @@ -67,10 +68,10 @@ export class DossierListingScreenComponent private _routerEventsScrollPositionSub: Subscription; private _fileChangedSub: Subscription; - @ViewChildren(PopupFilterComponent) - private readonly _filterList: QueryList; @ViewChild(QuickFiltersComponent) protected readonly _quickFiltersComponent: QuickFiltersComponent; + @ViewChild('needsWorkTemplate', { read: TemplateRef, static: true }) + private readonly _needsWorkTemplate: TemplateRef; constructor( readonly permissionsService: PermissionsService, @@ -155,7 +156,7 @@ export class DossierListingScreenComponent this._lastScrollPosition = this.scrollViewport.measureScrollOffset('top'); } }); - this._filterComponents = [...this._filterList.toArray(), this._quickFiltersComponent]; + this._filterComponents = [this._quickFiltersComponent]; } ngOnAttach() { @@ -175,7 +176,7 @@ export class DossierListingScreenComponent this._fileChangedSub.unsubscribe(); } - documentCount(dossier: DossierWrapper) { + filesCount(dossier: DossierWrapper) { return dossier.files.length; } @@ -248,12 +249,9 @@ export class DossierListingScreenComponent const allDistinctDossierTemplates = new Set(); this.allEntities.forEach(entry => { // all people - entry.dossier.memberIds.forEach(memberId => allDistinctPeople.add(memberId)); + entry.dossier.memberIds.forEach(f => allDistinctPeople.add(f)); // file statuses - entry.files.forEach(file => { - allDistinctFileStatus.add(file.status); - }); - + entry.files.forEach(f => allDistinctFileStatus.add(f.status)); // Needs work entry.files.forEach(file => { if (this.permissionsService.fileRequiresReanalysis(file)) @@ -312,7 +310,39 @@ export class DossierListingScreenComponent dossierTemplateFilters ); - this.quickFilters = [ + this._createFilterConfigs(); + this._createQuickFilters(); + } + + private _createFilterConfigs() { + this.filterConfigs = [ + { + label: 'filters.status', + primaryFilters: this.statusFilters, + icon: 'red:status' + }, + { + label: 'filters.people', + primaryFilters: this.peopleFilters, + icon: 'red:user' + }, + { + label: 'filters.needs-work', + primaryFilters: this.needsWorkFilters, + icon: 'red:needs-work', + filterTemplate: this._needsWorkTemplate + }, + { + label: 'filters.dossier-templates', + primaryFilters: this.dossierTemplateFilters, + icon: 'red:template', + hide: this.dossierTemplateFilters.length <= 1 + } + ]; + } + + private _createQuickFilters() { + const filters = [ { key: this.user.id, label: 'dossier-listing.quick-filters.my-dossiers', @@ -333,7 +363,9 @@ export class DossierListingScreenComponent label: 'dossier-listing.quick-filters.other', checker: (dw: DossierWrapper) => !dw.memberIds.includes(this.user.id) } - ].filter( + ]; + + this.quickFilters = filters.filter( f => f.label === 'dossier-listing.quick-filters.my-dossiers' || this._userPreferenceService.areDevFeaturesEnabled diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.html index d18157645..a53154b42 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.html @@ -1,84 +1,91 @@
- + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts index 6f537d418..d7de6c947 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts @@ -5,9 +5,8 @@ import { Injector, OnDestroy, OnInit, - QueryList, - ViewChild, - ViewChildren + TemplateRef, + ViewChild } from '@angular/core'; import { NavigationStart, Router } from '@angular/router'; import { NotificationService, NotificationType } from '@services/notification.service'; @@ -38,9 +37,12 @@ import { processFilters } from '@shared/components/filters/popup-filter/utils/filter-utils'; import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model'; -import { PopupFilterComponent } from '@shared/components/filters/popup-filter/popup-filter.component'; import { QuickFiltersComponent } from '../../../shared/components/filters/quick-filters/quick-filters.component'; import { AppConfigService } from '../../../app-config/app-config.service'; +import { + ActionConfig, + FilterConfig +} from '../../../shared/components/page-header/page-header.component'; @Component({ selector: 'redaction-dossier-overview-screen', @@ -61,6 +63,8 @@ export class DossierOverviewScreenComponent } = { needsWorkFilters: [], statusFilters: [] }; readonly itemSize = 80; quickFilters: FilterModel[]; + filterConfigs: FilterConfig[]; + actionConfigs: ActionConfig[]; protected readonly _searchKey = 'searchField'; protected readonly _selectionKey = 'fileId'; @@ -74,11 +78,10 @@ export class DossierOverviewScreenComponent private _lastScrollPosition: number; private _lastOpenedFileId = ''; - @ViewChildren(PopupFilterComponent) - private readonly _filterList: QueryList; @ViewChild(QuickFiltersComponent) protected readonly _quickFiltersComponent: QuickFiltersComponent; - + @ViewChild('needsWorkTemplate', { read: TemplateRef, static: true }) + private readonly _needsWorkTemplate: TemplateRef; @ViewChild('fileInput') private _fileInput: ElementRef; constructor( @@ -182,7 +185,7 @@ export class DossierOverviewScreenComponent } }); - this._filterComponents = [...this._filterList.toArray(), this._quickFiltersComponent]; + this._filterComponents = [this._quickFiltersComponent]; } ngOnDestroy(): void { @@ -393,10 +396,12 @@ export class DossierOverviewScreenComponent ); this.needsWorkFilters = processFilters(this.needsWorkFilters, needsWorkFilters); - this._computeQuickFilters(); + this._createQuickFilters(); + this._createFilterConfigs(); + this._createActionConfigs(); } - private _computeQuickFilters() { + private _createQuickFilters() { if (this.allEntities.filter(this.recentlyModifiedChecker).length > 0) { const recentPeriodInHours = this._appConfigService.getConfig('RECENT_PERIOD_IN_HOURS'); this.quickFilters = [ @@ -432,4 +437,42 @@ export class DossierOverviewScreenComponent } ]; } + + private _createFilterConfigs() { + this.filterConfigs = [ + { + label: 'filters.status', + primaryFilters: this.statusFilters, + icon: 'red:status' + }, + { + label: 'filters.assigned-people', + primaryFilters: this.peopleFilters, + icon: 'red:user' + }, + { + label: 'filters.needs-work', + primaryFilters: this.needsWorkFilters, + icon: 'red:needs-work', + filterTemplate: this._needsWorkTemplate + } + ]; + } + + private _createActionConfigs() { + this.actionConfigs = [ + { + label: 'dossier-overview.header-actions.edit', + action: $event => this.openEditDossierDialog($event), + icon: 'red:edit', + hide: !this.permissionsService.isManager() + }, + { + label: 'dossier-overview.header-actions.edit', + action: $event => this.openEditDossierDialog($event), + icon: 'red:edit', + hide: !this.permissionsService.isManager() + } + ]; + } } diff --git a/apps/red-ui/src/app/modules/shared/base/base-listing.component.ts b/apps/red-ui/src/app/modules/shared/base/base-listing.component.ts index 96db88b82..9099c9837 100644 --- a/apps/red-ui/src/app/modules/shared/base/base-listing.component.ts +++ b/apps/red-ui/src/app/modules/shared/base/base-listing.component.ts @@ -33,20 +33,12 @@ export abstract class BaseListingComponent { // Overwrite this in ngOnInit protected _filterComponents: (PopupFilterComponent | QuickFiltersComponent)[] = []; + private _searchValue = ''; + protected constructor(protected readonly _injector: Injector) { this._formBuilder = this._injector.get(FormBuilder); this._changeDetectorRef = this._injector.get(ChangeDetectorRef); this._sortingService = this._injector.get(SortingService); - this._initSearch(); - } - - get hasActiveFilters() { - return ( - this._filterComponents - ?.filter(f => !!f) - .reduce((prev, component) => prev || component?.hasActiveFilters, false) || - this.searchForm.get('query').value - ); } get areAllEntitiesSelected() { @@ -108,10 +100,9 @@ export abstract class BaseListingComponent { resetFilters() { for (const filterComponent of this._filterComponents.filter(f => !!f)) { - filterComponent.deactivateAllFilters(); + filterComponent.deactivateFilters(); } this.filtersChanged(); - this.searchForm.reset({ query: '' }); } // Filter @@ -155,7 +146,8 @@ export abstract class BaseListingComponent { } @debounce(200) - protected _executeSearch() { + executeSearch(value: string) { + this._searchValue = value; this._executeSearchImmediately(); } @@ -163,10 +155,9 @@ export abstract class BaseListingComponent { this.displayedEntities = ( this._filters.length ? this.filteredEntities : this.allEntities ).filter(entity => - this._searchField(entity) - .toLowerCase() - .includes(this.searchForm.get('query').value.toLowerCase()) + this._searchField(entity).toLowerCase().includes(this._searchValue.toLowerCase()) ); + this._updateSelection(); } @@ -183,15 +174,7 @@ export abstract class BaseListingComponent { protected _filterEntities() { this._preFilter(); this.filteredEntities = getFilteredEntities(this.allEntities, this._filters); - this._executeSearch(); + this.executeSearch(this._searchValue); this._changeDetectorRef.detectChanges(); } - - private _initSearch() { - this.searchForm = this._formBuilder.group({ - query: [''] - }); - - this.searchForm.valueChanges.subscribe(() => this._executeSearch()); - } } diff --git a/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/popup-filter.component.html b/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/popup-filter.component.html index e77ecdc39..801082a3c 100644 --- a/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/popup-filter.component.html +++ b/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/popup-filter.component.html @@ -16,10 +16,10 @@ -
+
@@ -35,30 +35,33 @@ >
+
- + >
+
+
- + >
-
+ @@ -88,16 +91,17 @@ [indeterminate]="_(filter).indeterminate" class="filter-menu-checkbox" > - + > - + >
+
- + > - + >
diff --git a/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/popup-filter.component.ts b/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/popup-filter.component.ts index b899ed9e8..d63f4486d 100644 --- a/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/popup-filter.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/popup-filter.component.ts @@ -1,4 +1,5 @@ import { + ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, @@ -15,6 +16,7 @@ import { MAT_CHECKBOX_DEFAULT_OPTIONS } from '@angular/material/checkbox'; selector: 'redaction-popup-filter', templateUrl: './popup-filter.component.html', styleUrls: ['./popup-filter.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, providers: [ { provide: MAT_CHECKBOX_DEFAULT_OPTIONS, @@ -38,9 +40,6 @@ export class PopupFilterComponent implements OnChanges { @Input() icon: string; @Input() chevron = false; - mouseOver = true; - mouseOverTimeout: number; - atLeastOneFilterIsExpandable = false; atLeastOneSecondaryFilterIsExpandable = false; @@ -60,44 +59,38 @@ export class PopupFilterComponent implements OnChanges { } ngOnChanges(): void { - this.atLeastOneFilterIsExpandable = false; - this.atLeastOneSecondaryFilterIsExpandable = false; - this.primaryFilters?.forEach(f => { - this.atLeastOneFilterIsExpandable = - this.atLeastOneFilterIsExpandable || this.isExpandable(f); - }); - this.secondaryFilters?.forEach(f => { - this.atLeastOneSecondaryFilterIsExpandable = - this.atLeastOneSecondaryFilterIsExpandable || this.isExpandable(f); - }); + this.atLeastOneFilterIsExpandable = !!this.primaryFilters?.find(f => this.isExpandable(f)); + this.atLeastOneSecondaryFilterIsExpandable = !!this.secondaryFilters?.find(f => + this.isExpandable(f) + ); } filterCheckboxClicked($event: any, filter: FilterModel, parent?: FilterModel) { $event.stopPropagation(); filter.checked = !filter.checked; + if (parent) { handleCheckedValue(parent); } else { - if (filter.indeterminate) { - filter.checked = false; - } + if (filter.indeterminate) filter.checked = false; filter.indeterminate = false; filter.filters?.forEach(f => (f.checked = filter.checked)); } - this._changeDetectorRef.detectChanges(); + this.applyFilters(); } - activateAllFilters() { - this._setAllFilters(true); + activatePrimaryFilters() { + this._setFilters(true); } - deactivateAllFilters() { - this._setAllFilters(false); + deactivateFilters() { + this._setFilters(); } applyFilters() { + this._changeDetectorRef.detectChanges(); this.filtersChanged.emit({ primary: this.primaryFilters, secondary: this.secondaryFilters @@ -109,20 +102,6 @@ export class PopupFilterComponent implements OnChanges { filter.expanded = !filter.expanded; } - filterMouseEnter() { - this.mouseOver = true; - if (this.mouseOverTimeout) { - clearTimeout(this.mouseOverTimeout); - } - } - - filterMouseLeave() { - this.mouseOver = false; - this.mouseOverTimeout = setTimeout(() => { - // this.trigger.closeMenu(); - }, 1000); - } - isExpandable(filter: FilterModel) { return filter.filters && filter.filters.length > 0; } @@ -131,14 +110,13 @@ export class PopupFilterComponent implements OnChanges { return obj as FilterModel; } - private _setAllFilters(value: boolean) { - const filters = value ? this.primaryFilters : this._allFilters; + private _setFilters(onlyPrimaryFilters = false) { + const filters = onlyPrimaryFilters ? this.primaryFilters : this._allFilters; filters.forEach(f => { - f.checked = value; + f.checked = onlyPrimaryFilters; f.indeterminate = false; - f.filters?.forEach(ff => { - ff.checked = value; - }); + f.filters?.forEach(ff => (ff.checked = onlyPrimaryFilters)); }); + this.applyFilters(); } } diff --git a/apps/red-ui/src/app/modules/shared/components/filters/quick-filters/quick-filters.component.ts b/apps/red-ui/src/app/modules/shared/components/filters/quick-filters/quick-filters.component.ts index f318b070c..fcb682f08 100644 --- a/apps/red-ui/src/app/modules/shared/components/filters/quick-filters/quick-filters.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/filters/quick-filters/quick-filters.component.ts @@ -10,16 +10,12 @@ export class QuickFiltersComponent { @Output() filtersChanged = new EventEmitter(); @Input() filters: FilterModel[]; - constructor() {} - get hasActiveFilters(): boolean { return this.filters.filter(f => f.checked).length > 0; } - deactivateAllFilters() { - for (const filter of this.filters) { - filter.checked = false; - } + deactivateFilters() { + for (const filter of this.filters) filter.checked = false; } toggle(filter: FilterModel) { diff --git a/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.html b/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.html new file mode 100644 index 000000000..99d20c336 --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.html @@ -0,0 +1,61 @@ + diff --git a/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.scss b/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.scss new file mode 100644 index 000000000..434b95fc1 --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.scss @@ -0,0 +1,3 @@ +.page-header .actions > *:not(:last-child) { + margin-right: 16px; +} diff --git a/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.ts b/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.ts new file mode 100644 index 000000000..465871018 --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/page-header/page-header.component.ts @@ -0,0 +1,92 @@ +import { + ChangeDetectionStrategy, + Component, + EventEmitter, + Input, + Output, + QueryList, + TemplateRef, + ViewChildren +} from '@angular/core'; +import { PermissionsService } from '@services/permissions.service'; +import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model'; +import { PopupFilterComponent } from '@shared/components/filters/popup-filter/popup-filter.component'; +import { FormBuilder, FormGroup } from '@angular/forms'; + +interface BaseHeaderConfig { + label: string; + icon?: string; + hide?: boolean; +} + +export interface FilterConfig extends BaseHeaderConfig { + primaryFilters: FilterModel[]; + filterTemplate?: TemplateRef; +} + +export interface ActionConfig extends BaseHeaderConfig { + action: ($event) => void; +} + +export interface ButtonConfig extends BaseHeaderConfig { + action: ($event) => void; + type?: 'default' | 'show-bg' | 'primary'; +} + +@Component({ + selector: 'redaction-page-header', + templateUrl: './page-header.component.html', + styleUrls: ['./page-header.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class PageHeaderComponent { + @Input() pageLabel: string; + @Input() showCloseButton: boolean; + @Input() filterConfigs: FilterConfig[]; + @Input() actionConfigs: ActionConfig[]; + @Input() buttonConfigs: ButtonConfig[]; + @Input() searchPlaceholder: string; + @Output() filtersChanged = new EventEmitter(); + @Output() searchChanged = new EventEmitter(); + + searchForm: FormGroup; + + @ViewChildren(PopupFilterComponent) + private readonly _filterComponents: QueryList; + + constructor( + readonly permissionsService: PermissionsService, + private readonly _formBuilder: FormBuilder + ) { + this._initSearch(); + } + + get hasActiveFilters() { + return ( + this._filterComponents + ?.filter(f => !!f) + .reduce((prev, component) => prev || component?.hasActiveFilters, false) || + this.searchForm.get('query').value + ); + } + + resetFilters() { + for (const filterComponent of this._filterComponents.filter(f => !!f)) { + filterComponent.deactivateFilters(); + } + this.filtersChanged.emit(); + this.searchForm.reset({ query: '' }); + } + + private _initSearch() { + this.searchForm = this._formBuilder.group({ + query: [''] + }); + + this.searchForm.valueChanges.subscribe(value => this.searchChanged.emit(value.query)); + } + + trackByLabel(index: number, item: BaseHeaderConfig) { + return item.label; + } +} diff --git a/apps/red-ui/src/app/modules/shared/shared.module.ts b/apps/red-ui/src/app/modules/shared/shared.module.ts index ea266532f..4118cd4da 100644 --- a/apps/red-ui/src/app/modules/shared/shared.module.ts +++ b/apps/red-ui/src/app/modules/shared/shared.module.ts @@ -37,6 +37,7 @@ import { QuickFiltersComponent } from './components/filters/quick-filters/quick- import { PopupFilterComponent } from '@shared/components/filters/popup-filter/popup-filter.component'; import { AssignUserDropdownComponent } from './components/assign-user-dropdown/assign-user-dropdown.component'; import { InputWithActionComponent } from '@shared/components/input-with-action/input-with-action.component'; +import { PageHeaderComponent } from './components/page-header/page-header.component'; const buttons = [ ChevronButtonComponent, @@ -67,6 +68,7 @@ const components = [ DictionaryManagerComponent, QuickFiltersComponent, AssignUserDropdownComponent, + PageHeaderComponent, ...buttons ];