RED-3411: list indicator

This commit is contained in:
Adina Țeudan 2022-02-17 19:55:18 +02:00
parent 7c1347bc24
commit 8b1d63a675
17 changed files with 70 additions and 40 deletions

View File

@ -2,6 +2,7 @@ import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
import { IDossierState } from '@red/domain'; import { IDossierState } from '@red/domain';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { FormBuilder, FormGroup } from '@angular/forms'; import { FormBuilder, FormGroup } from '@angular/forms';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
interface DialogData { interface DialogData {
readonly toBeDeletedState: IDossierState; readonly toBeDeletedState: IDossierState;
@ -38,7 +39,7 @@ export class ConfirmDeleteDossierStateDialogComponent {
} }
get label(): string { get label(): string {
return this.replaceDossierStatusId ? 'confirm-delete-dossier-state.delete-replace' : 'confirm-delete-dossier-state.delete'; return this.replaceDossierStatusId ? _('confirm-delete-dossier-state.delete-replace') : _('confirm-delete-dossier-state.delete');
} }
get afterCloseValue(): string | true { get afterCloseValue(): string | true {

View File

@ -1,5 +1,11 @@
<div> <div>
<div [class.error]="file.isError" [matTooltip]="file.filename" class="table-item-title" matTooltipPosition="above"> <div
[class.error]="file.isError"
[class.initial-processing]="file.isInitialProcessing"
[matTooltip]="file.filename"
class="table-item-title"
matTooltipPosition="above"
>
{{ file.filename }} {{ file.filename }}
</div> </div>
</div> </div>

View File

@ -2,6 +2,14 @@
.table-item-title { .table-item-title {
max-width: 25vw; max-width: 25vw;
&.error {
color: var(--iqser-red-1);
}
&.initial-processing {
color: var(--iqser-disabled);
}
} }
.primary-attribute { .primary-attribute {

View File

@ -40,15 +40,13 @@
<div [class.extend-cols]="file.isError" class="status-container cell"> <div [class.extend-cols]="file.isError" class="status-container cell">
<div *ngIf="file.isError" class="small-label error" translate="dossier-overview.file-listing.file-entry.file-error"></div> <div *ngIf="file.isError" class="small-label error" translate="dossier-overview.file-listing.file-entry.file-error"></div>
<div *ngIf="file.isPending" class="small-label" translate="dossier-overview.file-listing.file-entry.file-pending"></div> <div *ngIf="file.isUnprocessed" class="small-label" translate="dossier-overview.file-listing.file-entry.file-pending"></div>
<div *ngIf="file.isProcessing || file.canBeOpened" class="status-wrapper"> <div *ngIf="file.isProcessing || file.canBeOpened" class="status-wrapper">
<div *ngIf="file.isProcessing" [matTooltip]="'file-status.processing' | translate" class="spinning-icon" matTooltipPosition="above"> <redaction-processing-indicator [file]="file"></redaction-processing-indicator>
<mat-icon svgIcon="red:reanalyse"></mat-icon>
</div>
<iqser-status-bar <iqser-status-bar
*ngIf="!file.isError && !file.isPending" *ngIf="!file.isError && !file.isUnprocessed && !file.isInitialProcessing"
[configs]="[ [configs]="[
{ {
color: file.workflowStatus, color: file.workflowStatus,

View File

@ -20,14 +20,7 @@
<redaction-file-workload [file]="file"></redaction-file-workload> <redaction-file-workload [file]="file"></redaction-file-workload>
<div class="file-actions"> <div class="file-actions">
<div <redaction-processing-indicator [file]="file" class="mr-8"></redaction-processing-indicator>
*ngIf="file.isProcessing"
class="spinning-icon mr-8"
matTooltip="{{ 'file-status.processing' | translate }}"
matTooltipPosition="above"
>
<mat-icon svgIcon="red:reanalyse"></mat-icon>
</div>
<div #actionsWrapper class="actions-wrapper"> <div #actionsWrapper class="actions-wrapper">
<redaction-file-actions <redaction-file-actions

View File

@ -6,14 +6,7 @@
</div> </div>
<div class="flex-1 actions-container"> <div class="flex-1 actions-container">
<div <redaction-processing-indicator [file]="file" class="mr-16"></redaction-processing-indicator>
*ngIf="file.isProcessing"
class="spinning-icon mr-16"
matTooltip="{{ 'file-status.processing' | translate }}"
matTooltipPosition="above"
>
<mat-icon svgIcon="red:reanalyse"></mat-icon>
</div>
<redaction-user-management></redaction-user-management> <redaction-user-management></redaction-user-management>

View File

@ -566,7 +566,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
return this._router.navigate([this._dossiersService.find(this.dossierId).routerLink]); return this._router.navigate([this._dossiersService.find(this.dossierId).routerLink]);
} }
if (file.isPending) { if (file.isUnprocessed) {
return; return;
} }

View File

@ -1,13 +1,6 @@
<div *ngIf="isDossierOverviewList" class="action-buttons"> <div *ngIf="isDossierOverviewList" class="action-buttons">
<ng-container *ngTemplateOutlet="actions"></ng-container> <ng-container *ngTemplateOutlet="actions"></ng-container>
<div <redaction-processing-indicator *ngIf="showStatusBar" [file]="file"></redaction-processing-indicator>
*ngIf="showStatusBar && file.isProcessing"
class="spinning-icon"
matTooltip="{{ 'file-status.processing' | translate }}"
matTooltipPosition="above"
>
<mat-icon svgIcon="red:reanalyse"></mat-icon>
</div>
<iqser-status-bar *ngIf="showStatusBar" [configs]="[{ color: file.workflowStatus, length: 1 }]"></iqser-status-bar> <iqser-status-bar *ngIf="showStatusBar" [configs]="[{ color: file.workflowStatus, length: 1 }]"></iqser-status-bar>
</div> </div>

View File

@ -373,7 +373,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
this.canDisableAutoAnalysis = this._permissionsService.canDisableAutoAnalysis([this.file]); this.canDisableAutoAnalysis = this._permissionsService.canDisableAutoAnalysis([this.file]);
this.canEnableAutoAnalysis = this._permissionsService.canEnableAutoAnalysis([this.file]); this.canEnableAutoAnalysis = this._permissionsService.canEnableAutoAnalysis([this.file]);
this.showStatusBar = !this.file.isError && !this.file.isPending && this.isDossierOverviewList; this.showStatusBar = !this.file.isError && !this.file.isUnprocessed && this.isDossierOverviewList;
this.showAssignToSelf = this._permissionsService.canAssignToSelf(this.file) && this.isDossierOverview; this.showAssignToSelf = this._permissionsService.canAssignToSelf(this.file) && this.isDossierOverview;
this.showAssign = this.showAssign =

View File

@ -10,6 +10,8 @@ export const workflowFileStatusTranslations: { [key in WorkflowFileStatus]: stri
}; };
export const processingFileStatusTranslations: { [key in ProcessingFileStatus]: string } = { export const processingFileStatusTranslations: { [key in ProcessingFileStatus]: string } = {
ANALYSE: _('file-status.analyse'),
NER_ANALYZING: _('file-status.ner-analyzing'),
PROCESSED: _('file-status.processed'), PROCESSED: _('file-status.processed'),
DELETED: _('file-status.deleted'), DELETED: _('file-status.deleted'),
ERROR: _('file-status.error'), ERROR: _('file-status.error'),

View File

@ -0,0 +1,3 @@
<div *ngIf="file.isProcessing" [matTooltip]="tooltip | translate" class="spinning-icon" matTooltipPosition="above">
<mat-icon svgIcon="red:reanalyse"></mat-icon>
</div>

View File

@ -0,0 +1,3 @@
:host {
display: block;
}

View File

@ -0,0 +1,18 @@
import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core';
import { File } from '@red/domain';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
@Component({
selector: 'redaction-processing-indicator [file]',
templateUrl: './processing-indicator.component.html',
styleUrls: ['./processing-indicator.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ProcessingIndicatorComponent implements OnChanges {
tooltip: string;
@Input() file: File;
ngOnChanges() {
this.tooltip = this.file.isInitialProcessing ? _('file-status.initial-processing') : _('file-status.re-processing');
}
}

View File

@ -26,6 +26,7 @@ import { TypeFilterComponent } from './components/type-filter/type-filter.compon
import { TeamMembersComponent } from './components/team-members/team-members.component'; import { TeamMembersComponent } from './components/team-members/team-members.component';
import { EditorComponent } from './components/editor/editor.component'; import { EditorComponent } from './components/editor/editor.component';
import { ExpandableFileActionsComponent } from './components/expandable-file-actions/expandable-file-actions.component'; import { ExpandableFileActionsComponent } from './components/expandable-file-actions/expandable-file-actions.component';
import { ProcessingIndicatorComponent } from '@shared/components/processing-indicator/processing-indicator.component';
const buttons = [FileDownloadBtnComponent, UserButtonComponent]; const buttons = [FileDownloadBtnComponent, UserButtonComponent];
@ -41,6 +42,7 @@ const components = [
TypeFilterComponent, TypeFilterComponent,
TeamMembersComponent, TeamMembersComponent,
ExpandableFileActionsComponent, ExpandableFileActionsComponent,
ProcessingIndicatorComponent,
...buttons, ...buttons,
]; ];

View File

@ -410,8 +410,8 @@
"configurations": "Configurations", "configurations": "Configurations",
"confirm-delete-dossier-state": { "confirm-delete-dossier-state": {
"cancel": "Cancel", "cancel": "Cancel",
"delete-replace": "Delete and Replace",
"delete": "Delete only", "delete": "Delete only",
"delete-replace": "Delete and Replace",
"form": { "form": {
"status": "Replace Status", "status": "Replace Status",
"status-placeholder": "Choose another status" "status-placeholder": "Choose another status"
@ -910,12 +910,12 @@
}, },
"download-type": { "download-type": {
"annotated": "Annotated PDF", "annotated": "Annotated PDF",
"delta-preview": "Delta PDF",
"flatten": "Flatten PDF", "flatten": "Flatten PDF",
"label": "{length} document {length, plural, one{version} other{versions}}", "label": "{length} document {length, plural, one{version} other{versions}}",
"original": "Optimized PDF", "original": "Optimized PDF",
"preview": "Preview PDF", "preview": "Preview PDF",
"redacted": "Redacted PDF", "redacted": "Redacted PDF"
"delta-preview": "Delta PDF"
}, },
"downloads-list": { "downloads-list": {
"actions": { "actions": {
@ -1248,16 +1248,20 @@
} }
}, },
"file-status": { "file-status": {
"analyse": "Analyzing",
"approved": "Approved", "approved": "Approved",
"deleted": "Deleted", "deleted": "Deleted",
"error": "Re-processing required", "error": "Re-processing required",
"full-reprocess": "Processing", "full-reprocess": "Processing",
"image-analyzing": "Image Analyzing", "image-analyzing": "Image Analyzing",
"indexing": "Processing", "indexing": "Processing",
"initial-processing": "Initial processing...",
"ner-analyzing": "NER Analyzing",
"new": "New", "new": "New",
"ocr-processing": "OCR Processing", "ocr-processing": "OCR Processing",
"processed": "Processed", "processed": "Processed",
"processing": "Processing...", "processing": "Processing...",
"re-processing": "Re-processing...",
"reprocess": "Processing", "reprocess": "Processing",
"unassigned": "Unassigned", "unassigned": "Unassigned",
"under-approval": "Under Approval", "under-approval": "Under Approval",

View File

@ -48,8 +48,9 @@ export class File extends Entity<IFile> implements IFile {
readonly isNew: boolean; readonly isNew: boolean;
readonly isError: boolean; readonly isError: boolean;
readonly isProcessing: boolean; readonly isProcessing: boolean;
readonly isInitialProcessing: boolean;
readonly isApproved: boolean; readonly isApproved: boolean;
readonly isPending: boolean; readonly isUnprocessed: boolean;
readonly isUnderReview: boolean; readonly isUnderReview: boolean;
readonly isUnderApproval: boolean; readonly isUnderApproval: boolean;
readonly canBeApproved: boolean; readonly canBeApproved: boolean;
@ -89,6 +90,7 @@ export class File extends Entity<IFile> implements IFile {
this.processingStatus = file.processingStatus; this.processingStatus = file.processingStatus;
this.workflowStatus = file.workflowStatus; this.workflowStatus = file.workflowStatus;
this.isError = this.processingStatus === ProcessingFileStatuses.ERROR; this.isError = this.processingStatus === ProcessingFileStatuses.ERROR;
this.isUnprocessed = this.processingStatus === ProcessingFileStatuses.UNPROCESSED;
this.numberOfPages = this.isError ? 0 : file.numberOfPages ?? 0; this.numberOfPages = this.isError ? 0 : file.numberOfPages ?? 0;
this.rulesVersion = file.rulesVersion; this.rulesVersion = file.rulesVersion;
this.uploader = file.uploader; this.uploader = file.uploader;
@ -99,14 +101,14 @@ export class File extends Entity<IFile> implements IFile {
this.cacheIdentifier = btoa((this.lastUploaded ?? '') + (this.lastOCRTime ?? '')); this.cacheIdentifier = btoa((this.lastUploaded ?? '') + (this.lastOCRTime ?? ''));
this.hintsOnly = this.hasHints && !this.hasRedactions; this.hintsOnly = this.hasHints && !this.hasRedactions;
this.hasNone = !this.hasRedactions && !this.hasHints && !this.hasSuggestions; this.hasNone = !this.hasRedactions && !this.hasHints && !this.hasSuggestions;
this.isPending = this.processingStatus === ProcessingFileStatuses.UNPROCESSED;
this.isProcessing = isProcessingStatuses.includes(this.processingStatus); this.isProcessing = isProcessingStatuses.includes(this.processingStatus);
this.isInitialProcessing = this.isProcessing && this.numberOfAnalyses === 0;
this.isApproved = this.workflowStatus === WorkflowFileStatuses.APPROVED; this.isApproved = this.workflowStatus === WorkflowFileStatuses.APPROVED;
this.isNew = this.workflowStatus === WorkflowFileStatuses.NEW; this.isNew = this.workflowStatus === WorkflowFileStatuses.NEW;
this.isUnderReview = this.workflowStatus === WorkflowFileStatuses.UNDER_REVIEW; this.isUnderReview = this.workflowStatus === WorkflowFileStatuses.UNDER_REVIEW;
this.isUnderApproval = this.workflowStatus === WorkflowFileStatuses.UNDER_APPROVAL; this.isUnderApproval = this.workflowStatus === WorkflowFileStatuses.UNDER_APPROVAL;
this.canBeApproved = !this.analysisRequired && !this.hasSuggestions && !this.isProcessing && !this.isError; this.canBeApproved = !this.analysisRequired && !this.hasSuggestions && !this.isProcessing && !this.isError;
this.canBeOpened = !this.isError && !this.isPending && this.numberOfAnalyses > 0; this.canBeOpened = !this.isError && !this.isUnprocessed && this.numberOfAnalyses > 0;
this.canBeOCRed = !this.excluded && !this.lastOCRTime && (this.isNew || this.isUnderReview || this.isUnderApproval); this.canBeOCRed = !this.excluded && !this.lastOCRTime && (this.isNew || this.isUnderReview || this.isUnderApproval);
if (!this.fileAttributes || !this.fileAttributes.attributeIdToValue) { if (!this.fileAttributes || !this.fileAttributes.attributeIdToValue) {

View File

@ -11,16 +11,18 @@ export const WorkflowFileStatuses = {
export type WorkflowFileStatus = keyof typeof WorkflowFileStatuses; export type WorkflowFileStatus = keyof typeof WorkflowFileStatuses;
export const ProcessingFileStatuses = { export const ProcessingFileStatuses = {
ANALYSE: 'ANALYSE',
DELETED: 'DELETED', DELETED: 'DELETED',
ERROR: 'ERROR', ERROR: 'ERROR',
FULLREPROCESS: 'FULLREPROCESS', FULLREPROCESS: 'FULLREPROCESS',
IMAGE_ANALYZING: 'IMAGE_ANALYZING', IMAGE_ANALYZING: 'IMAGE_ANALYZING',
SURROUNDING_TEXT_PROCESSING: 'SURROUNDING_TEXT_PROCESSING',
INDEXING: 'INDEXING', INDEXING: 'INDEXING',
NER_ANALYZING: 'NER_ANALYZING',
OCR_PROCESSING: 'OCR_PROCESSING', OCR_PROCESSING: 'OCR_PROCESSING',
PROCESSED: 'PROCESSED', PROCESSED: 'PROCESSED',
PROCESSING: 'PROCESSING', PROCESSING: 'PROCESSING',
REPROCESS: 'REPROCESS', REPROCESS: 'REPROCESS',
SURROUNDING_TEXT_PROCESSING: 'SURROUNDING_TEXT_PROCESSING',
UNPROCESSED: 'UNPROCESSED', UNPROCESSED: 'UNPROCESSED',
} as const; } as const;
@ -32,8 +34,10 @@ export const isProcessingStatuses: List<ProcessingFileStatus> = [
ProcessingFileStatuses.SURROUNDING_TEXT_PROCESSING, ProcessingFileStatuses.SURROUNDING_TEXT_PROCESSING,
ProcessingFileStatuses.OCR_PROCESSING, ProcessingFileStatuses.OCR_PROCESSING,
ProcessingFileStatuses.IMAGE_ANALYZING, ProcessingFileStatuses.IMAGE_ANALYZING,
ProcessingFileStatuses.NER_ANALYZING,
ProcessingFileStatuses.INDEXING, ProcessingFileStatuses.INDEXING,
ProcessingFileStatuses.PROCESSING, ProcessingFileStatuses.PROCESSING,
ProcessingFileStatuses.ANALYSE,
] as const; ] as const;
export interface StatusBarConfig { export interface StatusBarConfig {