wip page header component
This commit is contained in:
parent
5adf7379c9
commit
fe8bc8826d
@ -1,17 +1,7 @@
|
|||||||
<section>
|
<section>
|
||||||
<div class="overlay-shadow"></div>
|
<div class="overlay-shadow"></div>
|
||||||
|
|
||||||
<div class="page-header">
|
<redaction-page-header pageLabel="trash.label" [showCloseButton]="true"></redaction-page-header>
|
||||||
<div class="breadcrumb" translate="trash.label"></div>
|
|
||||||
|
|
||||||
<redaction-circle-button
|
|
||||||
*ngIf="permissionsService.isUser()"
|
|
||||||
icon="red:close"
|
|
||||||
redactionNavigateLastDossiersScreen
|
|
||||||
tooltip="common.close"
|
|
||||||
tooltipPosition="below"
|
|
||||||
></redaction-circle-button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="red-content-inner">
|
<div class="red-content-inner">
|
||||||
<div class="content-container">
|
<div class="content-container">
|
||||||
|
|||||||
@ -38,7 +38,3 @@ redaction-table-col-name::ng-deep {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-header .actions > *:not(:last-child) {
|
|
||||||
margin-right: 16px;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,53 +1,11 @@
|
|||||||
<section>
|
<section>
|
||||||
<div class="page-header">
|
<redaction-page-header
|
||||||
<div class="filters">
|
(filtersChanged)="filtersChanged()"
|
||||||
<div translate="filters.filter-by"></div>
|
(searchChanged)="executeSearch($event)"
|
||||||
<redaction-popup-filter
|
[filterConfigs]="filterConfigs"
|
||||||
(filtersChanged)="filtersChanged()"
|
[buttonConfigs]="buttonConfigs"
|
||||||
[filterLabel]="'filters.status'"
|
[searchPlaceholder]="'dossier-listing.search'"
|
||||||
[icon]="'red:status'"
|
></redaction-page-header>
|
||||||
[primaryFilters]="statusFilters"
|
|
||||||
></redaction-popup-filter>
|
|
||||||
<redaction-popup-filter
|
|
||||||
(filtersChanged)="filtersChanged()"
|
|
||||||
[filterLabel]="'filters.people'"
|
|
||||||
[icon]="'red:user'"
|
|
||||||
[primaryFilters]="peopleFilters"
|
|
||||||
></redaction-popup-filter>
|
|
||||||
<redaction-popup-filter
|
|
||||||
(filtersChanged)="filtersChanged()"
|
|
||||||
[filterLabel]="'filters.needs-work'"
|
|
||||||
[filterTemplate]="needsWorkTemplate"
|
|
||||||
[icon]="'red:needs-work'"
|
|
||||||
[primaryFilters]="needsWorkFilters"
|
|
||||||
></redaction-popup-filter>
|
|
||||||
<redaction-popup-filter
|
|
||||||
(filtersChanged)="filtersChanged()"
|
|
||||||
*ngIf="dossierTemplateFilters.length > 1"
|
|
||||||
[filterLabel]="'filters.dossier-templates'"
|
|
||||||
[icon]="'red:template'"
|
|
||||||
[primaryFilters]="dossierTemplateFilters"
|
|
||||||
></redaction-popup-filter>
|
|
||||||
<redaction-input-with-action
|
|
||||||
[form]="searchForm"
|
|
||||||
placeholder="dossier-listing.search"
|
|
||||||
type="search"
|
|
||||||
></redaction-input-with-action>
|
|
||||||
<div
|
|
||||||
(click)="resetFilters()"
|
|
||||||
*ngIf="hasActiveFilters"
|
|
||||||
class="reset-filters"
|
|
||||||
translate="reset-filters"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
<redaction-icon-button
|
|
||||||
(action)="openAddDossierDialog()"
|
|
||||||
*ngIf="permissionsService.isManager()"
|
|
||||||
icon="red:plus"
|
|
||||||
text="dossier-listing.add-new"
|
|
||||||
type="primary"
|
|
||||||
></redaction-icon-button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="overlay-shadow"></div>
|
<div class="overlay-shadow"></div>
|
||||||
|
|
||||||
@ -135,7 +93,7 @@
|
|||||||
<div class="small-label stats-subtitle">
|
<div class="small-label stats-subtitle">
|
||||||
<div>
|
<div>
|
||||||
<mat-icon svgIcon="red:document"></mat-icon>
|
<mat-icon svgIcon="red:document"></mat-icon>
|
||||||
{{ documentCount(dw) }}
|
{{ filesCount(dw) }}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<mat-icon svgIcon="red:pages"></mat-icon>
|
<mat-icon svgIcon="red:pages"></mat-icon>
|
||||||
|
|||||||
@ -1,12 +1,4 @@
|
|||||||
import {
|
import { Component, Injector, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
||||||
Component,
|
|
||||||
Injector,
|
|
||||||
OnDestroy,
|
|
||||||
OnInit,
|
|
||||||
QueryList,
|
|
||||||
ViewChild,
|
|
||||||
ViewChildren
|
|
||||||
} from '@angular/core';
|
|
||||||
import { Dossier, DossierTemplateModel } from '@redaction/red-ui-http';
|
import { Dossier, DossierTemplateModel } from '@redaction/red-ui-http';
|
||||||
import { AppStateService } from '@state/app-state.service';
|
import { AppStateService } from '@state/app-state.service';
|
||||||
import { UserService } from '@services/user.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 { BaseListingComponent } from '@shared/base/base-listing.component';
|
||||||
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
|
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
|
||||||
import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model';
|
import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model';
|
||||||
import { PopupFilterComponent } from '@shared/components/filters/popup-filter/popup-filter.component';
|
|
||||||
import {
|
import {
|
||||||
annotationFilterChecker,
|
annotationFilterChecker,
|
||||||
dossierMemberChecker,
|
dossierMemberChecker,
|
||||||
@ -33,11 +24,11 @@ import {
|
|||||||
dossierTemplateChecker,
|
dossierTemplateChecker,
|
||||||
processFilters
|
processFilters
|
||||||
} from '@shared/components/filters/popup-filter/utils/filter-utils';
|
} 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 { UserPreferenceService } from '../../../../services/user-preference.service';
|
||||||
|
import { ButtonConfig, FilterConfig } from '@shared/components/page-header/page-header.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redaction-dossier-listing-screen',
|
|
||||||
templateUrl: './dossier-listing-screen.component.html',
|
templateUrl: './dossier-listing-screen.component.html',
|
||||||
styleUrls: ['./dossier-listing-screen.component.scss']
|
styleUrls: ['./dossier-listing-screen.component.scss']
|
||||||
})
|
})
|
||||||
@ -58,6 +49,16 @@ export class DossierListingScreenComponent
|
|||||||
};
|
};
|
||||||
quickFilters: FilterModel[];
|
quickFilters: FilterModel[];
|
||||||
readonly itemSize = 85;
|
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 _searchKey = 'name';
|
||||||
protected readonly _sortKey = 'dossier-listing';
|
protected readonly _sortKey = 'dossier-listing';
|
||||||
@ -67,10 +68,10 @@ export class DossierListingScreenComponent
|
|||||||
private _routerEventsScrollPositionSub: Subscription;
|
private _routerEventsScrollPositionSub: Subscription;
|
||||||
private _fileChangedSub: Subscription;
|
private _fileChangedSub: Subscription;
|
||||||
|
|
||||||
@ViewChildren(PopupFilterComponent)
|
|
||||||
private readonly _filterList: QueryList<PopupFilterComponent>;
|
|
||||||
@ViewChild(QuickFiltersComponent)
|
@ViewChild(QuickFiltersComponent)
|
||||||
protected readonly _quickFiltersComponent: QuickFiltersComponent;
|
protected readonly _quickFiltersComponent: QuickFiltersComponent;
|
||||||
|
@ViewChild('needsWorkTemplate', { read: TemplateRef, static: true })
|
||||||
|
private readonly _needsWorkTemplate: TemplateRef<any>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly permissionsService: PermissionsService,
|
readonly permissionsService: PermissionsService,
|
||||||
@ -155,7 +156,7 @@ export class DossierListingScreenComponent
|
|||||||
this._lastScrollPosition = this.scrollViewport.measureScrollOffset('top');
|
this._lastScrollPosition = this.scrollViewport.measureScrollOffset('top');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this._filterComponents = [...this._filterList.toArray(), this._quickFiltersComponent];
|
this._filterComponents = [this._quickFiltersComponent];
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnAttach() {
|
ngOnAttach() {
|
||||||
@ -175,7 +176,7 @@ export class DossierListingScreenComponent
|
|||||||
this._fileChangedSub.unsubscribe();
|
this._fileChangedSub.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
documentCount(dossier: DossierWrapper) {
|
filesCount(dossier: DossierWrapper) {
|
||||||
return dossier.files.length;
|
return dossier.files.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,12 +249,9 @@ export class DossierListingScreenComponent
|
|||||||
const allDistinctDossierTemplates = new Set<string>();
|
const allDistinctDossierTemplates = new Set<string>();
|
||||||
this.allEntities.forEach(entry => {
|
this.allEntities.forEach(entry => {
|
||||||
// all people
|
// all people
|
||||||
entry.dossier.memberIds.forEach(memberId => allDistinctPeople.add(memberId));
|
entry.dossier.memberIds.forEach(f => allDistinctPeople.add(f));
|
||||||
// file statuses
|
// file statuses
|
||||||
entry.files.forEach(file => {
|
entry.files.forEach(f => allDistinctFileStatus.add(f.status));
|
||||||
allDistinctFileStatus.add(file.status);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Needs work
|
// Needs work
|
||||||
entry.files.forEach(file => {
|
entry.files.forEach(file => {
|
||||||
if (this.permissionsService.fileRequiresReanalysis(file))
|
if (this.permissionsService.fileRequiresReanalysis(file))
|
||||||
@ -312,7 +310,39 @@ export class DossierListingScreenComponent
|
|||||||
dossierTemplateFilters
|
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,
|
key: this.user.id,
|
||||||
label: 'dossier-listing.quick-filters.my-dossiers',
|
label: 'dossier-listing.quick-filters.my-dossiers',
|
||||||
@ -333,7 +363,9 @@ export class DossierListingScreenComponent
|
|||||||
label: 'dossier-listing.quick-filters.other',
|
label: 'dossier-listing.quick-filters.other',
|
||||||
checker: (dw: DossierWrapper) => !dw.memberIds.includes(this.user.id)
|
checker: (dw: DossierWrapper) => !dw.memberIds.includes(this.user.id)
|
||||||
}
|
}
|
||||||
].filter(
|
];
|
||||||
|
|
||||||
|
this.quickFilters = filters.filter(
|
||||||
f =>
|
f =>
|
||||||
f.label === 'dossier-listing.quick-filters.my-dossiers' ||
|
f.label === 'dossier-listing.quick-filters.my-dossiers' ||
|
||||||
this._userPreferenceService.areDevFeaturesEnabled
|
this._userPreferenceService.areDevFeaturesEnabled
|
||||||
|
|||||||
@ -1,84 +1,91 @@
|
|||||||
<section *ngIf="!!activeDossier">
|
<section *ngIf="!!activeDossier">
|
||||||
<div class="page-header">
|
<redaction-page-header
|
||||||
<div class="filters">
|
(filtersChanged)="filtersChanged()"
|
||||||
<div translate="filters.filter-by"></div>
|
(searchChanged)="executeSearch($event)"
|
||||||
<redaction-popup-filter
|
[filterConfigs]="filterConfigs"
|
||||||
(filtersChanged)="filtersChanged()"
|
[actionConfigs]="actionConfigs"
|
||||||
[filterLabel]="'filters.status'"
|
[searchPlaceholder]="'dossier-overview.search'"
|
||||||
[icon]="'red:status'"
|
></redaction-page-header>
|
||||||
[primaryFilters]="statusFilters"
|
<!-- <div class="page-header">-->
|
||||||
></redaction-popup-filter>
|
<!-- <div class="filters">-->
|
||||||
<redaction-popup-filter
|
<!-- <div translate="filters.filter-by"></div>-->
|
||||||
(filtersChanged)="filtersChanged()"
|
<!-- <redaction-popup-filter-->
|
||||||
[filterLabel]="'filters.assigned-people'"
|
<!-- (filtersChanged)="filtersChanged()"-->
|
||||||
[icon]="'red:user'"
|
<!-- [filterLabel]="'filters.status'"-->
|
||||||
[primaryFilters]="peopleFilters"
|
<!-- [icon]="'red:status'"-->
|
||||||
></redaction-popup-filter>
|
<!-- [primaryFilters]="statusFilters"-->
|
||||||
<redaction-popup-filter
|
<!-- ></redaction-popup-filter>-->
|
||||||
(filtersChanged)="filtersChanged()"
|
<!-- <redaction-popup-filter-->
|
||||||
[filterLabel]="'filters.needs-work'"
|
<!-- (filtersChanged)="filtersChanged()"-->
|
||||||
[filterTemplate]="needsWorkTemplate"
|
<!-- [filterLabel]="'filters.assigned-people'"-->
|
||||||
[icon]="'red:needs-work'"
|
<!-- [icon]="'red:user'"-->
|
||||||
[primaryFilters]="needsWorkFilters"
|
<!-- [primaryFilters]="peopleFilters"-->
|
||||||
></redaction-popup-filter>
|
<!-- ></redaction-popup-filter>-->
|
||||||
|
<!-- <redaction-popup-filter-->
|
||||||
|
<!-- (filtersChanged)="filtersChanged()"-->
|
||||||
|
<!-- [filterLabel]="'filters.needs-work'"-->
|
||||||
|
<!-- [filterTemplate]="needsWorkTemplate"-->
|
||||||
|
<!-- [icon]="'red:needs-work'"-->
|
||||||
|
<!-- [primaryFilters]="needsWorkFilters"-->
|
||||||
|
<!-- ></redaction-popup-filter>-->
|
||||||
|
|
||||||
<redaction-input-with-action
|
<!-- <redaction-input-with-action-->
|
||||||
[form]="searchForm"
|
<!-- [form]="searchForm"-->
|
||||||
placeholder="dossier-overview.search"
|
<!-- [placeholder]="'dossier-overview.search'"-->
|
||||||
type="search"
|
<!-- type="search"-->
|
||||||
></redaction-input-with-action>
|
<!-- ></redaction-input-with-action>-->
|
||||||
|
|
||||||
<div
|
<!-- <div-->
|
||||||
(click)="resetFilters()"
|
<!-- (click)="resetFilters()"-->
|
||||||
*ngIf="hasActiveFilters"
|
<!-- *ngIf="hasActiveFilters"-->
|
||||||
class="reset-filters"
|
<!-- class="reset-filters"-->
|
||||||
translate="reset-filters"
|
<!-- translate="reset-filters"-->
|
||||||
></div>
|
<!-- ></div>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
|
|
||||||
<div class="actions">
|
<!-- <div class="actions">-->
|
||||||
<redaction-circle-button
|
<!-- <redaction-circle-button-->
|
||||||
(action)="openEditDossierDialog($event)"
|
<!-- (action)="openEditDossierDialog($event)"-->
|
||||||
*ngIf="permissionsService.isManager()"
|
<!-- *ngIf="permissionsService.isManager()"-->
|
||||||
icon="red:edit"
|
<!-- icon="red:edit"-->
|
||||||
tooltip="dossier-overview.header-actions.edit"
|
<!-- tooltip="dossier-overview.header-actions.edit"-->
|
||||||
tooltipPosition="below"
|
<!-- tooltipPosition="below"-->
|
||||||
></redaction-circle-button>
|
<!-- ></redaction-circle-button>-->
|
||||||
|
|
||||||
<redaction-file-download-btn
|
<!-- <redaction-file-download-btn-->
|
||||||
[disabled]="areSomeEntitiesSelected"
|
<!-- [disabled]="areSomeEntitiesSelected"-->
|
||||||
[dossier]="activeDossier"
|
<!-- [dossier]="activeDossier"-->
|
||||||
[file]="allEntities"
|
<!-- [file]="allEntities"-->
|
||||||
tooltipPosition="below"
|
<!-- tooltipPosition="below"-->
|
||||||
></redaction-file-download-btn>
|
<!-- ></redaction-file-download-btn>-->
|
||||||
|
|
||||||
<redaction-circle-button
|
<!-- <redaction-circle-button-->
|
||||||
(action)="reanalyseDossier()"
|
<!-- (action)="reanalyseDossier()"-->
|
||||||
*ngIf="permissionsService.displayReanalyseBtn()"
|
<!-- *ngIf="permissionsService.displayReanalyseBtn()"-->
|
||||||
[disabled]="areSomeEntitiesSelected"
|
<!-- [disabled]="areSomeEntitiesSelected"-->
|
||||||
[tooltipClass]="'small ' + (areSomeEntitiesSelected ? '' : 'warn')"
|
<!-- [tooltipClass]="'small ' + (areSomeEntitiesSelected ? '' : 'warn')"-->
|
||||||
[tooltip]="'dossier-overview.new-rule.toast.actions.reanalyse-all'"
|
<!-- [tooltip]="'dossier-overview.new-rule.toast.actions.reanalyse-all'"-->
|
||||||
icon="red:refresh"
|
<!-- icon="red:refresh"-->
|
||||||
tooltipPosition="below"
|
<!-- tooltipPosition="below"-->
|
||||||
type="warn"
|
<!-- type="warn"-->
|
||||||
></redaction-circle-button>
|
<!-- ></redaction-circle-button>-->
|
||||||
<redaction-circle-button
|
<!-- <redaction-circle-button-->
|
||||||
(action)="fileInput.click()"
|
<!-- (action)="fileInput.click()"-->
|
||||||
class="ml-14"
|
<!-- class="ml-14"-->
|
||||||
icon="red:upload"
|
<!-- icon="red:upload"-->
|
||||||
tooltip="dossier-overview.header-actions.upload-document"
|
<!-- tooltip="dossier-overview.header-actions.upload-document"-->
|
||||||
tooltipPosition="below"
|
<!-- tooltipPosition="below"-->
|
||||||
type="primary"
|
<!-- type="primary"-->
|
||||||
></redaction-circle-button>
|
<!-- ></redaction-circle-button>-->
|
||||||
<redaction-circle-button
|
<!-- <redaction-circle-button-->
|
||||||
[routerLink]="['/main/dossiers/']"
|
<!-- [routerLink]="['/main/dossiers/']"-->
|
||||||
class="ml-6"
|
<!-- class="ml-6"-->
|
||||||
icon="red:close"
|
<!-- icon="red:close"-->
|
||||||
tooltip="common.close"
|
<!-- tooltip="common.close"-->
|
||||||
tooltipPosition="below"
|
<!-- tooltipPosition="below"-->
|
||||||
></redaction-circle-button>
|
<!-- ></redaction-circle-button>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
|
|
||||||
<div class="overlay-shadow"></div>
|
<div class="overlay-shadow"></div>
|
||||||
|
|
||||||
|
|||||||
@ -5,9 +5,8 @@ import {
|
|||||||
Injector,
|
Injector,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
OnInit,
|
OnInit,
|
||||||
QueryList,
|
TemplateRef,
|
||||||
ViewChild,
|
ViewChild
|
||||||
ViewChildren
|
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { NavigationStart, Router } from '@angular/router';
|
import { NavigationStart, Router } from '@angular/router';
|
||||||
import { NotificationService, NotificationType } from '@services/notification.service';
|
import { NotificationService, NotificationType } from '@services/notification.service';
|
||||||
@ -38,9 +37,12 @@ import {
|
|||||||
processFilters
|
processFilters
|
||||||
} from '@shared/components/filters/popup-filter/utils/filter-utils';
|
} from '@shared/components/filters/popup-filter/utils/filter-utils';
|
||||||
import { FilterModel } from '@shared/components/filters/popup-filter/model/filter.model';
|
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 { QuickFiltersComponent } from '../../../shared/components/filters/quick-filters/quick-filters.component';
|
||||||
import { AppConfigService } from '../../../app-config/app-config.service';
|
import { AppConfigService } from '../../../app-config/app-config.service';
|
||||||
|
import {
|
||||||
|
ActionConfig,
|
||||||
|
FilterConfig
|
||||||
|
} from '../../../shared/components/page-header/page-header.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redaction-dossier-overview-screen',
|
selector: 'redaction-dossier-overview-screen',
|
||||||
@ -61,6 +63,8 @@ export class DossierOverviewScreenComponent
|
|||||||
} = { needsWorkFilters: [], statusFilters: [] };
|
} = { needsWorkFilters: [], statusFilters: [] };
|
||||||
readonly itemSize = 80;
|
readonly itemSize = 80;
|
||||||
quickFilters: FilterModel[];
|
quickFilters: FilterModel[];
|
||||||
|
filterConfigs: FilterConfig[];
|
||||||
|
actionConfigs: ActionConfig[];
|
||||||
|
|
||||||
protected readonly _searchKey = 'searchField';
|
protected readonly _searchKey = 'searchField';
|
||||||
protected readonly _selectionKey = 'fileId';
|
protected readonly _selectionKey = 'fileId';
|
||||||
@ -74,11 +78,10 @@ export class DossierOverviewScreenComponent
|
|||||||
private _lastScrollPosition: number;
|
private _lastScrollPosition: number;
|
||||||
private _lastOpenedFileId = '';
|
private _lastOpenedFileId = '';
|
||||||
|
|
||||||
@ViewChildren(PopupFilterComponent)
|
|
||||||
private readonly _filterList: QueryList<PopupFilterComponent>;
|
|
||||||
@ViewChild(QuickFiltersComponent)
|
@ViewChild(QuickFiltersComponent)
|
||||||
protected readonly _quickFiltersComponent: QuickFiltersComponent;
|
protected readonly _quickFiltersComponent: QuickFiltersComponent;
|
||||||
|
@ViewChild('needsWorkTemplate', { read: TemplateRef, static: true })
|
||||||
|
private readonly _needsWorkTemplate: TemplateRef<any>;
|
||||||
@ViewChild('fileInput') private _fileInput: ElementRef;
|
@ViewChild('fileInput') private _fileInput: ElementRef;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -182,7 +185,7 @@ export class DossierOverviewScreenComponent
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this._filterComponents = [...this._filterList.toArray(), this._quickFiltersComponent];
|
this._filterComponents = [this._quickFiltersComponent];
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
@ -393,10 +396,12 @@ export class DossierOverviewScreenComponent
|
|||||||
);
|
);
|
||||||
this.needsWorkFilters = processFilters(this.needsWorkFilters, needsWorkFilters);
|
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) {
|
if (this.allEntities.filter(this.recentlyModifiedChecker).length > 0) {
|
||||||
const recentPeriodInHours = this._appConfigService.getConfig('RECENT_PERIOD_IN_HOURS');
|
const recentPeriodInHours = this._appConfigService.getConfig('RECENT_PERIOD_IN_HOURS');
|
||||||
this.quickFilters = [
|
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()
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,20 +33,12 @@ export abstract class BaseListingComponent<T = any> {
|
|||||||
// Overwrite this in ngOnInit
|
// Overwrite this in ngOnInit
|
||||||
protected _filterComponents: (PopupFilterComponent | QuickFiltersComponent)[] = [];
|
protected _filterComponents: (PopupFilterComponent | QuickFiltersComponent)[] = [];
|
||||||
|
|
||||||
|
private _searchValue = '';
|
||||||
|
|
||||||
protected constructor(protected readonly _injector: Injector) {
|
protected constructor(protected readonly _injector: Injector) {
|
||||||
this._formBuilder = this._injector.get<FormBuilder>(FormBuilder);
|
this._formBuilder = this._injector.get<FormBuilder>(FormBuilder);
|
||||||
this._changeDetectorRef = this._injector.get<ChangeDetectorRef>(ChangeDetectorRef);
|
this._changeDetectorRef = this._injector.get<ChangeDetectorRef>(ChangeDetectorRef);
|
||||||
this._sortingService = this._injector.get<SortingService>(SortingService);
|
this._sortingService = this._injector.get<SortingService>(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() {
|
get areAllEntitiesSelected() {
|
||||||
@ -108,10 +100,9 @@ export abstract class BaseListingComponent<T = any> {
|
|||||||
|
|
||||||
resetFilters() {
|
resetFilters() {
|
||||||
for (const filterComponent of this._filterComponents.filter(f => !!f)) {
|
for (const filterComponent of this._filterComponents.filter(f => !!f)) {
|
||||||
filterComponent.deactivateAllFilters();
|
filterComponent.deactivateFilters();
|
||||||
}
|
}
|
||||||
this.filtersChanged();
|
this.filtersChanged();
|
||||||
this.searchForm.reset({ query: '' });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter
|
// Filter
|
||||||
@ -155,7 +146,8 @@ export abstract class BaseListingComponent<T = any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@debounce(200)
|
@debounce(200)
|
||||||
protected _executeSearch() {
|
executeSearch(value: string) {
|
||||||
|
this._searchValue = value;
|
||||||
this._executeSearchImmediately();
|
this._executeSearchImmediately();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,10 +155,9 @@ export abstract class BaseListingComponent<T = any> {
|
|||||||
this.displayedEntities = (
|
this.displayedEntities = (
|
||||||
this._filters.length ? this.filteredEntities : this.allEntities
|
this._filters.length ? this.filteredEntities : this.allEntities
|
||||||
).filter(entity =>
|
).filter(entity =>
|
||||||
this._searchField(entity)
|
this._searchField(entity).toLowerCase().includes(this._searchValue.toLowerCase())
|
||||||
.toLowerCase()
|
|
||||||
.includes(this.searchForm.get('query').value.toLowerCase())
|
|
||||||
);
|
);
|
||||||
|
|
||||||
this._updateSelection();
|
this._updateSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,15 +174,7 @@ export abstract class BaseListingComponent<T = any> {
|
|||||||
protected _filterEntities() {
|
protected _filterEntities() {
|
||||||
this._preFilter();
|
this._preFilter();
|
||||||
this.filteredEntities = getFilteredEntities(this.allEntities, this._filters);
|
this.filteredEntities = getFilteredEntities(this.allEntities, this._filters);
|
||||||
this._executeSearch();
|
this.executeSearch(this._searchValue);
|
||||||
this._changeDetectorRef.detectChanges();
|
this._changeDetectorRef.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _initSearch() {
|
|
||||||
this.searchForm = this._formBuilder.group({
|
|
||||||
query: ['']
|
|
||||||
});
|
|
||||||
|
|
||||||
this.searchForm.valueChanges.subscribe(() => this._executeSearch());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,10 +16,10 @@
|
|||||||
<mat-menu
|
<mat-menu
|
||||||
#filterMenu="matMenu"
|
#filterMenu="matMenu"
|
||||||
(closed)="applyFilters()"
|
(closed)="applyFilters()"
|
||||||
[class]="secondaryFilters?.length > 0 ? 'padding-bottom-0' : ''"
|
[class.padding-bottom-0]="secondaryFilters?.length > 0"
|
||||||
xPosition="before"
|
xPosition="before"
|
||||||
>
|
>
|
||||||
<div (mouseenter)="filterMouseEnter()" (mouseleave)="filterMouseLeave()">
|
<ng-template matMenuContent>
|
||||||
<div class="filter-menu-header">
|
<div class="filter-menu-header">
|
||||||
<div class="all-caps-label" translate="filter-menu.filter-types"></div>
|
<div class="all-caps-label" translate="filter-menu.filter-types"></div>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
@ -35,30 +35,33 @@
|
|||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngFor="let filter of primaryFilters">
|
<div *ngFor="let filter of primaryFilters">
|
||||||
<ng-template
|
<ng-container
|
||||||
|
[ngTemplateOutlet]="defaultFilterTemplate"
|
||||||
[ngTemplateOutletContext]="{
|
[ngTemplateOutletContext]="{
|
||||||
filter: filter,
|
filter: filter,
|
||||||
atLeastOneIsExpandable: atLeastOneFilterIsExpandable
|
atLeastOneIsExpandable: atLeastOneFilterIsExpandable
|
||||||
}"
|
}"
|
||||||
[ngTemplateOutlet]="defaultFilterTemplate"
|
></ng-container>
|
||||||
></ng-template>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="secondaryFilters?.length > 0" class="filter-options">
|
<div *ngIf="secondaryFilters?.length > 0" class="filter-options">
|
||||||
<div class="filter-menu-options">
|
<div class="filter-menu-options">
|
||||||
<div class="all-caps-label" translate="filter-menu.filter-options"></div>
|
<div class="all-caps-label" translate="filter-menu.filter-options"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngFor="let filter of secondaryFilters">
|
<div *ngFor="let filter of secondaryFilters">
|
||||||
<ng-template
|
<ng-container
|
||||||
|
[ngTemplateOutlet]="defaultFilterTemplate"
|
||||||
[ngTemplateOutletContext]="{
|
[ngTemplateOutletContext]="{
|
||||||
filter: filter,
|
filter: filter,
|
||||||
atLeastOneIsExpandable: atLeastOneSecondaryFilterIsExpandable
|
atLeastOneIsExpandable: atLeastOneSecondaryFilterIsExpandable
|
||||||
}"
|
}"
|
||||||
[ngTemplateOutlet]="defaultFilterTemplate"
|
></ng-container>
|
||||||
></ng-template>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</ng-template>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
|
||||||
<ng-template #defaultFilterLabelTemplate let-filter="filter">
|
<ng-template #defaultFilterLabelTemplate let-filter="filter">
|
||||||
@ -88,16 +91,17 @@
|
|||||||
[indeterminate]="_(filter).indeterminate"
|
[indeterminate]="_(filter).indeterminate"
|
||||||
class="filter-menu-checkbox"
|
class="filter-menu-checkbox"
|
||||||
>
|
>
|
||||||
<ng-template
|
<ng-container
|
||||||
|
[ngTemplateOutlet]="filterTemplate ?? defaultFilterLabelTemplate"
|
||||||
[ngTemplateOutletContext]="{ filter: filter }"
|
[ngTemplateOutletContext]="{ filter: filter }"
|
||||||
[ngTemplateOutlet]="filterTemplate ? filterTemplate : defaultFilterLabelTemplate"
|
></ng-container>
|
||||||
></ng-template>
|
|
||||||
</mat-checkbox>
|
</mat-checkbox>
|
||||||
<ng-template
|
<ng-container
|
||||||
|
[ngTemplateOutlet]="actionsTemplate ?? null"
|
||||||
[ngTemplateOutletContext]="{ filter: filter }"
|
[ngTemplateOutletContext]="{ filter: filter }"
|
||||||
[ngTemplateOutlet]="actionsTemplate ? actionsTemplate : null"
|
></ng-container>
|
||||||
></ng-template>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="_(filter).filters?.length && _(filter).expanded">
|
<div *ngIf="_(filter).filters?.length && _(filter).expanded">
|
||||||
<div
|
<div
|
||||||
(click)="$event.stopPropagation()"
|
(click)="$event.stopPropagation()"
|
||||||
@ -108,17 +112,16 @@
|
|||||||
(click)="filterCheckboxClicked($event, subFilter, filter)"
|
(click)="filterCheckboxClicked($event, subFilter, filter)"
|
||||||
[checked]="subFilter.checked"
|
[checked]="subFilter.checked"
|
||||||
>
|
>
|
||||||
<ng-template
|
<ng-container
|
||||||
|
[ngTemplateOutlet]="filterTemplate ?? defaultFilterLabelTemplate"
|
||||||
[ngTemplateOutletContext]="{ filter: subFilter }"
|
[ngTemplateOutletContext]="{ filter: subFilter }"
|
||||||
[ngTemplateOutlet]="
|
></ng-container>
|
||||||
filterTemplate ? filterTemplate : defaultFilterLabelTemplate
|
|
||||||
"
|
|
||||||
></ng-template>
|
|
||||||
</mat-checkbox>
|
</mat-checkbox>
|
||||||
<ng-template
|
|
||||||
|
<ng-container
|
||||||
|
[ngTemplateOutlet]="actionsTemplate ?? null"
|
||||||
[ngTemplateOutletContext]="{ filter: subFilter }"
|
[ngTemplateOutletContext]="{ filter: subFilter }"
|
||||||
[ngTemplateOutlet]="actionsTemplate ? actionsTemplate : null"
|
></ng-container>
|
||||||
></ng-template>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
ChangeDetectionStrategy,
|
||||||
ChangeDetectorRef,
|
ChangeDetectorRef,
|
||||||
Component,
|
Component,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
@ -15,6 +16,7 @@ import { MAT_CHECKBOX_DEFAULT_OPTIONS } from '@angular/material/checkbox';
|
|||||||
selector: 'redaction-popup-filter',
|
selector: 'redaction-popup-filter',
|
||||||
templateUrl: './popup-filter.component.html',
|
templateUrl: './popup-filter.component.html',
|
||||||
styleUrls: ['./popup-filter.component.scss'],
|
styleUrls: ['./popup-filter.component.scss'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
providers: [
|
providers: [
|
||||||
{
|
{
|
||||||
provide: MAT_CHECKBOX_DEFAULT_OPTIONS,
|
provide: MAT_CHECKBOX_DEFAULT_OPTIONS,
|
||||||
@ -38,9 +40,6 @@ export class PopupFilterComponent implements OnChanges {
|
|||||||
@Input() icon: string;
|
@Input() icon: string;
|
||||||
@Input() chevron = false;
|
@Input() chevron = false;
|
||||||
|
|
||||||
mouseOver = true;
|
|
||||||
mouseOverTimeout: number;
|
|
||||||
|
|
||||||
atLeastOneFilterIsExpandable = false;
|
atLeastOneFilterIsExpandable = false;
|
||||||
atLeastOneSecondaryFilterIsExpandable = false;
|
atLeastOneSecondaryFilterIsExpandable = false;
|
||||||
|
|
||||||
@ -60,44 +59,38 @@ export class PopupFilterComponent implements OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(): void {
|
ngOnChanges(): void {
|
||||||
this.atLeastOneFilterIsExpandable = false;
|
this.atLeastOneFilterIsExpandable = !!this.primaryFilters?.find(f => this.isExpandable(f));
|
||||||
this.atLeastOneSecondaryFilterIsExpandable = false;
|
this.atLeastOneSecondaryFilterIsExpandable = !!this.secondaryFilters?.find(f =>
|
||||||
this.primaryFilters?.forEach(f => {
|
this.isExpandable(f)
|
||||||
this.atLeastOneFilterIsExpandable =
|
);
|
||||||
this.atLeastOneFilterIsExpandable || this.isExpandable(f);
|
|
||||||
});
|
|
||||||
this.secondaryFilters?.forEach(f => {
|
|
||||||
this.atLeastOneSecondaryFilterIsExpandable =
|
|
||||||
this.atLeastOneSecondaryFilterIsExpandable || this.isExpandable(f);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
filterCheckboxClicked($event: any, filter: FilterModel, parent?: FilterModel) {
|
filterCheckboxClicked($event: any, filter: FilterModel, parent?: FilterModel) {
|
||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
|
|
||||||
filter.checked = !filter.checked;
|
filter.checked = !filter.checked;
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
handleCheckedValue(parent);
|
handleCheckedValue(parent);
|
||||||
} else {
|
} else {
|
||||||
if (filter.indeterminate) {
|
if (filter.indeterminate) filter.checked = false;
|
||||||
filter.checked = false;
|
|
||||||
}
|
|
||||||
filter.indeterminate = false;
|
filter.indeterminate = false;
|
||||||
filter.filters?.forEach(f => (f.checked = filter.checked));
|
filter.filters?.forEach(f => (f.checked = filter.checked));
|
||||||
}
|
}
|
||||||
this._changeDetectorRef.detectChanges();
|
|
||||||
this.applyFilters();
|
this.applyFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
activateAllFilters() {
|
activatePrimaryFilters() {
|
||||||
this._setAllFilters(true);
|
this._setFilters(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
deactivateAllFilters() {
|
deactivateFilters() {
|
||||||
this._setAllFilters(false);
|
this._setFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
applyFilters() {
|
applyFilters() {
|
||||||
|
this._changeDetectorRef.detectChanges();
|
||||||
this.filtersChanged.emit({
|
this.filtersChanged.emit({
|
||||||
primary: this.primaryFilters,
|
primary: this.primaryFilters,
|
||||||
secondary: this.secondaryFilters
|
secondary: this.secondaryFilters
|
||||||
@ -109,20 +102,6 @@ export class PopupFilterComponent implements OnChanges {
|
|||||||
filter.expanded = !filter.expanded;
|
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) {
|
isExpandable(filter: FilterModel) {
|
||||||
return filter.filters && filter.filters.length > 0;
|
return filter.filters && filter.filters.length > 0;
|
||||||
}
|
}
|
||||||
@ -131,14 +110,13 @@ export class PopupFilterComponent implements OnChanges {
|
|||||||
return obj as FilterModel;
|
return obj as FilterModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _setAllFilters(value: boolean) {
|
private _setFilters(onlyPrimaryFilters = false) {
|
||||||
const filters = value ? this.primaryFilters : this._allFilters;
|
const filters = onlyPrimaryFilters ? this.primaryFilters : this._allFilters;
|
||||||
filters.forEach(f => {
|
filters.forEach(f => {
|
||||||
f.checked = value;
|
f.checked = onlyPrimaryFilters;
|
||||||
f.indeterminate = false;
|
f.indeterminate = false;
|
||||||
f.filters?.forEach(ff => {
|
f.filters?.forEach(ff => (ff.checked = onlyPrimaryFilters));
|
||||||
ff.checked = value;
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
this.applyFilters();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,16 +10,12 @@ export class QuickFiltersComponent {
|
|||||||
@Output() filtersChanged = new EventEmitter<FilterModel[]>();
|
@Output() filtersChanged = new EventEmitter<FilterModel[]>();
|
||||||
@Input() filters: FilterModel[];
|
@Input() filters: FilterModel[];
|
||||||
|
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
get hasActiveFilters(): boolean {
|
get hasActiveFilters(): boolean {
|
||||||
return this.filters.filter(f => f.checked).length > 0;
|
return this.filters.filter(f => f.checked).length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
deactivateAllFilters() {
|
deactivateFilters() {
|
||||||
for (const filter of this.filters) {
|
for (const filter of this.filters) filter.checked = false;
|
||||||
filter.checked = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toggle(filter: FilterModel) {
|
toggle(filter: FilterModel) {
|
||||||
|
|||||||
@ -0,0 +1,61 @@
|
|||||||
|
<div class="page-header">
|
||||||
|
<div *ngIf="pageLabel" class="breadcrumb" translate>{{ pageLabel }}</div>
|
||||||
|
|
||||||
|
<div class="filters" *ngIf="filterConfigs">
|
||||||
|
<div translate="filters.filter-by"></div>
|
||||||
|
|
||||||
|
<ng-container *ngFor="let config of filterConfigs; trackBy: trackByLabel">
|
||||||
|
<redaction-popup-filter
|
||||||
|
(filtersChanged)="filtersChanged.emit($event)"
|
||||||
|
*ngIf="!config.hide"
|
||||||
|
[filterLabel]="config.label"
|
||||||
|
[icon]="config.icon"
|
||||||
|
[primaryFilters]="config.primaryFilters"
|
||||||
|
[filterTemplate]="config.filterTemplate"
|
||||||
|
></redaction-popup-filter>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<redaction-input-with-action
|
||||||
|
[form]="searchForm"
|
||||||
|
[placeholder]="searchPlaceholder"
|
||||||
|
type="search"
|
||||||
|
></redaction-input-with-action>
|
||||||
|
|
||||||
|
<div
|
||||||
|
(click)="resetFilters()"
|
||||||
|
*ngIf="hasActiveFilters"
|
||||||
|
class="reset-filters"
|
||||||
|
translate="reset-filters"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="actions" *ngIf="actionConfigs">
|
||||||
|
<ng-container *ngFor="let config of actionConfigs; trackBy: trackByLabel">
|
||||||
|
<redaction-circle-button
|
||||||
|
(action)="config.action($event)"
|
||||||
|
*ngIf="!config.hide"
|
||||||
|
[icon]="config.icon"
|
||||||
|
[tooltip]="config.label"
|
||||||
|
tooltipPosition="below"
|
||||||
|
></redaction-circle-button>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ng-container *ngFor="let config of buttonConfigs; trackBy: trackByLabel">
|
||||||
|
<redaction-icon-button
|
||||||
|
(action)="config.action($event)"
|
||||||
|
*ngIf="!config.hide"
|
||||||
|
[icon]="config.icon"
|
||||||
|
[text]="config.label"
|
||||||
|
[type]="config.type"
|
||||||
|
></redaction-icon-button>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<redaction-circle-button
|
||||||
|
*ngIf="showCloseButton && permissionsService.isUser()"
|
||||||
|
icon="red:close"
|
||||||
|
redactionNavigateLastDossiersScreen
|
||||||
|
tooltip="common.close"
|
||||||
|
tooltipPosition="below"
|
||||||
|
></redaction-circle-button>
|
||||||
|
</div>
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
.page-header .actions > *:not(:last-child) {
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
@ -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<any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
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<any>();
|
||||||
|
@Output() searchChanged = new EventEmitter<string>();
|
||||||
|
|
||||||
|
searchForm: FormGroup;
|
||||||
|
|
||||||
|
@ViewChildren(PopupFilterComponent)
|
||||||
|
private readonly _filterComponents: QueryList<PopupFilterComponent>;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -37,6 +37,7 @@ import { QuickFiltersComponent } from './components/filters/quick-filters/quick-
|
|||||||
import { PopupFilterComponent } from '@shared/components/filters/popup-filter/popup-filter.component';
|
import { PopupFilterComponent } from '@shared/components/filters/popup-filter/popup-filter.component';
|
||||||
import { AssignUserDropdownComponent } from './components/assign-user-dropdown/assign-user-dropdown.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 { InputWithActionComponent } from '@shared/components/input-with-action/input-with-action.component';
|
||||||
|
import { PageHeaderComponent } from './components/page-header/page-header.component';
|
||||||
|
|
||||||
const buttons = [
|
const buttons = [
|
||||||
ChevronButtonComponent,
|
ChevronButtonComponent,
|
||||||
@ -67,6 +68,7 @@ const components = [
|
|||||||
DictionaryManagerComponent,
|
DictionaryManagerComponent,
|
||||||
QuickFiltersComponent,
|
QuickFiltersComponent,
|
||||||
AssignUserDropdownComponent,
|
AssignUserDropdownComponent,
|
||||||
|
PageHeaderComponent,
|
||||||
|
|
||||||
...buttons
|
...buttons
|
||||||
];
|
];
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user