dossier wrapper refactor
This commit is contained in:
parent
fbc32d7e23
commit
9e7edc6b69
@ -12,7 +12,7 @@
|
||||
[routerLink]="'/main/dossiers/' + appStateService.activeDossierId"
|
||||
mat-menu-item
|
||||
>
|
||||
{{ appStateService.activeDossier.dossier.dossierName }}
|
||||
{{ appStateService.activeDossier.dossierName }}
|
||||
</button>
|
||||
<button
|
||||
*ngIf="appStateService.activeFile"
|
||||
@ -44,7 +44,7 @@
|
||||
class="breadcrumb"
|
||||
routerLinkActive="active"
|
||||
>
|
||||
{{ appStateService.activeDossier.dossier.dossierName }}
|
||||
{{ appStateService.activeDossier.dossierName }}
|
||||
</a>
|
||||
<mat-icon *ngIf="appStateService.activeFile" svgIcon="red:arrow-right"></mat-icon>
|
||||
<a
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
<div class="section small-label stats-subtitle">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:folder"></mat-icon>
|
||||
<span>{{ 'file-preview.tabs.document-info.details.dossier' | translate: { dossierName: dossier.name } }}</span>
|
||||
<span>{{ 'file-preview.tabs.document-info.details.dossier' | translate: { dossierName: dossier.dossierName } }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon svgIcon="red:document"></mat-icon>
|
||||
@ -36,11 +36,9 @@
|
||||
<mat-icon svgIcon="red:calendar"></mat-icon>
|
||||
<span>{{ 'file-preview.tabs.document-info.details.created-on' | translate: { date: file.added | date: 'mediumDate' } }}</span>
|
||||
</div>
|
||||
<div *ngIf="dossier.dossier.dueDate">
|
||||
<div *ngIf="dossier.dueDate">
|
||||
<mat-icon svgIcon="red:lightning"></mat-icon>
|
||||
<span>{{
|
||||
'file-preview.tabs.document-info.details.due' | translate: { date: dossier.dossier.dueDate | date: 'mediumDate' }
|
||||
}}</span>
|
||||
<span>{{ 'file-preview.tabs.document-info.details.due' | translate: { date: dossier.dueDate | date: 'mediumDate' } }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon svgIcon="red:template"></mat-icon>
|
||||
|
||||
@ -19,18 +19,18 @@
|
||||
'dossier-overview.dossier-details.stats.created-on'
|
||||
| translate
|
||||
: {
|
||||
date: activeDossier.dossier.date | date: 'd MMM. yyyy'
|
||||
date: activeDossier.date | date: 'd MMM. yyyy'
|
||||
}
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
<div *ngIf="activeDossier.dossier.dueDate">
|
||||
<div *ngIf="activeDossier.dueDate">
|
||||
<mat-icon svgIcon="red:lightning"></mat-icon>
|
||||
<span>{{
|
||||
'dossier-overview.dossier-details.stats.due-date'
|
||||
| translate
|
||||
: {
|
||||
date: activeDossier.dossier.dueDate | date: 'd MMM. yyyy'
|
||||
date: activeDossier.dueDate | date: 'd MMM. yyyy'
|
||||
}
|
||||
}}</span>
|
||||
</div>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
</div>
|
||||
|
||||
<div class="header-wrapper mt-8">
|
||||
<div class="heading-xl flex-1">{{ appStateService.activeDossier.dossier.dossierName }}</div>
|
||||
<div class="heading-xl flex-1">{{ appStateService.activeDossier.dossierName }}</div>
|
||||
<ng-container
|
||||
*ngTemplateOutlet="collapsible; context: { action: 'collapse', tooltip: (collapseTooltip | translate) }"
|
||||
></ng-container>
|
||||
@ -65,7 +65,7 @@
|
||||
></redaction-dossier-details-stats>
|
||||
</div>
|
||||
|
||||
<div *ngIf="appStateService.activeDossier.dossier.description as description" class="pb-32">
|
||||
<div *ngIf="appStateService.activeDossier.description as description" class="pb-32">
|
||||
<div class="heading" translate="dossier-overview.dossier-details.description"></div>
|
||||
<div class="mt-8">{{ description }}</div>
|
||||
</div>
|
||||
|
||||
@ -40,7 +40,7 @@ export class DossierDetailsComponent implements OnInit {
|
||||
) {}
|
||||
|
||||
get memberIds(): string[] {
|
||||
return this.appStateService.activeDossier.dossier.memberIds;
|
||||
return this.appStateService.activeDossier.memberIds;
|
||||
}
|
||||
|
||||
get hasFiles(): boolean {
|
||||
@ -54,7 +54,7 @@ export class DossierDetailsComponent implements OnInit {
|
||||
ngOnInit(): void {
|
||||
this.owner = this._userService.getRedUserById(this.appStateService.activeDossier.ownerId);
|
||||
this.calculateChartConfig();
|
||||
this.appStateService.fileChanged.subscribe(() => {
|
||||
this.appStateService.fileChanged$.subscribe(() => {
|
||||
this.calculateChartConfig();
|
||||
});
|
||||
}
|
||||
@ -81,12 +81,11 @@ export class DossierDetailsComponent implements OnInit {
|
||||
|
||||
async assignOwner(user: UserWrapper | string) {
|
||||
this.owner = typeof user === 'string' ? this._userService.getRedUserById(user) : user;
|
||||
const dw = Object.assign({}, this.appStateService.activeDossier);
|
||||
dw.dossier.ownerId = this.owner.id;
|
||||
await this.appStateService.createOrUpdateDossier(dw.dossier);
|
||||
const dw = { ...this.appStateService.activeDossier, ownerId: this.owner.id };
|
||||
await this.appStateService.createOrUpdateDossier(dw);
|
||||
|
||||
const ownerName = this._userService.getNameForId(this.owner.id);
|
||||
const dossierName = this.appStateService.activeDossier.name;
|
||||
const dossierName = this.appStateService.activeDossier.dossierName;
|
||||
this._toaster.info(_('assignment.owner'), { params: { ownerName, dossierName } });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { DossierWrapper } from '@state/model/dossier.wrapper';
|
||||
import { StatusSorter } from '@utils/sorters/status-sorter';
|
||||
@ -11,7 +11,8 @@ import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
@Component({
|
||||
selector: 'redaction-dossier-listing-actions',
|
||||
templateUrl: './dossier-listing-actions.component.html',
|
||||
styleUrls: ['./dossier-listing-actions.component.scss']
|
||||
styleUrls: ['./dossier-listing-actions.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class DossierListingActionsComponent implements OnInit {
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
|
||||
@ -100,7 +100,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
this.screen = 'file-preview';
|
||||
this._setup();
|
||||
|
||||
this.addSubscription = this.appStateService.fileChanged
|
||||
this.addSubscription = this.appStateService.fileChanged$
|
||||
.pipe(filter(file => file.fileId === this.fileStatus?.fileId))
|
||||
.subscribe(fileStatus => {
|
||||
this.fileStatus = fileStatus;
|
||||
|
||||
@ -34,7 +34,7 @@ export class PageIndicatorComponent implements OnChanges, OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this._subscription = this._appStateService.fileChanged.subscribe(() => {
|
||||
this._subscription = this._appStateService.fileChanged$.subscribe(() => {
|
||||
this.canMarkPagesAsViewed = this._permissionService.canMarkPagesAsViewed();
|
||||
});
|
||||
}
|
||||
|
||||
@ -82,11 +82,13 @@ export class TeamMembersManagerComponent implements OnInit {
|
||||
const ownerId = this.selectedOwnerId;
|
||||
const memberIds = this.selectedMembersList;
|
||||
const approverIds = this.selectedApproversList;
|
||||
const dw = Object.assign({}, this.dossierWrapper);
|
||||
dw.dossier.memberIds = memberIds;
|
||||
dw.dossier.approverIds = approverIds;
|
||||
dw.dossier.ownerId = ownerId;
|
||||
result = await this._appStateService.createOrUpdateDossier(dw.dossier);
|
||||
const dw = {
|
||||
...this.dossierWrapper,
|
||||
memberIds,
|
||||
approverIds,
|
||||
ownerId
|
||||
};
|
||||
result = await this._appStateService.createOrUpdateDossier(dw);
|
||||
this.save.emit(result);
|
||||
} catch (error) {
|
||||
this._toaster.error('Failed: ' + error.error ? error.error.message : error);
|
||||
|
||||
@ -8,7 +8,6 @@ import { downloadTypesTranslations } from '../../../../translations/download-typ
|
||||
import { IconButtonTypes } from '@iqser/common-ui';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-add-dossier-dialog',
|
||||
templateUrl: './add-dossier-dialog.component.html',
|
||||
styleUrls: ['./add-dossier-dialog.component.scss']
|
||||
})
|
||||
@ -71,7 +70,7 @@ export class AddDossierDialogComponent {
|
||||
async saveDossier() {
|
||||
const dossier: Dossier = this._formToObject();
|
||||
|
||||
const foundDossier = this._appStateService.allDossiers.find(p => p.dossier.dossierId === dossier.dossierId);
|
||||
const foundDossier = this._appStateService.allDossiers.find(p => p.dossierId === dossier.dossierId);
|
||||
if (foundDossier) {
|
||||
dossier.memberIds = foundDossier.memberIds;
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { DossierWrapper } from '@state/model/dossier.wrapper';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-document-info-dialog',
|
||||
templateUrl: './document-info-dialog.component.html',
|
||||
styleUrls: ['./document-info-dialog.component.scss']
|
||||
})
|
||||
|
||||
@ -43,11 +43,11 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
|
||||
get changed() {
|
||||
if (this.dossierForm) {
|
||||
for (const key of Object.keys(this.dossierForm.getRawValue())) {
|
||||
if (this.dossierWrapper.dossier[key].length !== this.dossierForm.get(key).value.length) {
|
||||
if (this.dossierWrapper[key].length !== this.dossierForm.get(key).value.length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const originalItems = [...this.dossierWrapper.dossier[key]].sort();
|
||||
const originalItems = [...this.dossierWrapper[key]].sort();
|
||||
const newItems = [...this.dossierForm.get(key).value].sort();
|
||||
|
||||
for (let idx = 0; idx < originalItems.length; ++idx) {
|
||||
@ -71,8 +71,8 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
|
||||
|
||||
this.dossierForm = this._formBuilder.group(
|
||||
{
|
||||
reportTemplateIds: [this.dossierWrapper.dossier.reportTemplateIds],
|
||||
downloadFileTypes: [this.dossierWrapper.dossier.downloadFileTypes]
|
||||
reportTemplateIds: [this.dossierWrapper.reportTemplateIds],
|
||||
downloadFileTypes: [this.dossierWrapper.downloadFileTypes]
|
||||
},
|
||||
{
|
||||
validators: control =>
|
||||
@ -85,7 +85,7 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
|
||||
|
||||
async save() {
|
||||
const dossier = {
|
||||
...this.dossierWrapper.dossier,
|
||||
...this.dossierWrapper,
|
||||
downloadFileTypes: this.dossierForm.get('downloadFileTypes').value,
|
||||
reportTemplateIds: this.dossierForm.get('reportTemplateIds').value
|
||||
};
|
||||
@ -95,8 +95,8 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
|
||||
|
||||
revert() {
|
||||
this.dossierForm.reset({
|
||||
downloadFileTypes: this.dossierWrapper.dossier.downloadFileTypes,
|
||||
reportTemplateIds: this.dossierWrapper.dossier.reportTemplateIds
|
||||
downloadFileTypes: this.dossierWrapper.downloadFileTypes,
|
||||
reportTemplateIds: this.dossierWrapper.reportTemplateIds
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<section class="dialog">
|
||||
<div class="dialog-header heading-l">
|
||||
{{ 'edit-dossier-dialog.header' | translate: { dossierName: dossierWrapper.name } }}
|
||||
{{ 'edit-dossier-dialog.header' | translate: { dossierName: dossierWrapper.dossierName } }}
|
||||
</div>
|
||||
|
||||
<div class="dialog-content">
|
||||
|
||||
@ -94,7 +94,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
|
||||
|
||||
async save() {
|
||||
const dossier = {
|
||||
...this.dossierWrapper.dossier,
|
||||
...this.dossierWrapper,
|
||||
dossierName: this.dossierForm.get('dossierName').value,
|
||||
description: this.dossierForm.get('description').value,
|
||||
watermarkEnabled: this.dossierForm.get('watermarkEnabled').value,
|
||||
|
||||
@ -23,54 +23,54 @@
|
||||
|
||||
<cdk-virtual-scroll-viewport #scrollViewport [itemSize]="itemSize" redactionHasScrollbar>
|
||||
<div
|
||||
*cdkVirtualFor="let dw of sortedDisplayedEntities$ | async; trackBy: trackByPrimaryKey"
|
||||
[class.pointer]="!!dw"
|
||||
[routerLink]="[!!dw ? '/main/dossiers/' + dw.dossier.dossierId : []]"
|
||||
*cdkVirtualFor="let item of sortedDisplayedEntities$ | async; trackBy: trackByPrimaryKey"
|
||||
[class.pointer]="!!item"
|
||||
[routerLink]="[item.routerLink]"
|
||||
class="table-item"
|
||||
>
|
||||
<div class="filename">
|
||||
<div [matTooltip]="dw.dossierName" class="table-item-title heading" matTooltipPosition="above">
|
||||
{{ dw.dossierName }}
|
||||
<div [matTooltip]="item.dossierName" class="table-item-title heading" matTooltipPosition="above">
|
||||
{{ item.dossierName }}
|
||||
</div>
|
||||
<div class="small-label stats-subtitle">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:template"></mat-icon>
|
||||
{{ getDossierTemplate(dw).name }}
|
||||
{{ item.dossierTemplateName }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="small-label stats-subtitle">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:document"></mat-icon>
|
||||
{{ dw.files.length }}
|
||||
{{ item.dossier.filesLength }}
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon svgIcon="red:pages"></mat-icon>
|
||||
{{ dw.totalNumberOfPages }}
|
||||
{{ item.dossier.totalNumberOfPages }}
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon svgIcon="red:user"></mat-icon>
|
||||
{{ dw.numberOfMembers }}
|
||||
{{ item.dossier.memberCount }}
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon svgIcon="red:calendar"></mat-icon>
|
||||
{{ dw.dossier.date | date: 'mediumDate' }}
|
||||
{{ item.dossier.date | date: 'mediumDate' }}
|
||||
</div>
|
||||
<div *ngIf="dw.dossier.dueDate">
|
||||
<div *ngIf="item.dossier.dueDate">
|
||||
<mat-icon svgIcon="red:lightning"></mat-icon>
|
||||
{{ dw.dossier.dueDate | date: 'mediumDate' }}
|
||||
{{ item.dossier.dueDate | date: 'mediumDate' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<redaction-needs-work-badge [needsWorkInput]="dw"></redaction-needs-work-badge>
|
||||
<redaction-needs-work-badge [needsWorkInput]="item.dossier"></redaction-needs-work-badge>
|
||||
</div>
|
||||
<div class="user-column">
|
||||
<redaction-initials-avatar [userId]="dw.dossier.ownerId" [withName]="true"></redaction-initials-avatar>
|
||||
<redaction-initials-avatar [userId]="item.dossier.ownerId" [withName]="true"></redaction-initials-avatar>
|
||||
</div>
|
||||
<div class="status-container">
|
||||
<redaction-dossier-listing-actions
|
||||
(actionPerformed)="calculateData()"
|
||||
[dossier]="dw"
|
||||
[dossier]="item.dossier"
|
||||
></redaction-dossier-listing-actions>
|
||||
</div>
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { AfterViewInit, ChangeDetectorRef, Component, Injector, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
||||
import { Component, Injector, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
||||
import { Dossier, DossierTemplateModel } from '@redaction/red-ui-http';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { UserService } from '@services/user.service';
|
||||
@ -31,19 +31,24 @@ import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
|
||||
|
||||
const isLeavingScreen = event => event instanceof NavigationStart && event.url !== '/main/dossiers';
|
||||
|
||||
interface ListItem {
|
||||
readonly dossierName: string;
|
||||
readonly routerLink: string;
|
||||
readonly dossierTemplateName: string;
|
||||
readonly dossier: DossierWrapper;
|
||||
}
|
||||
|
||||
@Component({
|
||||
templateUrl: './dossier-listing-screen.component.html',
|
||||
styleUrls: ['./dossier-listing-screen.component.scss'],
|
||||
providers: [...DefaultListingServices]
|
||||
})
|
||||
export class DossierListingScreenComponent
|
||||
extends ListingComponent<DossierWrapper>
|
||||
implements OnInit, AfterViewInit, OnDestroy, OnAttach, OnDetach
|
||||
{
|
||||
export class DossierListingScreenComponent extends ListingComponent<ListItem> implements OnInit, OnDestroy, OnAttach, OnDetach {
|
||||
readonly itemSize = 85;
|
||||
protected readonly _primaryKey = 'dossierName';
|
||||
readonly currentUser = this._userService.currentUser;
|
||||
readonly tableHeaderLabel = _('dossier-listing.table-header.title');
|
||||
readonly buttonConfigs: ButtonConfig[] = [
|
||||
readonly buttonConfigs: readonly ButtonConfig[] = [
|
||||
{
|
||||
label: _('dossier-listing.add-new'),
|
||||
action: () => this.openAddDossierDialog(),
|
||||
@ -52,7 +57,7 @@ export class DossierListingScreenComponent
|
||||
type: 'primary'
|
||||
}
|
||||
];
|
||||
readonly tableColumnConfigs: TableColumnConfig<DossierWrapper>[] = [
|
||||
readonly tableColumnConfigs: readonly TableColumnConfig<ListItem>[] = [
|
||||
{
|
||||
label: _('dossier-listing.table-col-names.name'),
|
||||
sortByKey: 'dossierName'
|
||||
@ -72,7 +77,6 @@ export class DossierListingScreenComponent
|
||||
|
||||
dossiersChartData: DoughnutChartConfig[] = [];
|
||||
documentsChartData: DoughnutChartConfig[] = [];
|
||||
protected readonly _primaryKey = 'dossierName';
|
||||
private _lastScrollPosition: number;
|
||||
|
||||
@ViewChild('needsWorkTemplate', { read: TemplateRef, static: true })
|
||||
@ -84,7 +88,6 @@ export class DossierListingScreenComponent
|
||||
private readonly _router: Router,
|
||||
protected readonly _injector: Injector,
|
||||
private readonly _userService: UserService,
|
||||
readonly changeDetectorRef: ChangeDetectorRef,
|
||||
readonly permissionsService: PermissionsService,
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _translateService: TranslateService,
|
||||
@ -97,10 +100,6 @@ export class DossierListingScreenComponent
|
||||
this._loadEntitiesFromState();
|
||||
}
|
||||
|
||||
private get _userId() {
|
||||
return this._userService.currentUser.id;
|
||||
}
|
||||
|
||||
private get _activeDossiersCount(): number {
|
||||
return this.entitiesService.all.filter(p => p.dossier.status === Dossier.StatusEnum.ACTIVE).length;
|
||||
}
|
||||
@ -118,7 +117,7 @@ export class DossierListingScreenComponent
|
||||
this.calculateData();
|
||||
});
|
||||
|
||||
this.addSubscription = this._appStateService.fileChanged.subscribe(() => {
|
||||
this.addSubscription = this._appStateService.fileChanged$.subscribe(() => {
|
||||
this.calculateData();
|
||||
});
|
||||
|
||||
@ -127,10 +126,6 @@ export class DossierListingScreenComponent
|
||||
});
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
ngOnAttach() {
|
||||
this._scrollViewport.scrollTo({ top: this._lastScrollPosition });
|
||||
this._appStateService.reset();
|
||||
@ -142,8 +137,8 @@ export class DossierListingScreenComponent
|
||||
this.ngOnDestroy();
|
||||
}
|
||||
|
||||
getDossierTemplate(dw: DossierWrapper): DossierTemplateModel {
|
||||
return this._appStateService.getDossierTemplateById(dw.dossier.dossierTemplateId);
|
||||
getDossierTemplate(dossierTemplateId: string): DossierTemplateModel {
|
||||
return this._appStateService.getDossierTemplateById(dossierTemplateId);
|
||||
}
|
||||
|
||||
openAddDossierDialog(): void {
|
||||
@ -181,7 +176,17 @@ export class DossierListingScreenComponent
|
||||
}
|
||||
|
||||
private _loadEntitiesFromState() {
|
||||
this.entitiesService.setEntities(this._appStateService.allDossiers);
|
||||
const entities = this._appStateService.allDossiers.map(dossier => this._toListItem(dossier));
|
||||
this.entitiesService.setEntities(entities);
|
||||
}
|
||||
|
||||
private _toListItem(dossier: DossierWrapper): ListItem {
|
||||
return {
|
||||
dossierName: dossier.dossierName,
|
||||
routerLink: '/main/dossiers/' + dossier.dossierId.toString(),
|
||||
dossierTemplateName: this.getDossierTemplate(dossier.dossierTemplateId).name,
|
||||
dossier
|
||||
};
|
||||
}
|
||||
|
||||
private _computeAllFilters() {
|
||||
@ -190,20 +195,20 @@ export class DossierListingScreenComponent
|
||||
const allDistinctNeedsWork = new Set<string>();
|
||||
const allDistinctDossierTemplates = new Set<string>();
|
||||
|
||||
this.entitiesService?.all?.forEach(entry => {
|
||||
this.entitiesService.all?.forEach(entry => {
|
||||
// all people
|
||||
entry.dossier.memberIds.forEach(f => allDistinctPeople.add(f));
|
||||
// Needs work
|
||||
entry.files.forEach(file => {
|
||||
entry.dossier.files.forEach(file => {
|
||||
allDistinctFileStatus.add(file.status);
|
||||
if (this.permissionsService.fileRequiresReanalysis(file)) allDistinctNeedsWork.add('analysis');
|
||||
if (entry.hintsOnly) allDistinctNeedsWork.add('hint');
|
||||
if (entry.hasRedactions) allDistinctNeedsWork.add('redaction');
|
||||
if (entry.hasRequests) allDistinctNeedsWork.add('suggestion');
|
||||
if (entry.hasNone) allDistinctNeedsWork.add('none');
|
||||
if (file.analysisRequired) allDistinctNeedsWork.add('analysis');
|
||||
if (entry.dossier.hintsOnly) allDistinctNeedsWork.add('hint');
|
||||
if (entry.dossier.hasRedactions) allDistinctNeedsWork.add('redaction');
|
||||
if (entry.dossier.hasRequests) allDistinctNeedsWork.add('suggestion');
|
||||
if (entry.dossier.hasNone) allDistinctNeedsWork.add('none');
|
||||
});
|
||||
|
||||
allDistinctDossierTemplates.add(entry.dossierTemplateId);
|
||||
allDistinctDossierTemplates.add(entry.dossier.dossierTemplateId);
|
||||
});
|
||||
|
||||
const statusFilters = [...allDistinctFileStatus].map<NestedFilter>(status => ({
|
||||
@ -276,22 +281,22 @@ export class DossierListingScreenComponent
|
||||
{
|
||||
key: 'my-dossiers',
|
||||
label: myDossiersLabel,
|
||||
checker: (dw: DossierWrapper) => dw.ownerId === this._userId
|
||||
checker: (dw: DossierWrapper) => dw.ownerId === this.currentUser.id
|
||||
},
|
||||
{
|
||||
key: 'to-approve',
|
||||
label: this._translateService.instant('dossier-listing.quick-filters.to-approve'),
|
||||
checker: (dw: DossierWrapper) => dw.approverIds.includes(this._userId)
|
||||
checker: (dw: DossierWrapper) => dw.approverIds.includes(this.currentUser.id)
|
||||
},
|
||||
{
|
||||
key: 'to-review',
|
||||
label: this._translateService.instant('dossier-listing.quick-filters.to-review'),
|
||||
checker: (dw: DossierWrapper) => dw.memberIds.includes(this._userId)
|
||||
checker: (dw: DossierWrapper) => dw.memberIds.includes(this.currentUser.id)
|
||||
},
|
||||
{
|
||||
key: 'other',
|
||||
label: this._translateService.instant('dossier-listing.quick-filters.other'),
|
||||
checker: (dw: DossierWrapper) => !dw.memberIds.includes(this._userId)
|
||||
checker: (dw: DossierWrapper) => !dw.memberIds.includes(this.currentUser.id)
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@ -141,7 +141,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<FileStatusW
|
||||
this._loadEntitiesFromState();
|
||||
});
|
||||
|
||||
this.addSubscription = this._appStateService.fileChanged.subscribe(() => {
|
||||
this.addSubscription = this._appStateService.fileChanged$.subscribe(() => {
|
||||
this.calculateData();
|
||||
});
|
||||
|
||||
|
||||
@ -548,7 +548,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
|
||||
private _subscribeToFileUpdates(): void {
|
||||
this.addSubscription = timer(0, 5000).subscribe(async () => await this.appStateService.reloadActiveFile());
|
||||
this.addSubscription = this.appStateService.fileReanalysed.subscribe(async (fileStatus: FileStatusWrapper) => {
|
||||
this.addSubscription = this.appStateService.fileReanalysed$.subscribe(async (fileStatus: FileStatusWrapper) => {
|
||||
if (fileStatus.fileId === this.fileId) {
|
||||
await this._loadFileData(!this._reloadFileOnReanalysis);
|
||||
this._reloadFileOnReanalysis = false;
|
||||
|
||||
@ -25,7 +25,7 @@ export class FileActionService {
|
||||
fileStatusWrapper = this._appStateService.activeFile;
|
||||
}
|
||||
return this._reanalysisControllerService.reanalyzeFile(
|
||||
this._appStateService.activeDossier.dossier.dossierId,
|
||||
this._appStateService.activeDossier.dossierId,
|
||||
fileStatusWrapper.fileId,
|
||||
true
|
||||
);
|
||||
|
||||
@ -31,9 +31,9 @@
|
||||
</div>
|
||||
<div class="red-input-group w-200 mr-8">
|
||||
<mat-select [(ngModel)]="dossier" [disabled]="!compare">
|
||||
<mat-option [value]="selectDossier">{{ selectDossier.name | translate }}</mat-option>
|
||||
<mat-option [value]="selectDossier">{{ selectDossier.dossierName | translate }}</mat-option>
|
||||
<mat-option *ngFor="let dossier of dossiers" [value]="dossier">
|
||||
{{ dossier.name }}
|
||||
{{ dossier.dossierName }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</div>
|
||||
@ -55,7 +55,7 @@
|
||||
[original]="diffEditorText"
|
||||
></ngx-monaco-diff-editor>
|
||||
|
||||
<div *ngIf="compare && dossier === selectDossier" class="no-dictionary-selected">
|
||||
<div *ngIf="compare && dossier.dossierName === selectDossier.dossierName" class="no-dictionary-selected">
|
||||
<mat-icon svgIcon="red:dictionary"></mat-icon>
|
||||
<span class="heading-l" translate="dictionary-overview.select-dictionary"></span>
|
||||
</div>
|
||||
|
||||
@ -40,7 +40,7 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
||||
showDiffEditor = false;
|
||||
searchText = '';
|
||||
|
||||
selectDossier = { name: _('dictionary-overview.compare.select-dossier') };
|
||||
selectDossier = { dossierName: _('dictionary-overview.compare.select-dossier') };
|
||||
compare: false;
|
||||
|
||||
private _codeEditor: ICodeEditor;
|
||||
|
||||
@ -16,11 +16,11 @@ export class PageHeaderComponent<T extends object> {
|
||||
|
||||
@Input() pageLabel: string;
|
||||
@Input() showCloseButton: boolean;
|
||||
@Input() actionConfigs: ActionConfig[];
|
||||
@Input() buttonConfigs: ButtonConfig[];
|
||||
@Input() actionConfigs: readonly ActionConfig[];
|
||||
@Input() buttonConfigs: readonly ButtonConfig[];
|
||||
@Input() searchPlaceholder: string;
|
||||
@Input() searchWidth: number | 'full';
|
||||
@Input() searchPosition: SearchPosition = this.searchPositions.afterFilters;
|
||||
@Input() searchPosition: SearchPosition = SearchPositions.afterFilters;
|
||||
|
||||
readonly filters$ = this.filterService?.filterGroups$.pipe(map(all => all.filter(f => f.icon)));
|
||||
readonly showResetFilters$ = this._showResetFilters$;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { EventEmitter, Injectable } from '@angular/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
import {
|
||||
DictionaryControllerService,
|
||||
Dossier,
|
||||
@ -13,7 +13,7 @@ import { Toaster } from '@services/toaster.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Event, NavigationEnd, ResolveStart, Router } from '@angular/router';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { forkJoin, Observable, of } from 'rxjs';
|
||||
import { forkJoin, Observable, of, Subject } from 'rxjs';
|
||||
import { catchError, tap } from 'rxjs/operators';
|
||||
import { FALLBACK_COLOR, hexToRgb } from '@utils/functions';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
@ -41,8 +41,8 @@ export interface AppState {
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AppStateService {
|
||||
fileChanged = new EventEmitter<FileStatusWrapper>();
|
||||
fileReanalysed = new EventEmitter<FileStatusWrapper>();
|
||||
fileChanged$ = new Subject<FileStatusWrapper>();
|
||||
fileReanalysed$ = new Subject<FileStatusWrapper>();
|
||||
private _appState: AppState;
|
||||
|
||||
constructor(
|
||||
@ -208,7 +208,7 @@ export class AppStateService {
|
||||
}
|
||||
|
||||
getDossierById(id: string) {
|
||||
return this.allDossiers.find(dossier => dossier.dossier.dossierId === id);
|
||||
return this.allDossiers.find(dossier => dossier.dossierId === id);
|
||||
}
|
||||
|
||||
getFileById(dossierId: string, fileId: string) {
|
||||
@ -252,9 +252,9 @@ export class AppStateService {
|
||||
|
||||
this._computeStats();
|
||||
if (activeFileWrapper.lastProcessed !== oldProcessedDate) {
|
||||
this.fileReanalysed.emit(activeFileWrapper);
|
||||
this.fileReanalysed$.next(activeFileWrapper);
|
||||
}
|
||||
this.fileChanged.emit(activeFileWrapper);
|
||||
this.fileChanged$.next(activeFileWrapper);
|
||||
return activeFileWrapper;
|
||||
}
|
||||
|
||||
@ -346,12 +346,13 @@ export class AppStateService {
|
||||
const updatedDossier = await this._dossiersService.createOrUpdate(dossier);
|
||||
let foundDossier = this.allDossiers.find(p => p.dossierId === updatedDossier.dossierId);
|
||||
if (foundDossier) {
|
||||
Object.assign((foundDossier.dossier = updatedDossier));
|
||||
this._appState.dossiers.splice(this._appState.dossiers.indexOf(foundDossier), 1);
|
||||
foundDossier = new DossierWrapper(updatedDossier, foundDossier.files);
|
||||
} else {
|
||||
foundDossier = new DossierWrapper(updatedDossier, []);
|
||||
this._appState.dossiers.push(foundDossier);
|
||||
}
|
||||
this._appState.dossiers = [...this._appState.dossiers];
|
||||
|
||||
this._appState.dossiers.push(foundDossier);
|
||||
return foundDossier;
|
||||
} catch (error) {
|
||||
this._toaster.error(
|
||||
@ -705,8 +706,8 @@ export class AppStateService {
|
||||
this._computeStats();
|
||||
|
||||
if (emitEvents) {
|
||||
fileReanalysedEvent.forEach(file => this.fileReanalysed.emit(file));
|
||||
fileStatusChangedEvent.forEach(file => this.fileChanged.emit(file));
|
||||
fileReanalysedEvent.forEach(file => this.fileReanalysed$.next(file));
|
||||
fileStatusChangedEvent.forEach(file => this.fileChanged$.next(file));
|
||||
}
|
||||
|
||||
return files;
|
||||
@ -716,12 +717,10 @@ export class AppStateService {
|
||||
let totalAnalysedPages = 0;
|
||||
let totalDocuments = 0;
|
||||
const totalPeople = new Set<string>();
|
||||
|
||||
this.allDossiers.forEach(d => {
|
||||
totalDocuments += d.files.length;
|
||||
if (d.dossier.memberIds) {
|
||||
d.dossier.memberIds.forEach(m => totalPeople.add(m));
|
||||
}
|
||||
|
||||
d.memberIds?.forEach(m => totalPeople.add(m));
|
||||
d.totalNumberOfPages = d.files.reduce((acc, file) => acc + file.numberOfPages, 0);
|
||||
totalAnalysedPages += d.totalNumberOfPages;
|
||||
});
|
||||
|
||||
@ -2,9 +2,32 @@ import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import * as moment from 'moment';
|
||||
import { Dictionary, Dossier } from '@redaction/red-ui-http';
|
||||
|
||||
export class DossierWrapper {
|
||||
totalNumberOfPages?: number;
|
||||
export class DossierWrapper implements Dossier {
|
||||
readonly approverIds = this._dossier.approverIds;
|
||||
readonly date = this._dossier.date;
|
||||
readonly description = this._dossier.description;
|
||||
readonly dossierId = this._dossier.dossierId;
|
||||
readonly dossierName = this._dossier.dossierName;
|
||||
readonly dossierTemplateId = this._dossier.dossierTemplateId;
|
||||
readonly downloadFileTypes = this._dossier.downloadFileTypes;
|
||||
readonly dueDate = this._dossier.dueDate;
|
||||
readonly hardDeletedTime = this._dossier.hardDeletedTime;
|
||||
readonly memberIds = this._dossier.memberIds;
|
||||
readonly ownerId = this._dossier.ownerId;
|
||||
readonly reportTemplateIds = this._dossier.reportTemplateIds;
|
||||
readonly reportTypes = this._dossier.reportTypes;
|
||||
readonly softDeletedTime = this._dossier.softDeletedTime;
|
||||
readonly status = this._dossier.status;
|
||||
readonly watermarkEnabled = this._dossier.watermarkEnabled;
|
||||
|
||||
readonly hasMoreThanOneApprover = this.approverIds.length > 1;
|
||||
readonly hasMoreThanOneReviewer = this.memberIds.length > 1;
|
||||
readonly memberCount = this.memberIds.length;
|
||||
|
||||
hasFiles = this._files.length > 0;
|
||||
filesLength = this._files.length;
|
||||
|
||||
totalNumberOfPages?: number;
|
||||
hintsOnly?: boolean;
|
||||
hasRedactions?: boolean;
|
||||
hasRequests?: boolean;
|
||||
@ -12,15 +35,12 @@ export class DossierWrapper {
|
||||
hasPendingOrProcessing?: boolean;
|
||||
|
||||
allFilesApproved?: boolean;
|
||||
type: Dictionary;
|
||||
type?: Dictionary;
|
||||
|
||||
constructor(public dossier: Dossier, files: FileStatusWrapper[]) {
|
||||
this._files = files ? files : [];
|
||||
constructor(private readonly _dossier: Dossier, private _files: FileStatusWrapper[] = []) {
|
||||
this._recomputeFileStatus();
|
||||
}
|
||||
|
||||
private _files: FileStatusWrapper[];
|
||||
|
||||
get files() {
|
||||
return this._files;
|
||||
}
|
||||
@ -30,84 +50,16 @@ export class DossierWrapper {
|
||||
this._recomputeFileStatus();
|
||||
}
|
||||
|
||||
get hasMoreThanOneApprover() {
|
||||
return this.approverIds.length > 1;
|
||||
}
|
||||
|
||||
get hasMoreThanOneReviewer() {
|
||||
return this.memberIds.length > 1;
|
||||
}
|
||||
|
||||
get dossierName() {
|
||||
return this.dossier.dossierName;
|
||||
}
|
||||
|
||||
get description() {
|
||||
return this.dossier.description;
|
||||
}
|
||||
|
||||
get dossierTemplateId() {
|
||||
return this.dossier.dossierTemplateId;
|
||||
}
|
||||
|
||||
get ownerId() {
|
||||
return this.dossier.ownerId;
|
||||
}
|
||||
|
||||
get dossierId() {
|
||||
return this.dossier.dossierId;
|
||||
}
|
||||
|
||||
get memberIds() {
|
||||
return this.dossier.memberIds;
|
||||
}
|
||||
|
||||
get approverIds() {
|
||||
return this.dossier.approverIds;
|
||||
}
|
||||
|
||||
get dossierDate() {
|
||||
return this.dossier.date;
|
||||
}
|
||||
|
||||
get numberOfMembers() {
|
||||
return this.dossier.memberIds.length;
|
||||
}
|
||||
|
||||
get dueDate() {
|
||||
return this.dossier.dueDate;
|
||||
}
|
||||
|
||||
get hasFiles() {
|
||||
return this._files.length > 0;
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.dossier.dossierName;
|
||||
}
|
||||
|
||||
get memberCount() {
|
||||
return this.dossier.memberIds.length;
|
||||
}
|
||||
|
||||
get watermarkEnabled(): boolean {
|
||||
return this.dossier.watermarkEnabled;
|
||||
}
|
||||
|
||||
hasStatus(status: string): boolean {
|
||||
return !!this._files.find(f => f.status === status);
|
||||
}
|
||||
|
||||
hasMember(key: string) {
|
||||
return this.dossier.memberIds.indexOf(key) >= 0;
|
||||
}
|
||||
|
||||
dueDateMatches(key: string) {
|
||||
return moment(this.dueDate).format('DD/MM/YYYY') === key;
|
||||
return this._dossier.memberIds.indexOf(key) >= 0;
|
||||
}
|
||||
|
||||
addedDateMatches(key: string) {
|
||||
return moment(this.dossierDate).format('DD/MM/YYYY') === key;
|
||||
return moment(this.date).format('DD/MM/YYYY') === key;
|
||||
}
|
||||
|
||||
private _recomputeFileStatus() {
|
||||
@ -127,5 +79,7 @@ export class DossierWrapper {
|
||||
this.hasPendingOrProcessing = this.hasPendingOrProcessing || f.isPending || f.isProcessing;
|
||||
});
|
||||
this.hasNone = !this.hasRequests && !this.hasRedactions && !this.hintsOnly;
|
||||
this.hasFiles = this._files.length > 0;
|
||||
this.filesLength = this._files.length;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user