common-ui/src/lib/listing/page-header/page-header.component.ts

84 lines
3.4 KiB
TypeScript

import { AsyncPipe, NgTemplateOutlet } from '@angular/common';
import { ChangeDetectionStrategy, Component, computed, inject, input, output, TemplateRef } from '@angular/core';
import { TranslateModule } from '@ngx-translate/core';
import { combineLatest, Observable, of } from 'rxjs';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { CircleButtonComponent } from '../../buttons';
import { IconButtonComponent } from '../../buttons';
import { IconButtonTypes } from '../../buttons';
import { FilterService } from '../../filtering';
import { IqserFiltersModule } from '../../filtering';
import { PopupFilterComponent } from '../../filtering';
import { InputWithActionComponent } from '../../inputs/input-with-action/input-with-action.component';
import { SearchService } from '../../search';
import { filterEach } from '../../utils';
import { List } from '../../utils';
import { IListable } from '../models';
import { ActionConfig, ButtonConfig, SearchPosition, SearchPositions } from './models';
import { MatTooltip } from '@angular/material/tooltip';
@Component({
selector: 'iqser-page-header',
templateUrl: './page-header.component.html',
styleUrls: ['./page-header.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [
AsyncPipe,
NgTemplateOutlet,
PopupFilterComponent,
IqserFiltersModule,
IconButtonComponent,
CircleButtonComponent,
TranslateModule,
InputWithActionComponent,
MatTooltip,
],
})
export class PageHeaderComponent<T extends IListable> {
readonly searchPositions = SearchPositions;
readonly iconButtonTypes = IconButtonTypes;
readonly filterService = inject(FilterService, { optional: true });
readonly searchService = inject<SearchService<T>>(SearchService<T>, { optional: true });
readonly pageLabel = input<string>();
readonly searchInputId = input<string>();
readonly showCloseButton = input(false);
readonly hideResetButton = input(false);
readonly actionConfigs = input<List<ActionConfig>>();
readonly buttonConfigs = input<List<ButtonConfig>>();
readonly viewModeSelection = input<TemplateRef<unknown>>();
readonly searchPlaceholder = input<string>();
readonly searchWidth = input<number | 'full'>();
readonly helpModeKey = input<'dossier' | 'document'>();
readonly searchPosition = input<SearchPosition>(SearchPositions.afterFilters);
readonly closeAction = output();
readonly filterHelpModeKey = computed(() =>
this.helpModeKey() ? (this.helpModeKey() === 'dossier' ? 'filter_dossier_list' : 'filter_documents') : '',
);
readonly filters$ = this.filterService?.filterGroups$.pipe(filterEach(f => !!f.icon));
readonly showResetFilters$ = this.#showResetFilters$;
get #showResetFilters$(): Observable<boolean> {
if (!this.filterService) {
return of(false);
}
return combineLatest([this.filterService.showResetFilters$, this.searchService?.valueChanges$ ?? of(undefined)]).pipe(
map(([showResetFilters, searchValue]) => showResetFilters || !!searchValue),
distinctUntilChanged(),
);
}
resetFilters(): void {
this.filterService?.reset();
this.searchService?.reset();
}
trackByLabel<K extends { label?: string }>(_index: number, item: K): string | undefined {
return item.label;
}
}