Dossier listing
This commit is contained in:
parent
31dff7aad5
commit
ce113ce464
@ -29,11 +29,8 @@
|
||||
[noDataIcon]="'red:dictionary'"
|
||||
[noDataText]="'dictionary-listing.no-data.title' | translate"
|
||||
[noMatchText]="'dictionary-listing.no-match.title' | translate"
|
||||
[routerLinkFn]="routerLinkFn"
|
||||
[selectionEnabled]="true"
|
||||
[showNoDataButton]="currentUser.isAdmin"
|
||||
[tableColumnConfigs]="tableColumnConfigs"
|
||||
[tableHeaderLabel]="tableHeaderLabel"
|
||||
emptyColumnWidth="1fr"
|
||||
></iqser-table>
|
||||
</div>
|
||||
|
||||
@ -19,10 +19,7 @@
|
||||
[noDataIcon]="'red:template'"
|
||||
[noDataText]="'dossier-templates-listing.no-data.title' | translate"
|
||||
[noMatchText]="'dossier-templates-listing.no-match.title' | translate"
|
||||
[routerLinkFn]="routerLinkFn"
|
||||
[selectionEnabled]="true"
|
||||
[tableColumnConfigs]="tableColumnConfigs"
|
||||
[tableHeaderLabel]="tableHeaderLabel"
|
||||
></iqser-table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -8,76 +8,16 @@
|
||||
|
||||
<div class="red-content-inner">
|
||||
<div class="content-container">
|
||||
<iqser-table-header [tableColumnConfigs]="tableColumnConfigs" [tableHeaderLabel]="tableHeaderLabel"></iqser-table-header>
|
||||
|
||||
<iqser-empty-state
|
||||
(action)="openAddDossierDialog()"
|
||||
*ngIf="entitiesService.noData$ | async"
|
||||
[buttonLabel]="'dossier-listing.no-data.action' | translate"
|
||||
[showButton]="currentUser.isManager"
|
||||
[text]="'dossier-listing.no-data.title' | translate"
|
||||
icon="red:folder"
|
||||
></iqser-empty-state>
|
||||
|
||||
<iqser-empty-state *ngIf="noMatch$ | async" [text]="'dossier-listing.no-match.title' | translate"></iqser-empty-state>
|
||||
|
||||
<cdk-virtual-scroll-viewport #scrollViewport [itemSize]="itemSize" iqserHasScrollbar>
|
||||
<div
|
||||
*cdkVirtualFor="let dossier of sortedDisplayedEntities$ | async; trackBy: trackByPrimaryKey"
|
||||
[class.pointer]="!!dossier"
|
||||
[routerLink]="['/main/dossiers/' + dossier.dossierId.toString()]"
|
||||
class="table-item"
|
||||
>
|
||||
<div class="filename">
|
||||
<div [matTooltip]="dossier.dossierName" class="table-item-title heading" matTooltipPosition="above">
|
||||
{{ dossier.dossierName }}
|
||||
</div>
|
||||
<div class="small-label stats-subtitle">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:template"></mat-icon>
|
||||
{{ dossier.dossierTemplateName }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="small-label stats-subtitle">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:document"></mat-icon>
|
||||
{{ dossier.filesLength }}
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon svgIcon="red:pages"></mat-icon>
|
||||
{{ dossier.totalNumberOfPages }}
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon svgIcon="red:user"></mat-icon>
|
||||
{{ dossier.memberCount }}
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon svgIcon="red:calendar"></mat-icon>
|
||||
{{ dossier.date | date: 'mediumDate' }}
|
||||
</div>
|
||||
<div *ngIf="dossier.dueDate">
|
||||
<mat-icon svgIcon="red:lightning"></mat-icon>
|
||||
{{ dossier.dueDate | date: 'mediumDate' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<redaction-needs-work-badge [needsWorkInput]="dossier"></redaction-needs-work-badge>
|
||||
</div>
|
||||
<div class="user-column">
|
||||
<redaction-initials-avatar [userId]="dossier.ownerId" [withName]="true"></redaction-initials-avatar>
|
||||
</div>
|
||||
<div class="status-container">
|
||||
<redaction-dossier-listing-actions
|
||||
(actionPerformed)="calculateData()"
|
||||
[dossier]="dossier"
|
||||
></redaction-dossier-listing-actions>
|
||||
</div>
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
</cdk-virtual-scroll-viewport>
|
||||
|
||||
<iqser-scroll-button [itemSize]="itemSize" [scrollViewport]="scrollViewport"></iqser-scroll-button>
|
||||
<iqser-table
|
||||
(noDataAction)="openAddDossierDialog()"
|
||||
[hasScrollButton]="true"
|
||||
[itemSize]="85"
|
||||
[noDataButtonLabel]="'dossier-listing.no-data.action' | translate"
|
||||
[noDataIcon]="'red:folder'"
|
||||
[noDataText]="'dossier-listing.no-data.title' | translate"
|
||||
[noMatchText]="'dossier-listing.no-match.title' | translate"
|
||||
[showNoDataButton]="currentUser.isManager"
|
||||
></iqser-table>
|
||||
</div>
|
||||
|
||||
<div class="right-container" iqserHasScrollbar>
|
||||
@ -90,6 +30,60 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<ng-template #needsWorkTemplate let-filter="filter">
|
||||
<ng-template #needsWorkFilterTemplate let-filter="filter">
|
||||
<redaction-type-filter [filter]="filter"></redaction-type-filter>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #nameTemplate let-dossier="entity">
|
||||
<div class="cell">
|
||||
<div [matTooltip]="dossier.dossierName" class="table-item-title heading" matTooltipPosition="above">
|
||||
{{ dossier.dossierName }}
|
||||
</div>
|
||||
<div class="small-label stats-subtitle">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:template"></mat-icon>
|
||||
{{ dossier.dossierTemplateName }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="small-label stats-subtitle">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:document"></mat-icon>
|
||||
{{ dossier.filesLength }}
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon svgIcon="red:pages"></mat-icon>
|
||||
{{ dossier.totalNumberOfPages }}
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon svgIcon="red:user"></mat-icon>
|
||||
{{ dossier.memberCount }}
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon svgIcon="red:calendar"></mat-icon>
|
||||
{{ dossier.date | date: 'mediumDate' }}
|
||||
</div>
|
||||
<div *ngIf="dossier.dueDate">
|
||||
<mat-icon svgIcon="red:lightning"></mat-icon>
|
||||
{{ dossier.dueDate | date: 'mediumDate' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #needsWorkTemplate let-dossier="entity">
|
||||
<div class="cell">
|
||||
<redaction-needs-work-badge [needsWorkInput]="dossier"></redaction-needs-work-badge>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #ownerTemplate let-dossier="entity">
|
||||
<div class="cell user-column">
|
||||
<redaction-initials-avatar [userId]="dossier.ownerId" [withName]="true"></redaction-initials-avatar>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #statusTemplate let-dossier="entity">
|
||||
<div class="cell status-container">
|
||||
<redaction-dossier-listing-actions (actionPerformed)="calculateData()" [dossier]="dossier"></redaction-dossier-listing-actions>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
@ -1,37 +1,23 @@
|
||||
@import '../../../../../assets/styles/variables';
|
||||
|
||||
.content-container {
|
||||
position: relative;
|
||||
|
||||
cdk-virtual-scroll-viewport {
|
||||
::ng-deep.cdk-virtual-scroll-content-wrapper {
|
||||
grid-template-columns: 2fr 1fr 1fr auto 11px;
|
||||
|
||||
.table-item .status-container {
|
||||
width: 160px;
|
||||
padding-right: 13px;
|
||||
}
|
||||
:host {
|
||||
::ng-deep iqser-table cdk-virtual-scroll-viewport .cdk-virtual-scroll-content-wrapper .table-item > div.cell {
|
||||
&.status-container {
|
||||
width: 160px;
|
||||
padding-right: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.right-container {
|
||||
display: flex;
|
||||
width: 466px;
|
||||
min-width: 466px;
|
||||
padding-right: 11px;
|
||||
|
||||
&.has-scrollbar:hover {
|
||||
::ng-deep.cdk-virtual-scroll-content-wrapper {
|
||||
grid-template-columns: 2fr 1fr 1fr auto;
|
||||
}
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
redaction-dossier-listing-details {
|
||||
min-width: 466px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right-container {
|
||||
display: flex;
|
||||
width: 466px;
|
||||
min-width: 466px;
|
||||
padding-right: 11px;
|
||||
|
||||
&.has-scrollbar:hover {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
redaction-dossier-listing-details {
|
||||
min-width: 466px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { AfterViewInit, Component, Injector, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
||||
import { AfterViewInit, Component, forwardRef, Injector, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
||||
import { Dossier } from '@redaction/red-ui-http';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { UserService } from '@services/user.service';
|
||||
@ -16,18 +16,17 @@ import { DossiersDialogService } from '../../services/dossiers-dialog.service';
|
||||
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
|
||||
import { UserPreferenceService } from '@services/user-preference.service';
|
||||
import { ButtonConfig } from '@shared/components/page-header/models/button-config.model';
|
||||
import { DefaultListingServices, ListingComponent, NestedFilter, TableColumnConfig } from '@iqser/common-ui';
|
||||
import { DefaultListingServices, ListingComponent, NestedFilter, TableColumnConfig, TableComponent } from '@iqser/common-ui';
|
||||
import { workloadTranslations } from '../../translations/workload-translations';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { fileStatusTranslations } from '../../translations/file-status-translations';
|
||||
import { annotationFilterChecker, dossierMemberChecker, dossierStatusChecker, dossierTemplateChecker } from '@utils/filter-utils';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
|
||||
|
||||
@Component({
|
||||
templateUrl: './dossier-listing-screen.component.html',
|
||||
styleUrls: ['./dossier-listing-screen.component.scss'],
|
||||
providers: [...DefaultListingServices]
|
||||
providers: [...DefaultListingServices, { provide: ListingComponent, useExisting: forwardRef(() => DossierListingScreenComponent) }]
|
||||
})
|
||||
export class DossierListingScreenComponent
|
||||
extends ListingComponent<DossierWrapper>
|
||||
@ -44,32 +43,21 @@ export class DossierListingScreenComponent
|
||||
type: 'primary'
|
||||
}
|
||||
];
|
||||
readonly tableColumnConfigs: readonly TableColumnConfig<DossierWrapper>[] = [
|
||||
{
|
||||
label: _('dossier-listing.table-col-names.name'),
|
||||
sortByKey: 'dossierName'
|
||||
},
|
||||
{
|
||||
label: _('dossier-listing.table-col-names.needs-work')
|
||||
},
|
||||
{
|
||||
label: _('dossier-listing.table-col-names.owner'),
|
||||
class: 'user-column'
|
||||
},
|
||||
{
|
||||
label: _('dossier-listing.table-col-names.status'),
|
||||
class: 'flex-end'
|
||||
}
|
||||
];
|
||||
tableColumnConfigs: TableColumnConfig<DossierWrapper>[];
|
||||
dossiersChartData: DoughnutChartConfig[] = [];
|
||||
documentsChartData: DoughnutChartConfig[] = [];
|
||||
readonly itemSize = 85;
|
||||
@ViewChild('nameTemplate', { static: true }) nameTemplate: TemplateRef<never>;
|
||||
@ViewChild('needsWorkTemplate', { static: true }) needsWorkTemplate: TemplateRef<never>;
|
||||
@ViewChild('ownerTemplate', { static: true }) ownerTemplate: TemplateRef<never>;
|
||||
@ViewChild('statusTemplate', { static: true }) statusTemplate: TemplateRef<never>;
|
||||
protected readonly _primaryKey = 'dossierName';
|
||||
private _lastScrolledIndex: number;
|
||||
@ViewChild('needsWorkTemplate', { read: TemplateRef, static: true })
|
||||
private readonly _needsWorkTemplate: TemplateRef<unknown>;
|
||||
@ViewChild(CdkVirtualScrollViewport)
|
||||
private readonly _scrollViewport: CdkVirtualScrollViewport;
|
||||
@ViewChild('needsWorkFilterTemplate', {
|
||||
read: TemplateRef,
|
||||
static: true
|
||||
})
|
||||
private readonly _needsWorkFilterTemplate: TemplateRef<unknown>;
|
||||
@ViewChild(TableComponent) private readonly _tableComponent: TableComponent<DossierWrapper>;
|
||||
|
||||
constructor(
|
||||
private readonly _router: Router,
|
||||
@ -95,7 +83,10 @@ export class DossierListingScreenComponent
|
||||
return this.entitiesService.all.length - this._activeDossiersCount;
|
||||
}
|
||||
|
||||
routerLinkFn = (dossier: DossierWrapper) => ['/main/dossiers/' + dossier.dossierId];
|
||||
|
||||
ngOnInit(): void {
|
||||
this._setColumnConfig();
|
||||
this.calculateData();
|
||||
|
||||
this.addSubscription = timer(0, 10000).subscribe(async () => {
|
||||
@ -110,7 +101,9 @@ export class DossierListingScreenComponent
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.addSubscription = this._scrollViewport.scrolledIndexChange.pipe(tap(index => (this._lastScrolledIndex = index))).subscribe();
|
||||
this.addSubscription = this._tableComponent.scrollViewport.scrolledIndexChange
|
||||
.pipe(tap(index => (this._lastScrolledIndex = index)))
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
ngOnAttach(): void {
|
||||
@ -118,7 +111,7 @@ export class DossierListingScreenComponent
|
||||
this._loadEntitiesFromState();
|
||||
this.ngOnInit();
|
||||
this.ngAfterViewInit();
|
||||
this._scrollViewport.scrollToIndex(this._lastScrolledIndex, 'smooth');
|
||||
this._tableComponent.scrollViewport.scrollToIndex(this._lastScrolledIndex, 'smooth');
|
||||
}
|
||||
|
||||
ngOnDetach(): void {
|
||||
@ -159,6 +152,32 @@ export class DossierListingScreenComponent
|
||||
this.documentsChartData = this._translateChartService.translateStatus(this.documentsChartData);
|
||||
}
|
||||
|
||||
private _setColumnConfig() {
|
||||
this.tableColumnConfigs = [
|
||||
{
|
||||
label: _('dossier-listing.table-col-names.name'),
|
||||
sortByKey: 'dossierName',
|
||||
template: this.nameTemplate,
|
||||
width: '2fr'
|
||||
},
|
||||
{
|
||||
label: _('dossier-listing.table-col-names.needs-work'),
|
||||
template: this.needsWorkTemplate
|
||||
},
|
||||
{
|
||||
label: _('dossier-listing.table-col-names.owner'),
|
||||
class: 'user-column',
|
||||
template: this.ownerTemplate
|
||||
},
|
||||
{
|
||||
label: _('dossier-listing.table-col-names.status'),
|
||||
class: 'flex-end',
|
||||
template: this.statusTemplate,
|
||||
width: 'auto'
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
private _loadEntitiesFromState() {
|
||||
this.entitiesService.setEntities(this._appStateService.allDossiers);
|
||||
}
|
||||
@ -230,7 +249,7 @@ export class DossierListingScreenComponent
|
||||
slug: 'needsWorkFilters',
|
||||
label: this._translateService.instant('filters.needs-work'),
|
||||
icon: 'red:needs-work',
|
||||
filterTemplate: this._needsWorkTemplate,
|
||||
filterTemplate: this._needsWorkFilterTemplate,
|
||||
filters: needsWorkFilters.sort(RedactionFilterSorter.byKey),
|
||||
checker: annotationFilterChecker,
|
||||
matchAll: true
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit b1e1bc3f1a95ae53c30485a3f2ac044d71255c00
|
||||
Subproject commit 704ea8221e6a6a198811c91f2a5fd15ed25c46da
|
||||
Loading…
x
Reference in New Issue
Block a user