From 86f6b4a3becb1e62d3bfcda909943ba4938a45f6 Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Tue, 16 Nov 2021 00:08:47 +0200 Subject: [PATCH] use observable file instead of fileData --- .../file-workload.component.html | 12 +-- .../file-workload/file-workload.component.ts | 33 ++++--- .../file-preview-screen.component.html | 23 ++--- .../file-preview-screen.component.ts | 92 ++++++++++--------- 4 files changed, 86 insertions(+), 74 deletions(-) diff --git a/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.html b/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.html index 41a6d5db2..580c995a8 100644 --- a/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.html +++ b/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.html @@ -26,8 +26,8 @@
-
-
+
+
@@ -87,15 +87,15 @@ *ngFor="let pageNumber of displayedPages" [activeSelection]="pageHasSelection(pageNumber)" [active]="pageNumber === activeViewerPage" - [file]="fileData?.file" + [file]="file" [number]="pageNumber" [showDottedIcon]="hasOnlyManualRedactionsAndNotExcluded(pageNumber)" - [viewedPages]="fileData?.viewedPages" + [viewedPages]="viewedPages" >
diff --git a/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.ts b/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.ts index d5c52e16f..e99fd1d58 100644 --- a/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.ts +++ b/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.ts @@ -1,14 +1,25 @@ -import { ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Input, Output, TemplateRef, ViewChild } from '@angular/core'; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + ElementRef, + EventEmitter, + HostListener, + Input, + Output, + TemplateRef, + ViewChild, +} from '@angular/core'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { AnnotationProcessingService } from '../../services/annotation-processing.service'; import { MatDialogRef, MatDialogState } from '@angular/material/dialog'; import scrollIntoView from 'scroll-into-view-if-needed'; import { CircleButtonTypes, Debounce, FilterService, IconButtonTypes, INestedFilter, IqserEventTarget } from '@iqser/common-ui'; -import { FileDataModel } from '@models/file/file-data.model'; import { PermissionsService } from '@services/permissions.service'; import { WebViewerInstance } from '@pdftron/webviewer'; import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; import { map } from 'rxjs/operators'; +import { File, IViewedPage } from '@red/domain'; const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape']; const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown']; @@ -17,6 +28,7 @@ const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown']; selector: 'redaction-file-workload', templateUrl: './file-workload.component.html', styleUrls: ['./file-workload.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class FileWorkloadComponent { readonly iconButtonTypes = IconButtonTypes; @@ -27,7 +39,8 @@ export class FileWorkloadComponent { @Input() activeViewerPage: number; @Input() shouldDeselectAnnotationsOnPageChange: boolean; @Input() dialogRef: MatDialogRef; - @Input() fileData: FileDataModel; + @Input() viewedPages: IViewedPage[]; + @Input() file: File; @Input() hideSkipped: boolean; @Input() excludePages: boolean; @Input() annotationActionsTemplate: TemplateRef; @@ -78,20 +91,16 @@ export class FileWorkloadComponent { } } - get isProcessing(): boolean { - return this.fileData?.file?.isProcessing; - } - get activeAnnotations(): AnnotationWrapper[] | undefined { return this.displayedAnnotations.get(this.activeViewerPage); } get isReadOnly(): boolean { - return !this._permissionsService.canPerformAnnotationActions(this.fileData?.file); + return !this._permissionsService.canPerformAnnotationActions(this.file); } get currentPageIsExcluded(): boolean { - return this.fileData?.file?.excludedPages?.includes(this.activeViewerPage); + return this.file?.excludedPages?.includes(this.activeViewerPage); } private get _firstSelectedAnnotation() { @@ -120,7 +129,7 @@ export class FileWorkloadComponent { hasOnlyManualRedactionsAndNotExcluded(pageNumber: number): boolean { const hasOnlyManualRedactions = this.displayedAnnotations.get(pageNumber).every(annotation => annotation.manual); - return hasOnlyManualRedactions && this.fileData.file.excludedPages.includes(pageNumber); + return hasOnlyManualRedactions && this.file.excludedPages.includes(pageNumber); } pageHasSelection(page: number) { @@ -171,7 +180,7 @@ export class FileWorkloadComponent { this._navigatePages($event); } - this._changeDetectorRef.detectChanges(); + this._changeDetectorRef.markForCheck(); } scrollAnnotations(): void { @@ -212,7 +221,7 @@ export class FileWorkloadComponent { } scrollQuickNavLast(): void { - this.selectPage.emit(this.fileData.file.numberOfPages); + this.selectPage.emit(this.file.numberOfPages); } pageSelectedByClick($event: number): void { 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 8fa70a529..b722b788c 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 @@ -19,9 +19,9 @@ {{ 'file-preview.delta' | translate }}
@@ -32,11 +32,11 @@
- +
{{ translations[file.workflowStatus] | translate }} - {{ 'by' | translate }}: + {{ 'by' | translate }}:
@@ -48,7 +48,7 @@ >
@@ -56,9 +56,9 @@ @@ -66,13 +66,13 @@
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 c1a8f8cf4..ab39b0e99 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 @@ -86,7 +86,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni readonly dossier$: Observable; readonly file$: Observable; readonly fileId: string; - file: File; private _instance: WebViewerInstance; private _lastPage: string; private _reloadFileOnReanalysis = false; @@ -126,7 +125,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this.dossierId = _activatedRoute.snapshot.paramMap.get('dossierId'); this.dossier$ = this._dossiersService.getEntityChanged$(this.dossierId); this.fileId = _activatedRoute.snapshot.paramMap.get('fileId'); - this.file = _filesMapService.get(this.dossierId, this.fileId); this.file$ = _filesMapService.watch$(this.dossierId, this.fileId); document.documentElement.addEventListener('fullscreenchange', () => { if (!document.fullscreenElement) { @@ -135,12 +133,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni }); } - get assignTooltip(): string { - return this.file.isUnderApproval - ? this._translateService.instant('dossier-overview.assign-approver') - : this.assignOrChangeReviewerTooltip; - } - get annotations(): AnnotationWrapper[] { return this.annotationData ? this.annotationData.visibleAnnotations : []; } @@ -161,10 +153,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni : (currentPage + 1) / 2; } - get canSwitchToRedactedView(): boolean { - return this.fileData && !this.fileData.file.analysisRequired && !this.fileData.file.excluded; - } - get canSwitchToDeltaView(): boolean { return this.fileData?.hasChangeLog; } @@ -177,18 +165,28 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni return !!this._workloadComponent?.multiSelectActive; } - get assignOrChangeReviewerTooltip(): string { - return this.file.currentReviewer + assignTooltip(file: File): string { + return file.isUnderApproval + ? this._translateService.instant('dossier-overview.assign-approver') + : this.assignOrChangeReviewerTooltip(file); + } + + canSwitchToRedactedView(file: File): boolean { + return this.fileData && !file.analysisRequired && !file.excluded; + } + + assignOrChangeReviewerTooltip(file: File): string { + return file.currentReviewer ? this._translateService.instant('file-preview.change-reviewer') : this._translateService.instant('file-preview.assign-reviewer'); } - get statusBarConfig(): [{ length: number; color: WorkflowFileStatus }] { - return [{ length: 1, color: this.file.workflowStatus }]; + statusBarConfig(file: File): [{ length: number; color: WorkflowFileStatus }] { + return [{ length: 1, color: file.workflowStatus }]; } - get isUnderReviewOrApproval(): boolean { - return this.file.isUnderReview || this.file.isUnderApproval; + isUnderReviewOrApproval(file: File): boolean { + return file.isUnderReview || file.isUnderApproval; } canAssign(file: File): boolean { @@ -200,13 +198,13 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni ); } - singleUsersSelectOptions(dossier: Dossier): List { - const unassignUser = this.permissionsService.canUnassignUser(this.file) ? [undefined] : []; - return this.file?.isUnderApproval ? [...dossier.approverIds, ...unassignUser] : [...dossier.memberIds, ...unassignUser]; + usersOptions(file: File, dossier: Dossier): List { + const unassignUser = this.permissionsService.canUnassignUser(file) ? [undefined] : []; + return file.isUnderApproval ? [...dossier.approverIds, ...unassignUser] : [...dossier.memberIds, ...unassignUser]; } - canAssignReviewer(dossier: Dossier): boolean { - return !this.file.currentReviewer && this.permissionsService.canAssignUser(this.file) && dossier.hasReviewers; + canAssignReviewer(file: File, dossier: Dossier): boolean { + return !file.currentReviewer && this.permissionsService.canAssignUser(file) && dossier.hasReviewers; } updateViewMode(): void { @@ -250,7 +248,8 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni } async ngOnAttach(previousRoute: ActivatedRouteSnapshot): Promise { - if (!this.file.canBeOpened) { + const file = this._filesMapService.get(this.dossierId, this.fileId); + if (!file.canBeOpened) { return this._router.navigate([this.dossiersService.find(this.dossierId)?.routerLink]); } @@ -264,7 +263,8 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this._updateCanPerformActions(); this._subscribeToFileUpdates(); - if (this.fileData?.file?.analysisRequired) { + const file = this._filesMapService.get(this.dossierId, this.fileId); + if (file?.analysisRequired) { this.fileActions.reanalyseFile(); } } @@ -358,7 +358,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni response.manualRedactionEntryWrapper.rectId, ); this._instance.Core.annotationManager.deleteAnnotation(annotation); - this.fileData.file = await this.appStateService.reloadFile(this.dossierId, this.fileId); + await this.appStateService.reloadFile(this.dossierId, this.fileId); const distinctPages = entryWrapper.manualRedactionEntry.positions .map(p => p.page) .filter((item, pos, self) => self.indexOf(item) === pos); @@ -497,18 +497,18 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni } } - async assignToMe() { - await this._fileActionService.assignToMe([this.fileData.file], async () => { + async assignToMe(file: File) { + await this._fileActionService.assignToMe([file], async () => { await this.appStateService.reloadFile(this.dossierId, this.fileId); this._updateCanPerformActions(); }); } - async assignReviewer(user: User | string) { + async assignReviewer(file: File, user: User | string) { const reviewerId = typeof user === 'string' ? user : user?.id; const reviewerName = this.userService.getNameForId(reviewerId); - const { dossierId, fileId, filename } = this.fileData.file; + const { dossierId, fileId, filename } = file; await this._filesService.setReviewerFor([fileId], dossierId, reviewerId).toPromise(); this._toaster.info(_('assignment.reviewer'), { params: { reviewerName, filename } }); @@ -529,11 +529,11 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this._scrollViews(); } - async downloadOriginalFile() { + async downloadOriginalFile(file: File) { const data = await this._fileManagementService - .downloadOriginalFile(this.fileData.file.dossierId, this.fileId, 'response', true, this.fileData.file.cacheIdentifier) + .downloadOriginalFile(this.dossierId, this.fileId, 'response', true, file.cacheIdentifier) .toPromise(); - download(data, this.fileData.file.filename); + download(data, file.filename); } toggleSkipped($event) { @@ -555,14 +555,15 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni }); } - private async _doStampExcludedPages(excludedPages: number[]) { + private async _doStampExcludedPages() { const pdfNet = this._instance.Core.PDFNet; const document = await this._instance.Core.documentViewer.getDocument().getPDFDoc(); - const allPages = [...Array(this.fileData.file.numberOfPages).keys()].map(page => page + 1); + const file = this._filesMapService.get(this.dossierId, this.fileId); + const allPages = [...Array(file.numberOfPages).keys()].map(page => page + 1); await clearStamps(document, pdfNet, allPages); - if (excludedPages && excludedPages.length > 0) { - this.viewerComponent.utils.excludedPages = excludedPages; + if (file.excludedPages && file.excludedPages.length > 0) { + this.viewerComponent.utils.excludedPages = file.excludedPages; await stampPDFPage( document, pdfNet, @@ -572,13 +573,13 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni 'DIAGONAL', 33, '#283241', - excludedPages, + file.excludedPages, ); } } private async _stampExcludedPages() { - await this._doStampExcludedPages(this.fileData.file.excludedPages); + await this._doStampExcludedPages(); this._instance.Core.documentViewer.refreshAll(); this._instance.Core.documentViewer.updateView([this.activeViewerPage], this.activeViewerPage); this._changeDetectorRef.markForCheck(); @@ -600,20 +601,21 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni } private _updateCanPerformActions() { + const file = this._filesMapService.get(this.dossierId, this.fileId); this.canPerformAnnotationActions = - this.permissionsService.canPerformAnnotationActions(this.file) && + this.permissionsService.canPerformAnnotationActions(file) && this.viewMode === 'STANDARD' && !this.viewerComponent?.utils.isCompareMode; } private async _loadFileData(performUpdate = false): Promise { - const fileData = await this._fileDownloadService.loadDataFor(this.file).toPromise(); + const file = this._filesMapService.get(this.dossierId, this.fileId); + const fileData = await this._fileDownloadService.loadDataFor(file).toPromise(); - if (!fileData.file?.isPending && !fileData.file?.isError) { + if (!file?.isPending && !file?.isError) { if (performUpdate) { this.fileData.redactionLog = fileData.redactionLog; this.fileData.viewedPages = fileData.viewedPages; - this.fileData.file = fileData.file; this.rebuildFilters(true); } else { this.fileData = fileData; @@ -623,7 +625,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni return; } - if (fileData.file.isError) { + if (file.isError) { await this._router.navigate([this.dossiersService.find(this.dossierId).routerLink]); } } @@ -647,7 +649,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni const currentPageAnnotations = this.annotations.filter(a => a.pageNumber === page); const currentPageAnnotationIds = currentPageAnnotations.map(a => a.id); - this.fileData.file = await this.appStateService.reloadFile(this.dossierId, this.fileId); + await this.appStateService.reloadFile(this.dossierId, this.fileId); this.fileData.redactionLog = await this._fileDownloadService.loadRedactionLogFor(this.dossierId, this.fileId).toPromise(); this.rebuildFilters();