From 9ba4120aa0c1a9523d940fdc8f4a3f37b085c5ba Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Fri, 12 Nov 2021 18:09:06 +0200 Subject: [PATCH] move chart computations to dossier listing details component --- .../dossier-details.component.html | 2 +- .../dossier-details.component.ts | 16 ++--- .../dossiers-listing-details.component.html | 7 ++- .../dossiers-listing-details.component.ts | 61 +++++++++++++++++-- .../dossiers-listing-screen.component.html | 8 +-- .../dossiers-listing-screen.component.ts | 44 ++----------- .../entity-services/dossiers.service.ts | 2 +- .../red-ui/src/app/state/app-state.service.ts | 21 +------ .../src/lib/dossiers/dossier.model.ts | 4 -- 9 files changed, 77 insertions(+), 88 deletions(-) diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details/dossier-details.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details/dossier-details.component.html index 184e7558a..7948aa15a 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details/dossier-details.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details/dossier-details.component.html @@ -41,7 +41,7 @@
dossier.stats$), - // map(stats => this._calculateChartConfig(stats.fileCountPerWorkflowStatus)), - // ); } get managers() { - return this._userService.managerUsers; + return this._userService.managerUsers.map(manager => manager.id); } - calculateChartConfig(dossier: Dossier): DoughnutChartConfig[] { - const groups = groupBy(dossier?.files, 'status'); - const documentsChartData: DoughnutChartConfig[] = Object.keys(groups).map(status => ({ - value: groups[status].length, + calculateChartConfig(filesCount: FileCountPerWorkflowStatus): DoughnutChartConfig[] { + const documentsChartData: DoughnutChartConfig[] = Object.keys(filesCount).map(status => ({ + value: filesCount[status], color: status, label: fileStatusTranslations[status], key: status, diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.html index 8bcc76779..81fc4b41c 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.html @@ -1,6 +1,7 @@
+
; + readonly dossiersChartData$: Observable; - constructor(readonly filterService: FilterService, readonly dossiersService: DossiersService) {} + constructor( + readonly filterService: FilterService, + readonly dossiersService: DossiersService, + private readonly _translateChartService: TranslateChartService, + ) { + this.documentsChartData$ = this.dossiersService.all$.pipe( + mapEach(dossier => dossier.stats$), + switchMap(stats$ => combineLatest(stats$)), + filter(stats => !stats.some(s => s === undefined)), + map(stats => this._toChartData(stats)), + ); + + this.dossiersChartData$ = this.dossiersService.all$.pipe(map(dossiers => this._toDossierChartData(dossiers))); + } + + private _toDossierChartData(dossiers: Dossier[]): DoughnutChartConfig[] { + const activeDossiersCount = dossiers.filter(p => p.status === DossierStatuses.ACTIVE).length; + const inactiveDossiersCount = (dossiers.length = activeDossiersCount); + + return [ + { value: activeDossiersCount, color: 'ACTIVE', label: _('active') }, + { value: inactiveDossiersCount, color: 'DELETED', label: _('archived') }, + ]; + } + + private _toChartData(stats: DossierStats[]) { + const chartData: FileCountPerWorkflowStatus = {}; + stats.forEach(stat => { + const statuses: FileCountPerWorkflowStatus = stat.fileCountPerWorkflowStatus; + Object.keys(statuses).forEach(status => { + chartData[status] = chartData[status] ? (chartData[status] as number) + (statuses[status] as number) : statuses[status]; + }); + }); + + const documentsChartData = Object.keys(chartData).map( + status => + ({ + value: chartData[status], + color: status, + label: fileStatusTranslations[status], + key: status, + } as DoughnutChartConfig), + ); + documentsChartData.sort((a, b) => StatusSorter.byStatus(a.key, b.key)); + return this._translateChartService.translateStatus(documentsChartData); + } } diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/screen/dossiers-listing-screen.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/screen/dossiers-listing-screen.component.html index 3994773e7..d5d25bd00 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/screen/dossiers-listing-screen.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/screen/dossiers-listing-screen.component.html @@ -18,11 +18,7 @@
- +
@@ -32,5 +28,5 @@ - + diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/screen/dossiers-listing-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/screen/dossiers-listing-screen.component.ts index 71194edd6..e8f138a6a 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/screen/dossiers-listing-screen.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/screen/dossiers-listing-screen.component.ts @@ -10,18 +10,15 @@ import { ViewChild, } from '@angular/core'; import { AppStateService } from '@state/app-state.service'; -import { Dossier, DossierStatuses, StatusSorter } from '@red/domain'; +import { Dossier } from '@red/domain'; import { UserService } from '@services/user.service'; import { PermissionsService } from '@services/permissions.service'; import { TranslateChartService } from '@services/translate-chart.service'; -import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/simple-doughnut-chart.component'; import { timer } from 'rxjs'; import { tap } from 'rxjs/operators'; import { Router } from '@angular/router'; import { DossiersDialogService } from '../../../services/dossiers-dialog.service'; -import { groupBy } from '@utils/index'; import { DefaultListingServicesTmp, EntitiesService, ListingComponent, OnAttach, OnDetach, TableComponent } from '@iqser/common-ui'; -import { fileStatusTranslations } from '../../../translations/file-status-translations'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { ConfigService } from '../config.service'; import { DossiersService } from '@services/entity-services/dossiers.service'; @@ -44,8 +41,6 @@ export class DossiersListingScreenComponent readonly tableColumnConfigs = this._configService.tableConfig; readonly tableHeaderLabel = _('dossier-listing.table-header.title'); readonly buttonConfigs = this._configService.buttonsConfig(() => this.openAddDossierDialog()); - dossiersChartData: DoughnutChartConfig[] = []; - documentsChartData: DoughnutChartConfig[] = []; private _lastScrolledIndex: number; @ViewChild('needsWorkFilterTemplate', { read: TemplateRef, @@ -66,23 +61,14 @@ export class DossiersListingScreenComponent private readonly _configService: ConfigService, ) { super(_injector); - this._appStateService.reset(); - } - - private get _activeDossiersCount(): number { - return this.entitiesService.all.filter(p => p.status === DossierStatuses.ACTIVE).length; - } - - private get _inactiveDossiersCount(): number { - return this.entitiesService.all.length - this._activeDossiersCount; } ngOnInit(): void { - this.calculateData(); + this.computeAllFilters(); this.addSubscription = timer(0, 20000).subscribe(async () => { await this._appStateService.loadAllDossiers(); - this.calculateData(); + this.computeAllFilters(); }); } @@ -115,29 +101,7 @@ export class DossiersListingScreenComponent }); } - calculateData(): void { - this._computeAllFilters(); - - this.dossiersChartData = [ - { value: this._activeDossiersCount, color: 'ACTIVE', label: _('active') }, - { value: this._inactiveDossiersCount, color: 'DELETED', label: _('archived') }, - ]; - const groups = groupBy(this._dossiersService.allFiles, 'status'); - this.documentsChartData = []; - - for (const status of Object.keys(groups)) { - this.documentsChartData.push({ - value: groups[status].length, - color: status, - label: fileStatusTranslations[status], - key: status, - }); - } - this.documentsChartData.sort((a, b) => StatusSorter.byStatus(a.key, b.key)); - this.documentsChartData = this._translateChartService.translateStatus(this.documentsChartData); - } - - private _computeAllFilters() { + computeAllFilters() { const filterGroups = this._configService.filterGroups(this.entitiesService.all, this._needsWorkFilterTemplate); this.filterService.addFilterGroups(filterGroups); } diff --git a/apps/red-ui/src/app/services/entity-services/dossiers.service.ts b/apps/red-ui/src/app/services/entity-services/dossiers.service.ts index afca232c5..e31465590 100644 --- a/apps/red-ui/src/app/services/entity-services/dossiers.service.ts +++ b/apps/red-ui/src/app/services/entity-services/dossiers.service.ts @@ -109,7 +109,7 @@ export class DossiersService extends EntitiesService { const stats$ = dossier$.pipe(switchMap(updatedDossier => this._dossierStatsService.getFor([updatedDossier.dossierId]))); return combineLatest([dossier$, stats$]).pipe( - map(([updatedDossier, stats]) => new Dossier(updatedDossier, stats[0], this.find(updatedDossier.dossierId)?.files ?? [])), + map(([updatedDossier, stats]) => new Dossier(updatedDossier, stats[0], [])), tap(newDossier => this.replace(newDossier)), catchError(showToast), ); diff --git a/apps/red-ui/src/app/state/app-state.service.ts b/apps/red-ui/src/app/state/app-state.service.ts index 0806d07d7..9504a8d0e 100644 --- a/apps/red-ui/src/app/state/app-state.service.ts +++ b/apps/red-ui/src/app/state/app-state.service.ts @@ -120,7 +120,7 @@ export class AppStateService { return data ? data : this._dictionaryData[dossierTemplateId]['default']; } - async loadAllDossiers(emitEvents = true) { + async loadAllDossiers() { const dossiers = await this._dossiersService.get().toPromise(); if (!dossiers) { return; @@ -133,17 +133,9 @@ export class AppStateService { const oldDossier = this._dossiersService.find(p.dossierId); const type = oldDossier?.type ?? (await this._getDictionaryFor(p)); const stats = dossierStats.find(s => s.dossierId === p.dossierId); - return new Dossier(p, stats, oldDossier?.files ?? [], type); + this._dossiersService.replace(new Dossier(p, stats, [], type)); }); - const mappedDossiers = await Promise.all(mappedDossiers$); - const fileData = await this._filesService.getFor(mappedDossiers.map(p => p.id)).toPromise(); - - for (const dossierId of Object.keys(fileData)) { - const dossier = mappedDossiers.find(p => p.id === dossierId); - if (dossier) { - this._processFiles(dossier, fileData[dossierId], emitEvents); - } - } + return Promise.all(mappedDossiers$); } async reloadActiveFile() { @@ -160,10 +152,6 @@ export class AppStateService { this._userService.getNameForId(iFile.currentReviewer), this._fileAttributesService.getFileAttributeConfig(activeDossier.dossierTemplateId), ); - const files = activeDossier.files.filter(file => file.fileId !== activeFile.fileId); - files.push(activeFile); - const newDossier = new Dossier(activeDossier, activeDossier.stats, files, activeDossier.type); - this._dossiersService.replace(newDossier); if (activeFile.lastProcessed !== oldProcessedDate) { this.fileReanalysed$.next(activeFile); @@ -514,9 +502,6 @@ export class AppStateService { } } - const newDossier = new Dossier(dossier, dossier.stats, newFiles, dossier.type); - this._dossiersService.replace(newDossier); - return newFiles; } } diff --git a/libs/red-domain/src/lib/dossiers/dossier.model.ts b/libs/red-domain/src/lib/dossiers/dossier.model.ts index 3165c5ad2..a27ed0246 100644 --- a/libs/red-domain/src/lib/dossiers/dossier.model.ts +++ b/libs/red-domain/src/lib/dossiers/dossier.model.ts @@ -68,10 +68,6 @@ export class Dossier implements IDossier, IListable { return this._stats$.getValue(); } - hasStatus(status: string): boolean { - return !!this.files.find(f => f.status === status); - } - hasMember(memberId: string): boolean { return !!this.memberIds && this.memberIds.indexOf(memberId) >= 0; }