From 53d8406c23be66ecf959e52f947d9fb8997172d5 Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Wed, 7 Jul 2021 15:33:37 +0300 Subject: [PATCH] add actions to page header, reset quick filters from page header --- .../dossier-listing-screen.component.html | 8 +- .../dossier-listing-screen.component.ts | 33 +++-- .../dossier-overview-screen.component.html | 114 +++++------------- .../dossier-overview-screen.component.scss | 4 - .../dossier-overview-screen.component.ts | 48 ++++---- .../shared/base/base-listing.component.ts | 22 ++-- .../icon-button/icon-button.component.ts | 9 +- .../popup-filter/popup-filter.component.ts | 19 ++- .../page-header/models/action-config.model.ts | 5 + .../page-header/models/base-config.model.ts | 5 + .../page-header/models/button-config.model.ts | 7 ++ .../page-header/models/filter-config.model.ts | 8 ++ .../page-header/page-header.component.html | 43 ++++--- .../page-header/page-header.component.scss | 4 +- .../page-header/page-header.component.ts | 64 ++++------ 15 files changed, 174 insertions(+), 219 deletions(-) create mode 100644 apps/red-ui/src/app/modules/shared/components/page-header/models/action-config.model.ts create mode 100644 apps/red-ui/src/app/modules/shared/components/page-header/models/base-config.model.ts create mode 100644 apps/red-ui/src/app/modules/shared/components/page-header/models/button-config.model.ts create mode 100644 apps/red-ui/src/app/modules/shared/components/page-header/models/filter-config.model.ts 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 1dcc66ff5..a45e9638e 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,10 +1,12 @@
@@ -20,7 +22,7 @@ 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 1a62be189..c9789db01 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 @@ -24,9 +24,9 @@ import { dossierTemplateChecker, processFilters } from '@shared/components/filters/popup-filter/utils/filter-utils'; -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'; +import { FilterConfig } from '../../../shared/components/page-header/models/filter-config.model'; +import { ButtonConfig } from '../../../shared/components/page-header/models/button-config.model'; @Component({ templateUrl: './dossier-listing-screen.component.html', @@ -48,11 +48,10 @@ export class DossierListingScreenComponent statusFilters: [] }; quickFilters: FilterModel[]; - readonly itemSize = 85; filterConfigs: FilterConfig[]; buttonConfigs: ButtonConfig[] = [ { - label: 'dossier-listing.add-new', + label: this._translateService.instant('dossier-listing.add-new'), action: () => this.openAddDossierDialog(), hide: !this.permissionsService.isManager(), icon: 'red:plus', @@ -60,6 +59,8 @@ export class DossierListingScreenComponent } ]; + readonly itemSize = 85; + protected readonly _searchKey = 'name'; protected readonly _sortKey = 'dossier-listing'; @@ -68,8 +69,6 @@ export class DossierListingScreenComponent private _routerEventsScrollPositionSub: Subscription; private _fileChangedSub: Subscription; - @ViewChild(QuickFiltersComponent) - protected readonly _quickFiltersComponent: QuickFiltersComponent; @ViewChild('needsWorkTemplate', { read: TemplateRef, static: true }) private readonly _needsWorkTemplate: TemplateRef; @@ -156,7 +155,6 @@ export class DossierListingScreenComponent this._lastScrollPosition = this.scrollViewport.measureScrollOffset('top'); } }); - this._filterComponents = [this._quickFiltersComponent]; } ngOnAttach() { @@ -317,23 +315,23 @@ export class DossierListingScreenComponent private _createFilterConfigs() { this.filterConfigs = [ { - label: 'filters.status', + label: this._translateService.instant('filters.status'), primaryFilters: this.statusFilters, icon: 'red:status' }, { - label: 'filters.people', + label: this._translateService.instant('filters.people'), primaryFilters: this.peopleFilters, icon: 'red:user' }, { - label: 'filters.needs-work', + label: this._translateService.instant('filters.needs-work'), primaryFilters: this.needsWorkFilters, icon: 'red:needs-work', filterTemplate: this._needsWorkTemplate }, { - label: 'filters.dossier-templates', + label: this._translateService.instant('filters.dossier-templates'), primaryFilters: this.dossierTemplateFilters, icon: 'red:template', hide: this.dossierTemplateFilters.length <= 1 @@ -342,32 +340,33 @@ export class DossierListingScreenComponent } private _createQuickFilters() { - const filters = [ + const filters: FilterModel[] = [ { key: this.user.id, - label: 'dossier-listing.quick-filters.my-dossiers', + label: this._translateService.instant('dossier-listing.quick-filters.my-dossiers'), checker: (dw: DossierWrapper) => dw.ownerId === this.user.id }, { key: this.user.id, - label: 'dossier-listing.quick-filters.to-approve', + label: this._translateService.instant('dossier-listing.quick-filters.to-approve'), checker: (dw: DossierWrapper) => dw.approverIds.includes(this.user.id) }, { key: this.user.id, - label: 'dossier-listing.quick-filters.to-review', + label: this._translateService.instant('dossier-listing.quick-filters.to-review'), checker: (dw: DossierWrapper) => dw.memberIds.includes(this.user.id) }, { key: this.user.id, - label: 'dossier-listing.quick-filters.other', + label: this._translateService.instant('dossier-listing.quick-filters.other'), checker: (dw: DossierWrapper) => !dw.memberIds.includes(this.user.id) } ]; this.quickFilters = filters.filter( f => - f.label === 'dossier-listing.quick-filters.my-dossiers' || + f.label === + this._translateService.instant('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 a53154b42..a0cd15405 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,91 +1,41 @@
- - - - - - - - - - - - - - - - - - - - - - + [showResetFilters]="showResetFilters" + [showCloseButton]="true" + [searchPlaceholder]="'dossier-overview.search' | translate" + > + - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +
@@ -113,7 +63,7 @@ > diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.scss b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.scss index a0f607c1e..a84f71a23 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.scss +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.scss @@ -96,10 +96,6 @@ cdk-virtual-scroll-viewport { } } -.ml-6 { - margin-left: 6px; -} - .mr-4 { margin-right: 4px; } 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 d7de6c947..8eba4f95a 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 @@ -37,12 +37,9 @@ import { processFilters } from '@shared/components/filters/popup-filter/utils/filter-utils'; import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model'; -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'; +import { AppConfigKey, AppConfigService } from '../../../app-config/app-config.service'; +import { FilterConfig } from '@shared/components/page-header/models/filter-config.model'; +import { ActionConfig } from '@shared/components/page-header/models/action-config.model'; @Component({ selector: 'redaction-dossier-overview-screen', @@ -78,8 +75,6 @@ export class DossierOverviewScreenComponent private _lastScrollPosition: number; private _lastOpenedFileId = ''; - @ViewChild(QuickFiltersComponent) - protected readonly _quickFiltersComponent: QuickFiltersComponent; @ViewChild('needsWorkTemplate', { read: TemplateRef, static: true }) private readonly _needsWorkTemplate: TemplateRef; @ViewChild('fileInput') private _fileInput: ElementRef; @@ -184,8 +179,6 @@ export class DossierOverviewScreenComponent this._lastScrollPosition = this.scrollViewport.measureScrollOffset('top'); } }); - - this._filterComponents = [this._quickFiltersComponent]; } ngOnDestroy(): void { @@ -317,7 +310,7 @@ export class DossierOverviewScreenComponent recentlyModifiedChecker = (file: FileStatusWrapper) => moment(file.lastUpdated) - .add(this._appConfigService.getConfig('RECENT_PERIOD_IN_HOURS'), 'hours') + .add(this._appConfigService.getConfig(AppConfigKey.RECENT_PERIOD_IN_HOURS), 'hours') .isAfter(moment()); protected _preFilter() { @@ -403,12 +396,15 @@ export class DossierOverviewScreenComponent private _createQuickFilters() { if (this.allEntities.filter(this.recentlyModifiedChecker).length > 0) { - const recentPeriodInHours = this._appConfigService.getConfig('RECENT_PERIOD_IN_HOURS'); + const recentPeriod = this._appConfigService.getConfig( + AppConfigKey.RECENT_PERIOD_IN_HOURS + ); this.quickFilters = [ { key: this.user.id, - label: 'dossier-overview.quick-filters.recent', - labelParams: { hours: recentPeriodInHours }, + label: this._translateService.instant('dossier-overview.quick-filters.recent', { + hours: recentPeriod + }), required: true, checker: this.recentlyModifiedChecker } @@ -421,17 +417,21 @@ export class DossierOverviewScreenComponent ...this.quickFilters, { key: this.user.id, - label: 'dossier-overview.quick-filters.assigned-to-me', + label: this._translateService.instant( + 'dossier-overview.quick-filters.assigned-to-me' + ), checker: (file: FileStatusWrapper) => file.currentReviewer === this.user.id }, { key: this.user.id, - label: 'dossier-overview.quick-filters.unassigned', + label: this._translateService.instant('dossier-overview.quick-filters.unassigned'), checker: (file: FileStatusWrapper) => !file.currentReviewer }, { key: this.user.id, - label: 'dossier-overview.quick-filters.assigned-to-others', + label: this._translateService.instant( + 'dossier-overview.quick-filters.assigned-to-others' + ), checker: (file: FileStatusWrapper) => !!file.currentReviewer && file.currentReviewer !== this.user.id } @@ -441,17 +441,17 @@ export class DossierOverviewScreenComponent private _createFilterConfigs() { this.filterConfigs = [ { - label: 'filters.status', + label: this._translateService.instant('filters.status'), primaryFilters: this.statusFilters, icon: 'red:status' }, { - label: 'filters.assigned-people', + label: this._translateService.instant('filters.assigned-people'), primaryFilters: this.peopleFilters, icon: 'red:user' }, { - label: 'filters.needs-work', + label: this._translateService.instant('filters.needs-work'), primaryFilters: this.needsWorkFilters, icon: 'red:needs-work', filterTemplate: this._needsWorkTemplate @@ -462,13 +462,7 @@ export class DossierOverviewScreenComponent 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', + label: this._translateService.instant('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 9099c9837..d2a1c65a3 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 @@ -3,7 +3,6 @@ import { FormBuilder, FormGroup } from '@angular/forms'; import { debounce } from '@utils/debounce'; import { ScreenName, SortingOption, SortingService } from '@services/sorting.service'; import { FilterModel } from '../components/filters/popup-filter/model/filter.model'; -import { PopupFilterComponent } from '../components/filters/popup-filter/popup-filter.component'; import { getFilteredEntities } from '../components/filters/popup-filter/utils/filter-utils'; import { QuickFiltersComponent } from '../components/filters/quick-filters/quick-filters.component'; import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling'; @@ -19,6 +18,7 @@ export abstract class BaseListingComponent { displayedEntities: T[] = []; selectedEntitiesIds: string[] = []; searchForm: FormGroup; + showResetFilters = false; @ViewChild(CdkVirtualScrollViewport) scrollViewport: CdkVirtualScrollViewport; protected readonly _formBuilder: FormBuilder; @@ -31,7 +31,8 @@ export abstract class BaseListingComponent { protected readonly _selectionKey: string; protected readonly _sortKey: ScreenName; // Overwrite this in ngOnInit - protected _filterComponents: (PopupFilterComponent | QuickFiltersComponent)[] = []; + @ViewChild(QuickFiltersComponent) + protected _quickFilters: QuickFiltersComponent; private _searchValue = ''; @@ -87,26 +88,25 @@ export abstract class BaseListingComponent { return this._sortKey; } - filtersChanged(filters?: { [key: string]: FilterModel[] }): void { - if (filters) { - for (const key of Object.keys(filters)) { - for (let idx = 0; idx < this[key].length; ++idx) { + filtersChanged(filters?: { [key: string]: FilterModel[] } | FilterModel[]): void { + if (filters instanceof Array) this.showResetFilters = !!filters.find(f => f.checked); + else + for (const key of Object.keys(filters ?? {})) { + for (let idx = 0; idx < this[key]?.length; ++idx) { this[key][idx] = filters[key][idx]; } } - } + this._filterEntities(); } resetFilters() { - for (const filterComponent of this._filterComponents.filter(f => !!f)) { - filterComponent.deactivateFilters(); - } + this._quickFilters.deactivateFilters(); + this.showResetFilters = false; this.filtersChanged(); } // Filter - toggleEntitySelected($event: MouseEvent, entity: T) { $event.stopPropagation(); const idx = this.selectedEntitiesIds.indexOf(entity[this._getSelectionKey]); diff --git a/apps/red-ui/src/app/modules/shared/components/buttons/icon-button/icon-button.component.ts b/apps/red-ui/src/app/modules/shared/components/buttons/icon-button/icon-button.component.ts index 507d9f601..0faab82ab 100644 --- a/apps/red-ui/src/app/modules/shared/components/buttons/icon-button/icon-button.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/buttons/icon-button/icon-button.component.ts @@ -1,5 +1,12 @@ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; +export type IconButtonType = 'default' | 'show-bg' | 'primary'; +export enum IconButtonTypes { + DEFAULT = 'default', + SHOW_BG = 'show-bg', + PRIMARY = 'primary' +} + @Component({ selector: 'redaction-icon-button', templateUrl: './icon-button.component.html', @@ -11,6 +18,6 @@ export class IconButtonComponent { @Input() text: string; @Input() showDot = false; @Input() disabled = false; - @Input() type: 'default' | 'show-bg' | 'primary' = 'default'; + @Input() type: IconButtonType = IconButtonTypes.DEFAULT; @Output() action = new EventEmitter(); } 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 d63f4486d..0064a4f40 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 @@ -11,6 +11,7 @@ import { import { FilterModel } from './model/filter.model'; import { handleCheckedValue } from './utils/filter-utils'; import { MAT_CHECKBOX_DEFAULT_OPTIONS } from '@angular/material/checkbox'; +import { TranslateService } from '@ngx-translate/core'; @Component({ selector: 'redaction-popup-filter', @@ -36,22 +37,20 @@ export class PopupFilterComponent implements OnChanges { @Input() actionsTemplate: TemplateRef; @Input() primaryFilters: FilterModel[] = []; @Input() secondaryFilters: FilterModel[] = []; - @Input() filterLabel = 'filter-menu.label'; + @Input() filterLabel = this._translateService.instant('filter-menu.label'); @Input() icon: string; @Input() chevron = false; atLeastOneFilterIsExpandable = false; atLeastOneSecondaryFilterIsExpandable = false; - constructor(private readonly _changeDetectorRef: ChangeDetectorRef) {} + constructor( + private readonly _changeDetectorRef: ChangeDetectorRef, + private readonly _translateService: TranslateService + ) {} get hasActiveFilters(): boolean { - for (const filter of this._allFilters) { - if (filter.checked || filter.indeterminate) { - return true; - } - } - return false; + return !!this._allFilters.find(f => f.checked || f.indeterminate); } private get _allFilters(): FilterModel[] { @@ -90,11 +89,11 @@ export class PopupFilterComponent implements OnChanges { } applyFilters() { - this._changeDetectorRef.detectChanges(); this.filtersChanged.emit({ primary: this.primaryFilters, secondary: this.secondaryFilters }); + this._changeDetectorRef.detectChanges(); } toggleFilterExpanded($event: MouseEvent, filter: FilterModel) { @@ -103,7 +102,7 @@ export class PopupFilterComponent implements OnChanges { } isExpandable(filter: FilterModel) { - return filter.filters && filter.filters.length > 0; + return filter?.filters?.length > 0; } _(obj): FilterModel { diff --git a/apps/red-ui/src/app/modules/shared/components/page-header/models/action-config.model.ts b/apps/red-ui/src/app/modules/shared/components/page-header/models/action-config.model.ts new file mode 100644 index 000000000..223953f8f --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/page-header/models/action-config.model.ts @@ -0,0 +1,5 @@ +import { BaseHeaderConfig } from './base-config.model'; + +export interface ActionConfig extends BaseHeaderConfig { + action: ($event) => void; +} diff --git a/apps/red-ui/src/app/modules/shared/components/page-header/models/base-config.model.ts b/apps/red-ui/src/app/modules/shared/components/page-header/models/base-config.model.ts new file mode 100644 index 000000000..238f47d39 --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/page-header/models/base-config.model.ts @@ -0,0 +1,5 @@ +export interface BaseHeaderConfig { + label: string; + icon?: string; + hide?: boolean; +} diff --git a/apps/red-ui/src/app/modules/shared/components/page-header/models/button-config.model.ts b/apps/red-ui/src/app/modules/shared/components/page-header/models/button-config.model.ts new file mode 100644 index 000000000..d9dca889e --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/page-header/models/button-config.model.ts @@ -0,0 +1,7 @@ +import { IconButtonType } from '../../buttons/icon-button/icon-button.component'; +import { BaseHeaderConfig } from './base-config.model'; + +export interface ButtonConfig extends BaseHeaderConfig { + action: ($event) => void; + type?: IconButtonType; +} diff --git a/apps/red-ui/src/app/modules/shared/components/page-header/models/filter-config.model.ts b/apps/red-ui/src/app/modules/shared/components/page-header/models/filter-config.model.ts new file mode 100644 index 000000000..29b749703 --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/page-header/models/filter-config.model.ts @@ -0,0 +1,8 @@ +import { FilterModel } from '../../filters/popup-filter/model/filter.model'; +import { TemplateRef } from '@angular/core'; +import { BaseHeaderConfig } from './base-config.model'; + +export interface FilterConfig extends BaseHeaderConfig { + primaryFilters: FilterModel[]; + filterTemplate?: TemplateRef; +} 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 index 99d20c336..c953293a9 100644 --- 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 @@ -1,5 +1,5 @@ -
- - - -
- - +
+ + + + + + + +
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 index 434b95fc1..acbdfdf11 100644 --- 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 @@ -1,3 +1,3 @@ -.page-header .actions > *:not(:last-child) { - margin-right: 16px; +.ml-6 { + margin-left: 6px; } 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 index 465871018..922ca72ce 100644 --- 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 @@ -5,33 +5,16 @@ import { 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'; -} +import { FormBuilder } from '@angular/forms'; +import { FilterConfig } from '@shared/components/page-header/models/filter-config.model'; +import { ActionConfig } from '@shared/components/page-header/models/action-config.model'; +import { ButtonConfig } from '@shared/components/page-header/models/button-config.model'; +import { BaseHeaderConfig } from '@shared/components/page-header/models/base-config.model'; @Component({ selector: 'redaction-page-header', @@ -42,14 +25,21 @@ export interface ButtonConfig extends BaseHeaderConfig { export class PageHeaderComponent { @Input() pageLabel: string; @Input() showCloseButton: boolean; + @Input() showResetFilters: boolean; @Input() filterConfigs: FilterConfig[]; @Input() actionConfigs: ActionConfig[]; @Input() buttonConfigs: ButtonConfig[]; @Input() searchPlaceholder: string; - @Output() filtersChanged = new EventEmitter(); + @Output() filtersChanged = new EventEmitter<{ + primary: FilterModel[]; + secondary?: FilterModel[]; + }>(); + @Output() filtersReset = new EventEmitter(); @Output() searchChanged = new EventEmitter(); - searchForm: FormGroup; + readonly searchForm = this._formBuilder.group({ + query: [''] + }); @ViewChildren(PopupFilterComponent) private readonly _filterComponents: QueryList; @@ -58,34 +48,24 @@ export class PageHeaderComponent { readonly permissionsService: PermissionsService, private readonly _formBuilder: FormBuilder ) { - this._initSearch(); + this.searchForm.valueChanges.subscribe(value => this.searchChanged.emit(value.query)); } get hasActiveFilters() { - return ( - this._filterComponents - ?.filter(f => !!f) - .reduce((prev, component) => prev || component?.hasActiveFilters, false) || - this.searchForm.get('query').value + const hasActiveFilters = this._filterComponents?.reduce( + (acc, component) => acc || component?.hasActiveFilters, + false ); + return hasActiveFilters || this.searchForm.get('query').value || this.showResetFilters; } resetFilters() { - for (const filterComponent of this._filterComponents.filter(f => !!f)) { - filterComponent.deactivateFilters(); - } - this.filtersChanged.emit(); + this._filterComponents.forEach(component => component?.deactivateFilters()); + + this.filtersReset.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; }