Moved page header

This commit is contained in:
Adina Țeudan 2021-10-02 22:13:54 +03:00
parent 36fbb00660
commit 4c45c6f38b
10 changed files with 160 additions and 1 deletions

View File

@ -12,3 +12,6 @@ export * from './sync-width.directive';
export * from './listing.module';
export * from './listing-component.directive';
export * from './page-header/page-header.component';
export * from './page-header/models';

View File

@ -16,15 +16,25 @@ import { RouterModule } from '@angular/router';
import { IqserEmptyStatesModule } from '../empty-states';
import { WorkflowComponent } from './workflow/workflow.component';
import { DragDropModule } from '@angular/cdk/drag-drop';
import { PageHeaderComponent } from './page-header/page-header.component';
import { IqserButtonsModule } from '../buttons';
const matModules = [MatTooltipModule];
const components = [TableHeaderComponent, TableComponent, WorkflowComponent, TableColumnNameComponent, ScrollButtonComponent];
const components = [
TableHeaderComponent,
TableComponent,
WorkflowComponent,
TableColumnNameComponent,
ScrollButtonComponent,
PageHeaderComponent
];
const modules = [
DragDropModule,
TranslateModule,
IqserFiltersModule,
IqserInputsModule,
IqserIconsModule,
IqserButtonsModule,
IqserScrollbarModule,
IqserEmptyStatesModule,
ScrollingModule,

View File

@ -0,0 +1,5 @@
import { BaseHeaderConfig } from './base-config.model';
export interface ActionConfig extends BaseHeaderConfig {
readonly action: ($event: MouseEvent) => void;
}

View File

@ -0,0 +1,5 @@
export interface BaseHeaderConfig {
readonly label: string;
readonly icon?: string;
readonly hide?: boolean;
}

View File

@ -0,0 +1,6 @@
import { IconButtonType } from '@iqser/common-ui';
import { ActionConfig } from './action-config.model';
export interface ButtonConfig extends ActionConfig {
readonly type?: IconButtonType;
}

View File

@ -0,0 +1,4 @@
export * from './action-config.model';
export * from './base-config.model';
export * from './button-config.model';
export * from './search-positions.type';

View File

@ -0,0 +1,6 @@
export const SearchPositions = {
beforeFilters: 'beforeFilters',
afterFilters: 'afterFilters'
} as const;
export type SearchPosition = keyof typeof SearchPositions;

View File

@ -0,0 +1,63 @@
<div class="page-header">
<div *ngIf="pageLabel" class="breadcrumb">{{ pageLabel }}</div>
<div *ngIf="filters$ | async as filters" class="filters">
<div *ngIf="filters.length && searchPosition !== searchPositions.beforeFilters" translate="filters.filter-by"></div>
<ng-container *ngIf="searchPosition === searchPositions.beforeFilters" [ngTemplateOutlet]="searchBar"></ng-container>
<ng-container *ngFor="let config of filters; trackBy: trackByLabel">
<iqser-popup-filter *ngIf="!config.hide" [primaryFiltersSlug]="config.slug"></iqser-popup-filter>
</ng-container>
<ng-container *ngIf="searchPosition === searchPositions.afterFilters" [ngTemplateOutlet]="searchBar"></ng-container>
<div (click)="resetFilters()" *ngIf="showResetFilters$ | async" class="reset-filters" translate="reset-filters"></div>
</div>
<div *ngIf="showCloseButton || actionConfigs || buttonConfigs || viewModeSelection" class="actions">
<ng-container [ngTemplateOutlet]="viewModeSelection"></ng-container>
<ng-container *ngFor="let config of buttonConfigs; trackBy: trackByLabel">
<iqser-icon-button
(action)="config.action($event)"
*ngIf="!config.hide"
[icon]="config.icon"
[label]="config.label | translate"
[type]="config.type"
></iqser-icon-button>
</ng-container>
<ng-container *ngFor="let config of actionConfigs; trackBy: trackByLabel">
<iqser-circle-button
(action)="config.action($event)"
*ngIf="!config.hide"
[icon]="config.icon"
[tooltip]="config.label"
tooltipPosition="below"
></iqser-circle-button>
</ng-container>
<!-- Extra custom actions here -->
<ng-content></ng-content>
<iqser-circle-button
(action)="closeAction.emit()"
*ngIf="showCloseButton"
[class.ml-6]="actionConfigs"
[tooltip]="'common.close' | translate"
icon="iqser:close"
tooltipPosition="below"
></iqser-circle-button>
</div>
</div>
<ng-template #searchBar>
<iqser-input-with-action
*ngIf="searchPlaceholder && searchService"
[(value)]="searchService.searchValue"
[class.mr-8]="searchPosition === searchPositions.beforeFilters"
[placeholder]="searchPlaceholder"
[width]="searchWidth"
></iqser-input-with-action>
</ng-template>

View File

@ -0,0 +1,3 @@
.ml-6 {
margin-left: 6px;
}

View File

@ -0,0 +1,54 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Optional, Output, TemplateRef } from '@angular/core';
import { ActionConfig, ButtonConfig, SearchPosition, SearchPositions } from './models';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { combineLatest, Observable, of } from 'rxjs';
import { IListable } from '../models';
import { IconButtonTypes } from '../../buttons';
import { SearchService } from '../../search';
import { FilterService } from '../../filtering';
@Component({
selector: 'iqser-page-header',
templateUrl: './page-header.component.html',
styleUrls: ['./page-header.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PageHeaderComponent<T extends IListable> {
readonly searchPositions = SearchPositions;
readonly iconButtonTypes = IconButtonTypes;
@Input() pageLabel?: string;
@Input() showCloseButton: boolean = false;
@Input() actionConfigs?: readonly ActionConfig[];
@Input() buttonConfigs?: readonly ButtonConfig[];
@Input() viewModeSelection?: TemplateRef<unknown>;
@Input() searchPlaceholder?: string;
@Input() searchWidth?: number | 'full';
@Input() searchPosition: SearchPosition = SearchPositions.afterFilters;
@Output() readonly closeAction = new EventEmitter();
readonly filters$ = this.filterService?.filterGroups$.pipe(map(all => all.filter(f => f.icon)));
readonly showResetFilters$ = this._showResetFilters$;
constructor(@Optional() readonly filterService: FilterService, @Optional() readonly searchService: SearchService<T>) {}
get _showResetFilters$(): Observable<boolean> {
if (!this.filterService) {
return of(false);
}
return combineLatest([this.filterService.showResetFilters$, this.searchService.valueChanges$]).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;
}
}