diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details/dossier-details.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details/dossier-details.component.ts index 01cf7c101..744641109 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details/dossier-details.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details/dossier-details.component.ts @@ -4,7 +4,7 @@ import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/si import { TranslateChartService } from '@services/translate-chart.service'; import { UserService } from '@services/user.service'; import { FilterService, shareLast, Toaster } from '@iqser/common-ui'; -import { fileStatusTranslations } from '../../../../translations/file-status-translations'; +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'; import { DossiersService } from '@services/entity-services/dossiers.service'; @@ -61,7 +61,7 @@ export class DossierDetailsComponent { const documentsChartData: DoughnutChartConfig[] = Object.keys(stats.fileCountPerWorkflowStatus).map(status => ({ value: stats.fileCountPerWorkflowStatus[status], color: status, - label: fileStatusTranslations[status], + label: workflowFileStatusTranslations[status], key: status, })); documentsChartData.sort((a, b) => StatusSorter.byStatus(a.key, b.key)); diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/table-item.component.html b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/table-item.component.html index 8d5a5db03..a12cb71f3 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/table-item.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/table-item/table-item.component.html @@ -49,12 +49,11 @@
-
Promise): WorkflowConfig { + workflowConfig(reloadDossiers: () => Promise): WorkflowConfig { return { - columnIdentifierFn: entity => entity.status, + columnIdentifierFn: entity => entity.workflowStatus, itemVersionFn: (entity: File) => `${entity.lastUpdated}-${entity.numberOfAnalyses}`, columns: [ { - label: fileStatusTranslations[FileStatuses.UNASSIGNED], - key: FileStatuses.UNASSIGNED, + label: workflowFileStatusTranslations[WorkflowFileStatuses.UNASSIGNED], + key: WorkflowFileStatuses.UNASSIGNED, enterFn: this._unassignFn(reloadDossiers), enterPredicate: (file: File) => this._permissionsService.canUnassignUser(file), color: '#D3D5DA', }, { - label: fileStatusTranslations[FileStatuses.UNDER_REVIEW], + label: workflowFileStatusTranslations[WorkflowFileStatuses.UNDER_REVIEW], enterFn: this._underReviewFn(reloadDossiers), enterPredicate: (file: File) => this._permissionsService.canSetUnderReview(file) || this._permissionsService.canAssignToSelf(file) || this._permissionsService.canAssignUser(file), - key: FileStatuses.UNDER_REVIEW, + key: WorkflowFileStatuses.UNDER_REVIEW, color: '#FDBD00', }, { - label: fileStatusTranslations[FileStatuses.UNDER_APPROVAL], + label: workflowFileStatusTranslations[WorkflowFileStatuses.UNDER_APPROVAL], enterFn: this._underApprovalFn(reloadDossiers), enterPredicate: (file: File) => this._permissionsService.canSetUnderApproval(file) || this._permissionsService.canUndoApproval(file), - key: FileStatuses.UNDER_APPROVAL, + key: WorkflowFileStatuses.UNDER_APPROVAL, color: '#374C81', }, { - label: fileStatusTranslations[FileStatuses.APPROVED], + label: workflowFileStatusTranslations[WorkflowFileStatuses.APPROVED], enterFn: this._approveFn(reloadDossiers), enterPredicate: (file: File) => this._permissionsService.isReadyForApproval(file) && file.canBeApproved, - key: FileStatuses.APPROVED, + key: WorkflowFileStatuses.APPROVED, color: '#48C9F7', }, ], @@ -141,7 +141,7 @@ export class ConfigService { checkedRequiredFilters: () => NestedFilter[], checkedNotRequiredFilters: () => NestedFilter[], ) { - const allDistinctFileStatuses = new Set(); + const allDistinctWorkflowFileStatuses = new Set(); const allDistinctPeople = new Set(); const allDistinctAddedDates = new Set(); const allDistinctNeedsWork = new Set(); @@ -152,7 +152,7 @@ export class ConfigService { entities.forEach(file => { allDistinctPeople.add(file.currentReviewer); - allDistinctFileStatuses.add(file.status); + allDistinctWorkflowFileStatuses.add(file.workflowStatus); allDistinctAddedDates.add(moment(file.added).format('DD/MM/YYYY')); if (file.analysisRequired) { @@ -196,11 +196,11 @@ export class ConfigService { }); if (listingMode === ListingModes.table) { - const statusFilters = [...allDistinctFileStatuses].map( + const statusFilters = [...allDistinctWorkflowFileStatuses].map( status => new NestedFilter({ id: status, - label: this._translateService.instant(fileStatusTranslations[status]), + label: this._translateService.instant(workflowFileStatusTranslations[status]), }), ); @@ -209,7 +209,7 @@ export class ConfigService { label: this._translateService.instant('filters.status'), icon: 'red:status', filters: statusFilters.sort((a, b) => StatusSorter[a.id] - StatusSorter[b.id]), - checker: keyChecker('status'), + checker: keyChecker('workflowStatus'), }); } @@ -333,12 +333,12 @@ export class ConfigService { { id: 'unassigned', label: this._translateService.instant('dossier-overview.quick-filters.unassigned'), - checker: (file: File) => !file.currentReviewer, + checker: (file: File) => file.isUnassigned, }, { id: 'assigned-to-others', label: this._translateService.instant('dossier-overview.quick-filters.assigned-to-others'), - checker: (file: File) => !!file.currentReviewer && file.currentReviewer !== this._userService.currentUser.id, + checker: (file: File) => !file.isUnassigned && file.currentReviewer !== this._userService.currentUser.id, }, ].map(filter => new NestedFilter(filter)); } diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.ts index bc6d06d25..7ca4a474a 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.ts @@ -11,7 +11,7 @@ import { TemplateRef, ViewChild, } from '@angular/core'; -import { Dossier, DossierAttributeWithValue, File, FileStatus, IFileAttributeConfig } from '@red/domain'; +import { Dossier, DossierAttributeWithValue, File, IFileAttributeConfig, WorkflowFileStatus } from '@red/domain'; import { AppStateService } from '@state/app-state.service'; import { FileDropOverlayService } from '@upload-download/services/file-drop-overlay.service'; import { FileUploadModel } from '@upload-download/model/file-upload.model'; @@ -74,7 +74,7 @@ export class DossierOverviewScreenComponent extends ListingComponent imple analysisForced: boolean; displayedInFileListAttributes: IFileAttributeConfig[] = []; displayedAttributes: IFileAttributeConfig[] = []; - readonly workflowConfig: WorkflowConfig = this._configService.workflowConfig(() => this.reloadFiles()); + readonly workflowConfig: WorkflowConfig = this._configService.workflowConfig(() => this.reloadFiles()); readonly actionConfigs: readonly ActionConfig[]; readonly dossier$: Observable; readonly dossierId: string; @@ -265,7 +265,8 @@ export class DossierOverviewScreenComponent extends ListingComponent imple 'primaryAttribute', 'numberOfPages', 'assignee', - 'status', + 'workflowStatus', + 'processingStatus', 'lastUpdated', 'lastUploaded', 'lastProcessed', diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.ts index 5db91902b..d7f07bc65 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.ts @@ -4,7 +4,7 @@ import { FilterService, mapEach } from '@iqser/common-ui'; import { DossiersService } from '@services/entity-services/dossiers.service'; import { combineLatest, Observable } from 'rxjs'; import { Dossier, DossierStats, DossierStatuses, FileCountPerWorkflowStatus, StatusSorter } from '@red/domain'; -import { fileStatusTranslations } from '../../../../translations/file-status-translations'; +import { workflowFileStatusTranslations } from '../../../../translations/file-status-translations'; import { TranslateChartService } from '@services/translate-chart.service'; import { filter, map, switchMap } from 'rxjs/operators'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; @@ -60,7 +60,7 @@ export class DossiersListingDetailsComponent { ({ value: chartData[status], color: status, - label: fileStatusTranslations[status], + label: workflowFileStatusTranslations[status], key: status, } as DoughnutChartConfig), ); diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/config.service.ts b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/config.service.ts index 388bd6dce..b1e0d35e2 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/config.service.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/config.service.ts @@ -5,7 +5,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { TranslateService } from '@ngx-translate/core'; import { UserPreferenceService } from '@services/user-preference.service'; import { UserService } from '@services/user.service'; -import { fileStatusTranslations } from '../../translations/file-status-translations'; +import { workflowFileStatusTranslations } from '../../translations/file-status-translations'; import { dossierMemberChecker, dossierTemplateChecker, RedactionFilterSorter } from '@utils/index'; import { workloadTranslations } from '../../translations/workload-translations'; import { AppStateService } from '@state/app-state.service'; @@ -113,7 +113,7 @@ export class ConfigService { status => new NestedFilter({ id: status, - label: this._translateService.instant(fileStatusTranslations[status]), + label: this._translateService.instant(workflowFileStatusTranslations[status]), }), ); diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.html b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.html index f8685dc99..8fa70a529 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.html @@ -35,7 +35,7 @@
- {{ translations[file.status] | translate }} + {{ translations[file.workflowStatus] | translate }} {{ 'by' | translate }}:
diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts index ddb70ffcd..c1a8f8cf4 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts @@ -33,7 +33,7 @@ import { AnnotationData, FileDataModel } from '@models/file/file-data.model'; import { FileActionService } from '../../shared/services/file-action.service'; import { AnnotationDrawService } from '../../services/annotation-draw.service'; import { AnnotationProcessingService } from '../../services/annotation-processing.service'; -import { Dossier, File, FileStatus, User, ViewMode } from '@red/domain'; +import { Dossier, File, User, ViewMode, WorkflowFileStatus } from '@red/domain'; import { PermissionsService } from '@services/permissions.service'; import { Observable, timer } from 'rxjs'; import { UserPreferenceService } from '@services/user-preference.service'; @@ -44,7 +44,7 @@ import { FileWorkloadComponent } from '../../components/file-workload/file-workl import { DossiersDialogService } from '../../services/dossiers-dialog.service'; import { clearStamps, stampPDFPage } from '@utils/page-stamper'; import { TranslateService } from '@ngx-translate/core'; -import { fileStatusTranslations } from '../../translations/file-status-translations'; +import { workflowFileStatusTranslations } from '../../translations/file-status-translations'; import { handleFilterDelta } from '@utils/filter-utils'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { FileActionsComponent } from '../../shared/components/file-actions/file-actions.component'; @@ -65,7 +65,7 @@ const ALL_HOTKEY_ARRAY = ['Escape', 'F', 'f']; }) export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnInit, OnDestroy, OnAttach, OnDetach { readonly circleButtonTypes = CircleButtonTypes; - readonly translations = fileStatusTranslations; + readonly translations = workflowFileStatusTranslations; dialogRef: MatDialogRef; viewMode: ViewMode = 'STANDARD'; @@ -183,12 +183,12 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni : this._translateService.instant('file-preview.assign-reviewer'); } - get statusBarConfig(): [{ length: number; color: FileStatus }] { - return [{ length: 1, color: this.file.status }]; + get statusBarConfig(): [{ length: number; color: WorkflowFileStatus }] { + return [{ length: 1, color: this.file.workflowStatus }]; } get isUnderReviewOrApproval(): boolean { - return this.file.status === 'UNDER_REVIEW' || this.file.status === 'UNDER_APPROVAL'; + return this.file.isUnderReview || this.file.isUnderApproval; } canAssign(file: File): boolean { diff --git a/apps/red-ui/src/app/modules/dossier/screens/search-screen/search-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/search-screen/search-screen.component.ts index 35daad415..ad23466f1 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/search-screen/search-screen.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/search-screen/search-screen.component.ts @@ -15,7 +15,7 @@ import { merge, Observable } from 'rxjs'; import { debounceTime, map, startWith, switchMap, tap } from 'rxjs/operators'; import { ActivatedRoute, Router } from '@angular/router'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; -import { fileStatusTranslations } from '../../translations/file-status-translations'; +import { workflowFileStatusTranslations } from '../../translations/file-status-translations'; import { TranslateService } from '@ngx-translate/core'; import { RouterHistoryService } from '@services/router-history.service'; import { DossiersService } from '@services/entity-services/dossiers.service'; @@ -37,7 +37,7 @@ function toSearchInput(query: string, dossierIds: List | string): ISearchInput { changeDetection: ChangeDetectionStrategy.OnPush, }) export class SearchScreenComponent extends ListingComponent implements OnDestroy { - readonly fileStatusTranslations = fileStatusTranslations; + readonly fileStatusTranslations = workflowFileStatusTranslations; readonly searchPositions = SearchPositions; readonly tableHeaderLabel = _('search-screen.table-header'); @@ -139,7 +139,7 @@ export class SearchScreenComponent extends ListingComponent imp dossierId, unmatched: unmatchedTerms || null, highlights, - status: file.status, + status: file.workflowStatus, numberOfPages: file.numberOfPages, dossierName: this._dossiersService.find(dossierId).dossierName, filename: file.filename, diff --git a/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.ts b/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.ts index dbb8581eb..dcfc25cbd 100644 --- a/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.ts +++ b/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { PermissionsService } from '@services/permissions.service'; -import { Dossier, File, FileStatus } from '@red/domain'; +import { Dossier, File, WorkflowFileStatus } from '@red/domain'; import { AppStateService } from '@state/app-state.service'; import { DossiersDialogService } from '../../../services/dossiers-dialog.service'; import { @@ -45,7 +45,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD @Output() readonly actionPerformed = new EventEmitter(); dossier$: Observable; - statusBarConfig?: List>; + statusBarConfig?: List>; tooltipPosition?: 'below' | 'above'; toggleTooltip?: string; assignTooltip?: string; @@ -234,7 +234,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD } setup() { - this.statusBarConfig = [{ color: this.file.status, length: 1 }]; + this.statusBarConfig = [{ color: this.file.workflowStatus, length: 1 }]; this.tooltipPosition = this.isFilePreview ? 'below' : 'above'; this.assignTooltip = this.file.isUnderApproval ? _('dossier-overview.assign-approver') : _('dossier-overview.assign-reviewer'); this.buttonType = this.isFilePreview ? CircleButtonTypes.default : CircleButtonTypes.dark; diff --git a/apps/red-ui/src/app/modules/dossier/translations/file-status-translations.ts b/apps/red-ui/src/app/modules/dossier/translations/file-status-translations.ts index 4d01b3ed2..d8cc442a4 100644 --- a/apps/red-ui/src/app/modules/dossier/translations/file-status-translations.ts +++ b/apps/red-ui/src/app/modules/dossier/translations/file-status-translations.ts @@ -1,18 +1,21 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; -import { FileStatus } from '@red/domain'; +import { ProcessingFileStatus, WorkflowFileStatus } from '@red/domain'; -export const fileStatusTranslations: { [key in FileStatus]: string } = { +export const workflowFileStatusTranslations: { [key in WorkflowFileStatus]: string } = { APPROVED: _('file-status.approved'), + UNASSIGNED: _('file-status.unassigned'), + UNDER_APPROVAL: _('file-status.under-approval'), + UNDER_REVIEW: _('file-status.under-review'), +}; + +export const processingFileStatusTranslations: { [key in ProcessingFileStatus]: string } = { + PROCESSED: _('file-status.processed'), DELETED: _('file-status.deleted'), ERROR: _('file-status.error'), - EXCLUDED: _('file-status.excluded'), FULLREPROCESS: _('file-status.full-reprocess'), INDEXING: _('file-status.indexing'), OCR_PROCESSING: _('file-status.ocr-processing'), PROCESSING: _('file-status.processing'), REPROCESS: _('file-status.reprocess'), - UNASSIGNED: _('file-status.unassigned'), - UNDER_APPROVAL: _('file-status.under-approval'), - UNDER_REVIEW: _('file-status.under-review'), UNPROCESSED: _('file-status.unprocessed'), }; diff --git a/apps/red-ui/src/app/services/permissions.service.ts b/apps/red-ui/src/app/services/permissions.service.ts index dbc12e1b8..7680a46cd 100644 --- a/apps/red-ui/src/app/services/permissions.service.ts +++ b/apps/red-ui/src/app/services/permissions.service.ts @@ -22,7 +22,7 @@ export class PermissionsService { } canToggleAnalysis(file: File, dossier: Dossier): boolean { - return this.isReviewerOrApprover(file, dossier) && ['UNASSIGNED', 'UNDER_REVIEW', 'UNDER_APPROVAL'].includes(file.status); + return this.isReviewerOrApprover(file, dossier) && (file.isUnassigned || file.isUnderReview || file.isUnderApproval); } canReanalyseFile(file: File, dossier: Dossier): boolean { @@ -102,8 +102,9 @@ export class PermissionsService { return dossier?.memberIds.includes(user.id); } + // TODO: Remove '?', after we make sure file is loaded before page canPerformAnnotationActions(file: File): boolean { - return ['UNDER_REVIEW', 'UNDER_APPROVAL'].includes(file?.status) && this.isFileReviewer(file); + return (file?.isUnderReview || file?.isUnderApproval) && this.isFileReviewer(file); } canUndoApproval(file: File): boolean { @@ -111,7 +112,7 @@ export class PermissionsService { } canMarkPagesAsViewed(file: File): boolean { - return ['UNDER_REVIEW', 'UNDER_APPROVAL'].includes(file?.status) && this.isFileReviewer(file); + return (file.isUnderReview || file.isUnderApproval) && this.isFileReviewer(file); } canDownloadFiles(file: File): boolean { @@ -137,7 +138,7 @@ export class PermissionsService { canExcludePages(file: File): boolean { const dossier = this._getDossier(file); - return ['UNDER_REVIEW', 'UNDER_APPROVAL'].includes(file.status) && (this.isFileReviewer(file) || this.isApprover(dossier)); + return (file.isUnderReview || file.isUnderApproval) && (this.isFileReviewer(file) || this.isApprover(dossier)); } canDeleteComment(comment: IComment, file: File) { diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index 068dd721a..303452bd9 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -698,8 +698,7 @@ "file-listing": { "file-entry": { "file-error": "Re-processing required", - "file-pending": "Pending...", - "file-processing": "Processing" + "file-pending": "Pending..." } }, "filters": { @@ -1081,10 +1080,10 @@ "approved": "Approved", "deleted": "Deleted", "error": "Re-processing required", - "excluded": "Excluded", "full-reprocess": "Processing", "indexing": "Processing", "ocr-processing": "OCR Processing", + "processed": "Processed", "processing": "Processing", "reprocess": "Processing", "unassigned": "Unassigned", diff --git a/libs/common-ui b/libs/common-ui index 8beb712c5..643df41d0 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 8beb712c5492dd77e81f46cb67752615f582ecf4 +Subproject commit 643df41d09d3a1d159adbb1f2cf3cefa26002bc8 diff --git a/libs/red-domain/src/lib/dossier-stats/types.ts b/libs/red-domain/src/lib/dossier-stats/types.ts index d87f9521d..54a188567 100644 --- a/libs/red-domain/src/lib/dossier-stats/types.ts +++ b/libs/red-domain/src/lib/dossier-stats/types.ts @@ -1,26 +1,4 @@ -export const WorkflowFileStatuses = { - APPROVED: 'APPROVED', - UNASSIGNED: 'UNASSIGNED', - UNDER_APPROVAL: 'UNDER_APPROVAL', - UNDER_REVIEW: 'UNDER_REVIEW', -} as const; - -export type WorkflowFileStatus = keyof typeof WorkflowFileStatuses; +import { ProcessingFileStatus, WorkflowFileStatus } from '../files'; export type FileCountPerWorkflowStatus = { [key in WorkflowFileStatus]?: number }; - -export const ProcessingFileStatuses = { - DELETED: 'DELETED', - ERROR: 'ERROR', - FULLREPROCESS: 'FULLREPROCESS', - INDEXING: 'INDEXING', - OCR_PROCESSING: 'OCR_PROCESSING', - PROCESSED: 'PROCESSED', - PROCESSING: 'PROCESSING', - REPROCESS: 'REPROCESS', - UNPROCESSED: 'UNPROCESSED', -} as const; - -export type ProcessingFileStatus = keyof typeof ProcessingFileStatuses; - export type FileCountPerProcessingStatus = { [key in ProcessingFileStatus]?: number }; diff --git a/libs/red-domain/src/lib/files/file.model.ts b/libs/red-domain/src/lib/files/file.model.ts index 42c2d89ec..c84931493 100644 --- a/libs/red-domain/src/lib/files/file.model.ts +++ b/libs/red-domain/src/lib/files/file.model.ts @@ -1,15 +1,15 @@ import { Entity, List } from '@iqser/common-ui'; import { StatusSorter } from '../shared'; -import { FileStatus, FileStatuses } from './types'; +import { ProcessingFileStatus, ProcessingFileStatuses, WorkflowFileStatus, WorkflowFileStatuses } from './types'; import { IFile } from './file'; import { FileAttributes, IFileAttributesConfig } from '../file-attributes'; -const processingStatuses: List = [ - FileStatuses.REPROCESS, - FileStatuses.FULLREPROCESS, - FileStatuses.OCR_PROCESSING, - FileStatuses.INDEXING, - FileStatuses.PROCESSING, +const processingStatuses: List = [ + ProcessingFileStatuses.REPROCESS, + ProcessingFileStatuses.FULLREPROCESS, + ProcessingFileStatuses.OCR_PROCESSING, + ProcessingFileStatuses.INDEXING, + ProcessingFileStatuses.PROCESSING, ] as const; export class File extends Entity implements IFile { @@ -40,10 +40,11 @@ export class File extends Entity implements IFile { readonly numberOfAnalyses: number; readonly numberOfPages?: number; readonly rulesVersion?: number; - readonly status: FileStatus; readonly uploader?: string; readonly excludedPages?: number[]; readonly hasSuggestions: boolean; + readonly processingStatus: ProcessingFileStatus; + readonly workflowStatus: WorkflowFileStatus; readonly primaryAttribute?: string; lastOpened = false; @@ -90,30 +91,31 @@ export class File extends Entity implements IFile { this.lastUploaded = file.lastUploaded; this.legalBasisVersion = file.legalBasisVersion; this.numberOfAnalyses = file.numberOfAnalyses; - this.status = ['REPROCESS', 'FULLREPROCESS', 'INDEXING'].includes(file.status) ? FileStatuses.PROCESSING : file.status; - this.isError = this.status === FileStatuses.ERROR; + this.processingStatus = file.processingStatus; + this.workflowStatus = file.workflowStatus; + this.isError = this.processingStatus === ProcessingFileStatuses.ERROR; this.numberOfPages = this.isError ? 0 : file.numberOfPages ?? 0; this.rulesVersion = file.rulesVersion; this.uploader = file.uploader; this.excludedPages = file.excludedPages; this.hasSuggestions = !!file.hasSuggestions; - this.statusSort = StatusSorter[this.status]; + this.statusSort = StatusSorter[this.workflowStatus]; if (this.lastUpdated && this.lastOCRTime) { this.cacheIdentifier = btoa((this.lastUploaded ?? '') + this.lastOCRTime); } this.hintsOnly = this.hasHints && !this.hasRedactions; this.hasNone = !this.hasRedactions && !this.hasHints && !this.hasSuggestions; - this.isUnassigned = !this.currentReviewer; - this.isProcessing = processingStatuses.includes(this.status); - this.isApproved = this.status === FileStatuses.APPROVED; - this.isPending = this.status === FileStatuses.UNPROCESSED; - this.isUnderReview = this.status === FileStatuses.UNDER_REVIEW; - this.isUnderApproval = this.status === FileStatuses.UNDER_APPROVAL; + this.isPending = this.processingStatus === ProcessingFileStatuses.UNPROCESSED; + this.isProcessing = processingStatuses.includes(this.processingStatus); + this.isApproved = this.workflowStatus === WorkflowFileStatuses.APPROVED; + this.isUnassigned = this.workflowStatus === WorkflowFileStatuses.UNASSIGNED; + this.isUnderReview = this.workflowStatus === WorkflowFileStatuses.UNDER_REVIEW; + this.isUnderApproval = this.workflowStatus === WorkflowFileStatuses.UNDER_APPROVAL; this.canBeApproved = !this.analysisRequired && !this.hasSuggestions; this.canBeOpened = !this.isError && !this.isPending && this.numberOfAnalyses > 0; this.isWorkable = !this.isProcessing && this.canBeOpened; - this.canBeOCRed = !this.excluded && !this.lastOCRTime && ['UNASSIGNED', 'UNDER_REVIEW', 'UNDER_APPROVAL'].includes(this.status); + this.canBeOCRed = !this.excluded && !this.lastOCRTime && (this.isUnassigned || this.isUnderReview || this.isUnderApproval); if (fileAttributesConfig) { const primary = fileAttributesConfig.fileAttributeConfigs?.find(c => c.primaryAttribute); diff --git a/libs/red-domain/src/lib/files/file.ts b/libs/red-domain/src/lib/files/file.ts index f3ddd649b..73ea1584b 100644 --- a/libs/red-domain/src/lib/files/file.ts +++ b/libs/red-domain/src/lib/files/file.ts @@ -1,7 +1,7 @@ /** * Object containing information on a specific file. */ -import { FileStatus } from './types'; +import { ProcessingFileStatus, WorkflowFileStatus } from './types'; import { FileAttributes } from '../file-attributes'; export interface IFile { @@ -130,12 +130,12 @@ export interface IFile { * Shows if the file is soft deleted. */ readonly softDeleted?: string; - /** - * The status of the file with regard to its analysis an review processes. - */ - readonly status: FileStatus; /** * The ID of the user who uploaded the file. */ readonly uploader?: string; + + readonly processingStatus: ProcessingFileStatus; + + readonly workflowStatus: WorkflowFileStatus; } diff --git a/libs/red-domain/src/lib/files/types.ts b/libs/red-domain/src/lib/files/types.ts index 83f856bd4..cc5e23930 100644 --- a/libs/red-domain/src/lib/files/types.ts +++ b/libs/red-domain/src/lib/files/types.ts @@ -1,17 +1,22 @@ -export const FileStatuses = { +export const WorkflowFileStatuses = { APPROVED: 'APPROVED', - DELETED: 'DELETED', - ERROR: 'ERROR', - EXCLUDED: 'EXCLUDED', - FULLREPROCESS: 'FULLREPROCESS', - INDEXING: 'INDEXING', - OCR_PROCESSING: 'OCR_PROCESSING', - PROCESSING: 'PROCESSING', - REPROCESS: 'REPROCESS', UNASSIGNED: 'UNASSIGNED', UNDER_APPROVAL: 'UNDER_APPROVAL', UNDER_REVIEW: 'UNDER_REVIEW', +} as const; + +export type WorkflowFileStatus = keyof typeof WorkflowFileStatuses; + +export const ProcessingFileStatuses = { + DELETED: 'DELETED', + ERROR: 'ERROR', + FULLREPROCESS: 'FULLREPROCESS', + INDEXING: 'INDEXING', + OCR_PROCESSING: 'OCR_PROCESSING', + PROCESSED: 'PROCESSED', + PROCESSING: 'PROCESSING', + REPROCESS: 'REPROCESS', UNPROCESSED: 'UNPROCESSED', } as const; -export type FileStatus = keyof typeof FileStatuses; +export type ProcessingFileStatus = keyof typeof ProcessingFileStatuses; diff --git a/libs/red-domain/src/lib/shared/sorters/status-sorter.ts b/libs/red-domain/src/lib/shared/sorters/status-sorter.ts index fc6b88f52..8598dc56e 100644 --- a/libs/red-domain/src/lib/shared/sorters/status-sorter.ts +++ b/libs/red-domain/src/lib/shared/sorters/status-sorter.ts @@ -1,32 +1,22 @@ -import { FileStatus } from '../../files'; +import { WorkflowFileStatus } from '../../files'; -type StatusSorterItem = { key: FileStatus } | FileStatus | string; -type Sorter = Record & { +type StatusSorterItem = { key: WorkflowFileStatus } | WorkflowFileStatus | string; +type Sorter = Record & { byStatus: (a: T, b: T) => number; }; export const StatusSorter: Sorter = { - ERROR: 0, - DELETED: 0, - FULLREPROCESS: 0, - EXCLUDED: 0, - INDEXING: 0, - UNPROCESSED: 1, - REPROCESS: 5, - PROCESSING: 5, - OCR_PROCESSING: 7, - - UNASSIGNED: 10, - UNDER_REVIEW: 15, - UNDER_APPROVAL: 20, - APPROVED: 25, + UNASSIGNED: 1, + UNDER_REVIEW: 2, + UNDER_APPROVAL: 3, + APPROVED: 4, byStatus: (a: StatusSorterItem, b: StatusSorterItem): number => { if (typeof a !== typeof b) { throw TypeError('Used different types when calling StatusSorter.byStatus1'); } - const x = typeof a === 'string' ? (a as FileStatus) : a.key; - const y = typeof b === 'string' ? (b as FileStatus) : b.key; + const x = typeof a === 'string' ? (a as WorkflowFileStatus) : a.key; + const y = typeof b === 'string' ? (b as WorkflowFileStatus) : b.key; return StatusSorter[x] - StatusSorter[y]; }, };