RED-3411: Display processing stats

This commit is contained in:
Adina Țeudan 2022-02-18 16:31:52 +02:00
parent 8a0ab0ae84
commit 168f748924
6 changed files with 107 additions and 19 deletions

View File

@ -23,8 +23,8 @@
[tooltip]="'dossier-details.edit-owner' | translate"
class="ml-14"
icon="iqser:edit"
tooltipPosition="below"
iqserHelpMode="edit_dossier_owner"
tooltipPosition="below"
></iqser-circle-button>
</ng-container>
</div>
@ -38,7 +38,7 @@
<ng-container *ngIf="dossierStats$ | async as stats">
<div *ngIf="stats.hasFiles" class="mt-24">
<redaction-simple-doughnut-chart
[config]="calculateChartConfig(stats)"
[config]="chartConfig$ | async"
[radius]="63"
[strokeWidth]="15"
[subtitle]="'dossier-overview.dossier-details.charts.documents-in-dossier' | translate"
@ -47,9 +47,13 @@
></redaction-simple-doughnut-chart>
</div>
<div *ngIf="statusConfig$ | async as statusConfig" class="mt-24">
<iqser-progress-bar *ngFor="let config of statusConfig" [config]="config"></iqser-progress-bar>
</div>
<div
*ngIf="stats.hasFiles && needsWorkFilters$ | async as filters"
class="mt-24 legend pb-32"
class="mt-32 legend pb-32"
iqserHelpMode="filter_for_editing_notes"
>
<div

View File

@ -41,3 +41,7 @@
}
}
}
iqser-progress-bar:not(:last-child) {
margin-bottom: 10px;
}

View File

@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, In
import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/simple-doughnut-chart.component';
import { TranslateChartService } from '@services/translate-chart.service';
import { UserService } from '@services/user.service';
import { FilterService, shareLast, Toaster } from '@iqser/common-ui';
import { FilterService, ProgressBarConfigModel, shareLast, Toaster } from '@iqser/common-ui';
import { workflowFileStatusTranslations } from '../../../../translations/file-status-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { Dossier, DossierAttributeWithValue, DossierStats, IDossierRequest, StatusSorter, User } from '@red/domain';
@ -10,7 +10,7 @@ import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActivatedRoute } from '@angular/router';
import { firstValueFrom, Observable } from 'rxjs';
import { DossierStatsService } from '@services/entity-services/dossier-stats.service';
import { pluck, switchMap } from 'rxjs/operators';
import { map, pluck, switchMap } from 'rxjs/operators';
import { DossiersDialogService } from '../../../../services/dossiers-dialog.service';
import { FilesService } from '@services/entity-services/files.service';
import { DOSSIER_ID } from '@utils/constants';
@ -33,6 +33,8 @@ export class DossierDetailsComponent {
readonly dossierId: string;
readonly dossier$: Observable<Dossier>;
readonly dossierStats$: Observable<DossierStats>;
chartConfig$: Observable<DoughnutChartConfig[]>;
statusConfig$: Observable<ProgressBarConfigModel[]>;
constructor(
readonly dossiersService: DossiersService,
@ -52,23 +54,14 @@ export class DossierDetailsComponent {
pluck('dossierId'),
switchMap(dossierId => this._dossierStatsService.watch$(dossierId)),
);
this.chartConfig$ = this.dossierStats$.pipe(map(stats => this.#calculateChartConfig(stats)));
this.statusConfig$ = this.dossierStats$.pipe(map(stats => this.#calculateStatusConfig(stats)));
}
get managers() {
return this._userService.managerUsers.map(manager => manager.id);
}
calculateChartConfig(stats: DossierStats): DoughnutChartConfig[] {
const documentsChartData: DoughnutChartConfig[] = Object.keys(stats.fileCountPerWorkflowStatus).map(status => ({
value: stats.fileCountPerWorkflowStatus[status],
color: status,
label: workflowFileStatusTranslations[status],
key: status,
}));
documentsChartData.sort((a, b) => StatusSorter.byStatus(a.key, b.key));
return this.translateChartService.translateStatus(documentsChartData);
}
async assignOwner(user: User | string, dossier: Dossier) {
const owner = typeof user === 'string' ? this._userService.find(user) : user;
const dossierRequest: IDossierRequest = { ...dossier, ownerId: owner.id };
@ -78,4 +71,44 @@ export class DossierDetailsComponent {
const dossierName = dossier.dossierName;
this._toaster.info(_('assignment.owner'), { params: { ownerName, dossierName } });
}
#calculateChartConfig(stats: DossierStats): DoughnutChartConfig[] {
const documentsChartData: DoughnutChartConfig[] = Object.keys(stats.fileCountPerWorkflowStatus).map(status => ({
value: stats.fileCountPerWorkflowStatus[status],
color: status,
label: workflowFileStatusTranslations[status],
key: status,
}));
documentsChartData.sort((a, b) => StatusSorter.byStatus(a.key, b.key));
return this.translateChartService.translateStatus(documentsChartData);
}
#calculateStatusConfig(stats: DossierStats): ProgressBarConfigModel[] {
return [
{
label: _('processing-status.pending'),
total: stats.numberOfFiles,
count: stats.processingStats.pending,
icon: 'red:reanalyse',
},
{
label: _('processing-status.ocr'),
total: stats.numberOfFiles,
count: stats.processingStats.ocr,
icon: 'iqser:ocr',
},
{
label: _('processing-status.processing'),
total: stats.numberOfFiles,
count: stats.processingStats.processing,
icon: 'red:reanalyse',
},
{
label: _('processing-status.processed'),
total: stats.numberOfFiles,
count: stats.processingStats.proccesed,
icon: 'red:ready-for-approval',
},
].filter(config => config.count > 0);
}
}

View File

@ -1532,6 +1532,12 @@
},
"toggle-tooltips": "{active, select, true{Disable} false{Enable} other{}} annotation tooltips"
},
"processing-status": {
"ocr": "OCR",
"pending": "Pending",
"processed": "Processed",
"processing": "Processing"
},
"readonly": "Read only",
"recategorize-image-dialog": {
"actions": {

@ -1 +1 @@
Subproject commit cec7a033629be8110ddb838c279fb3a6a15a9e18
Subproject commit 12fd37dd11e4f47b0755c6b613d4efd8de140135

View File

@ -1,6 +1,33 @@
import { IDossierStats } from './dossier-stats';
import { FileCountPerProcessingStatus, FileCountPerWorkflowStatus } from './types';
import { isProcessingStatuses, ProcessingFileStatus } from '../files';
import { isProcessingStatuses, ProcessingFileStatus, ProcessingFileStatuses } from '../files';
const PENDING_STATES: ProcessingFileStatus[] = [
ProcessingFileStatuses.ANALYSE,
ProcessingFileStatuses.ERROR,
ProcessingFileStatuses.FULLREPROCESS,
ProcessingFileStatuses.REPROCESS,
ProcessingFileStatuses.UNPROCESSED,
];
const PROCESSING_STATES: ProcessingFileStatus[] = [
ProcessingFileStatuses.IMAGE_ANALYZING,
ProcessingFileStatuses.INDEXING,
ProcessingFileStatuses.NER_ANALYZING,
ProcessingFileStatuses.PROCESSING,
ProcessingFileStatuses.SURROUNDING_TEXT_PROCESSING,
];
const PROCESSED_STATES: ProcessingFileStatus[] = [ProcessingFileStatuses.PROCESSED];
const OCR_STATES: ProcessingFileStatus[] = [ProcessingFileStatuses.OCR_PROCESSING];
interface ProcessingStats {
pending: number;
ocr: number;
processing: number;
proccesed: number;
}
export class DossierStats implements IDossierStats {
readonly dossierId: string;
@ -14,6 +41,7 @@ export class DossierStats implements IDossierStats {
readonly numberOfPages: number;
readonly numberOfFiles: number;
readonly numberOfProcessingFiles: number;
readonly processingStats: ProcessingStats;
readonly hasFiles: boolean;
@ -31,7 +59,20 @@ export class DossierStats implements IDossierStats {
this.numberOfProcessingFiles = Object.entries<number>(this.fileCountPerProcessingStatus)
.filter(([key, _]) => isProcessingStatuses.includes(key as ProcessingFileStatus))
.reduce((count, [_, value]) => count + value, 0);
this.processingStats = this.#processingStats;
this.hasFiles = this.numberOfFiles > 0;
}
get #processingStats(): ProcessingStats {
return {
pending: this.#getTotal(PENDING_STATES),
proccesed: this.#getTotal(PROCESSED_STATES),
processing: this.#getTotal(PROCESSING_STATES),
ocr: this.#getTotal(OCR_STATES),
};
}
#getTotal(states: ProcessingFileStatus[]): number {
return states.reduce((total, state) => total + (this.fileCountPerProcessingStatus[state] || 0), 0);
}
}