From 9e562b189a016aafb76c18f8820565cf39bbbfd7 Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Wed, 24 Nov 2021 22:36:02 +0200 Subject: [PATCH] add exclude pages service --- .../file-workload.component.html | 63 +++++++++-------- .../file-workload/file-workload.component.ts | 5 +- .../page-exclusion.component.ts | 9 +-- .../file-preview-screen.component.html | 7 +- .../file-preview-screen.component.ts | 69 +++++++++++-------- .../services/excluded-pages.service.ts | 25 +++++++ .../file-actions/file-actions.component.html | 6 +- .../file-actions/file-actions.component.ts | 6 +- 8 files changed, 114 insertions(+), 76 deletions(-) create mode 100644 apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/excluded-pages.service.ts 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 6fdbcb1ad..16338b043 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 @@ -1,25 +1,11 @@ -
-
-
- -
-
- -
+
+ +
+
+
+ +
+
+
+
@@ -62,6 +68,7 @@ tooltipPosition="above" >
+
+
+
- +
{{ 'file-preview.tabs.annotations.page-is' | translate }} . +
+ - +
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 23ca8210f..240b8ab0d 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 @@ -20,6 +20,7 @@ import { WebViewerInstance } from '@pdftron/webviewer'; import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { File, IViewedPage } from '@red/domain'; +import { ExcludedPagesService } from '../../screens/file-preview-screen/services/excluded-pages.service'; const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape']; const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown']; @@ -42,7 +43,6 @@ export class FileWorkloadComponent { @Input() viewedPages: IViewedPage[]; @Input() @Required() file!: File; @Input() hideSkipped: boolean; - @Input() showExcludedPages: boolean; @Input() annotationActionsTemplate: TemplateRef; @Input() viewer: WebViewerInstance; @Output() readonly shouldDeselectAnnotationsOnPageChangeChange = new EventEmitter(); @@ -53,16 +53,15 @@ export class FileWorkloadComponent { @Output() readonly selectPage = new EventEmitter(); @Output() readonly toggleSkipped = new EventEmitter(); @Output() readonly annotationsChanged = new EventEmitter(); - @Output() readonly excludePages = new EventEmitter(); displayedPages: number[] = []; pagesPanelActive = true; readonly displayedAnnotations$: Observable>; - @Output() @Required() readonly toggleViewExcludedPages = new EventEmitter(); private _annotations$ = new BehaviorSubject([]); @ViewChild('annotationsElement') private readonly _annotationsElement: ElementRef; @ViewChild('quickNavigation') private readonly _quickNavigationElement: ElementRef; constructor( + readonly excludedPageService: ExcludedPagesService, private readonly _permissionsService: PermissionsService, private readonly _changeDetectorRef: ChangeDetectorRef, private readonly _filterService: FilterService, diff --git a/apps/red-ui/src/app/modules/dossier/components/page-exclusion/page-exclusion.component.ts b/apps/red-ui/src/app/modules/dossier/components/page-exclusion/page-exclusion.component.ts index 81df44ccb..a766a2ddb 100644 --- a/apps/red-ui/src/app/modules/dossier/components/page-exclusion/page-exclusion.component.ts +++ b/apps/red-ui/src/app/modules/dossier/components/page-exclusion/page-exclusion.component.ts @@ -1,9 +1,10 @@ -import { Component, EventEmitter, Input, OnChanges, Output, ViewChild } from '@angular/core'; +import { Component, Input, OnChanges, ViewChild } from '@angular/core'; import { PermissionsService } from '@services/permissions.service'; import { InputWithActionComponent, LoadingService, Toaster } from '@iqser/common-ui'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { File, IPageRange } from '@red/domain'; import { ReanalysisService } from '@services/reanalysis.service'; +import { ExcludedPagesService } from '../../screens/file-preview-screen/services/excluded-pages.service'; @Component({ selector: 'redaction-page-exclusion', @@ -12,13 +13,13 @@ import { ReanalysisService } from '@services/reanalysis.service'; }) export class PageExclusionComponent implements OnChanges { @Input() file: File; - @Output() readonly excludePages = new EventEmitter(); excludedPagesRanges: IPageRange[] = []; @ViewChild(InputWithActionComponent) private readonly _inputComponent: InputWithActionComponent; constructor( readonly permissionsService: PermissionsService, + readonly excludedPagesService: ExcludedPagesService, private readonly _reanalysisService: ReanalysisService, private readonly _toaster: Toaster, private readonly _loadingService: LoadingService, @@ -66,7 +67,7 @@ export class PageExclusionComponent implements OnChanges { ) .toPromise(); this._inputComponent.reset(); - this.excludePages.emit(); + this.excludedPagesService.toggle(); } catch (e) { this._toaster.error(_('file-preview.tabs.exclude-pages.error')); this._loadingService.stop(); @@ -85,6 +86,6 @@ export class PageExclusionComponent implements OnChanges { ) .toPromise(); this._inputComponent.reset(); - this.excludePages.emit(); + this.excludedPagesService.toggle(); } } 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 71f38b8eb..adf78b835 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 @@ -94,9 +94,7 @@ #fileActions (ocredFile)="ocredFile()" (toggleViewDocumentInfo)="toggleViewDocumentInfo()" - (toggleViewExcludedPages)="toggleViewExcludedPages()" [activeDocumentInfo]="viewDocumentInfo" - [activeExcludePages]="showExcludedPages" [file]="file" type="file-preview" > @@ -157,7 +155,7 @@
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 e34b01ed0..a59007e0b 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 @@ -51,9 +51,10 @@ import { FileActionsComponent } from '../../shared/components/file-actions/file- import { FilesService } from '@services/entity-services/files.service'; import { DossiersService } from '@services/entity-services/dossiers.service'; import { FileManagementService } from '@services/entity-services/file-management.service'; -import { filter, switchMapTo, tap } from 'rxjs/operators'; +import { filter, switchMap, switchMapTo, tap } from 'rxjs/operators'; import { FilesMapService } from '@services/entity-services/files-map.service'; import { WatermarkService } from '@shared/services/watermark.service'; +import { ExcludedPagesService } from './services/excluded-pages.service'; import Annotation = Core.Annotations.Annotation; import PDFNet = Core.PDFNet; @@ -62,7 +63,7 @@ const ALL_HOTKEY_ARRAY = ['Escape', 'F', 'f']; @Component({ templateUrl: './file-preview-screen.component.html', styleUrls: ['./file-preview-screen.component.scss'], - providers: [FilterService], + providers: [FilterService, ExcludedPagesService], changeDetection: ChangeDetectionStrategy.OnPush, }) export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnInit, OnDestroy, OnAttach, OnDetach { @@ -81,11 +82,11 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni hideSkipped = false; displayPDFViewer = false; viewDocumentInfo = false; - showExcludedPages = false; @ViewChild(PdfViewerComponent) readonly viewerComponent: PdfViewerComponent; @ViewChild('fileActions') fileActions: FileActionsComponent; readonly dossierId: string; readonly dossier$: Observable; + readonly showExcludedPages$: Observable; readonly file$: Observable; readonly fileId: string; private _instance: WebViewerInstance; @@ -121,12 +122,18 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni private readonly _translateService: TranslateService, private readonly _filesMapService: FilesMapService, private readonly _dossiersService: DossiersService, + readonly excludedPagesService: ExcludedPagesService, ) { super(); this.dossierId = _activatedRoute.snapshot.paramMap.get('dossierId'); this.dossier$ = _dossiersService.getEntityChanged$(this.dossierId); this.fileId = _activatedRoute.snapshot.paramMap.get('fileId'); - this.file$ = _filesMapService.watch$(this.dossierId, this.fileId); + this.file$ = _filesMapService.watch$(this.dossierId, this.fileId).pipe( + tap(async file => { + await this._reloadFile(file); + }), + ); + this.showExcludedPages$ = this._showExcludedPages$; document.documentElement.addEventListener('fullscreenchange', () => { if (!document.fullscreenElement) { @@ -167,6 +174,10 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni return !!this._workloadComponent?.multiSelectActive; } + private get _showExcludedPages$() { + return this.excludedPagesService.show$.pipe(tap(() => this._disableMultiSelectAndDocumentInfo())); + } + assignTooltip(file: File): string { return file.isUnderApproval ? this._translateService.instant('dossier-overview.assign-approver') @@ -263,7 +274,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni async ngOnInit(): Promise { this._loadingService.start(); await this.userPreferenceService.saveLastOpenedFileForDossier(this.dossierId, this.fileId); - await this._loadFileData(); this._updateCanPerformActions(); this._subscribeToFileUpdates(); @@ -437,7 +447,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni async viewerReady($event: WebViewerInstance) { this._instance = $event; await this._stampPDF(); - this._cleanupAndRedrawManualAnnotations$(); + await this._cleanupAndRedrawManualAnnotations$().toPromise(); this._updateCanPerformActions(); // Go to initial page from query params @@ -462,24 +472,10 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this._reloadFileOnReanalysis = true; } - async excludePages(): Promise { - this._loadingService.start(); - await this._loadFileData(true); - this._cleanupAndRedrawManualAnnotations$(); - await this._stampPDF(); - this._loadingService.stop(); - } - - toggleViewExcludedPages(): void { - this.showExcludedPages = !this.showExcludedPages; - this._workloadComponent.multiSelectActive = false; - this.viewDocumentInfo = false; - } - toggleViewDocumentInfo(): void { this.viewDocumentInfo = !this.viewDocumentInfo; this._workloadComponent.multiSelectActive = false; - this.showExcludedPages = false; + this.excludedPagesService.hide(); } async assignToMe(file: File) { @@ -534,6 +530,19 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni return false; } + private async _reloadFile(file: File): Promise { + this._loadingService.start(); + await this._loadFileData(file, true); + await this._cleanupAndRedrawManualAnnotations$().toPromise(); + await this._stampPDF(); + this._loadingService.stop(); + } + + private _disableMultiSelectAndDocumentInfo(): void { + this._workloadComponent.multiSelectActive = false; + this.viewDocumentInfo = false; + } + private _setHiddenPropertyToNewAnnotations(newAnnotations: AnnotationWrapper[], oldAnnotations: AnnotationWrapper[]) { newAnnotations.map(newAnnotation => { const oldAnnotation = oldAnnotations.find(a => a.annotationId === newAnnotation.annotationId); @@ -544,6 +553,9 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni } private async _stampPDF() { + if (!this._instance) { + return; + } const pdfNet = this._instance.Core.PDFNet; const document = await this._instance.Core.documentViewer.getDocument().getPDFDoc(); const file = this._filesMapService.get(this.dossierId, this.fileId); @@ -603,11 +615,11 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni }); this.addSubscription = this._filesMapService.fileReanalysed$ .pipe(filter(file => file.fileId === this.fileId)) - .subscribe(async () => { - await this._loadFileData(!this._reloadFileOnReanalysis); + .subscribe(async file => { + await this._loadFileData(file, !this._reloadFileOnReanalysis); this._reloadFileOnReanalysis = false; this._loadingService.stop(); - this._cleanupAndRedrawManualAnnotations$(); + await this._cleanupAndRedrawManualAnnotations$().toPromise(); }); } @@ -619,12 +631,11 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni !this.viewerComponent?.utils.isCompareMode; } - private async _loadFileData(performUpdate = false): Promise { - const file = this._filesMapService.get(this.dossierId, this.fileId); + private async _loadFileData(file: File, performUpdate = false): Promise { const fileData = await this._fileDownloadService.loadDataFor(file).toPromise(); if (!file?.isPending && !file?.isError) { - if (performUpdate) { + if (performUpdate && !!this.fileData) { this.fileData.redactionLog = fileData.redactionLog; this.fileData.viewedPages = fileData.viewedPages; this.rebuildFilters(true); @@ -652,7 +663,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni private _cleanupAndRedrawManualAnnotations$() { return this._fileDownloadService.loadRedactionLogFor(this.dossierId, this.fileId).pipe( tap(redactionLog => (this.fileData.redactionLog = redactionLog)), - switchMapTo(this._redrawAnnotations()), + switchMap(() => this._redrawAnnotations()), ); } @@ -682,7 +693,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this.fileId, this.dossierId, this.hideSkipped, - this.viewerComponent.utils.isCompareMode, + !!this.viewerComponent?.utils?.isCompareMode, ); } diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/excluded-pages.service.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/excluded-pages.service.ts new file mode 100644 index 000000000..8285eeefc --- /dev/null +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/excluded-pages.service.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject, Observable } from 'rxjs'; +import { shareDistinctLast } from '@iqser/common-ui'; + +@Injectable() +export class ExcludedPagesService { + readonly show$: Observable; + private readonly _show$ = new BehaviorSubject(false); + + constructor() { + this.show$ = this._show$.asObservable().pipe(shareDistinctLast()); + } + + show() { + this._show$.next(true); + } + + hide() { + this._show$.next(false); + } + + toggle() { + this._show$.next(!this._show$.value); + } +} diff --git a/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.html b/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.html index 3b7168251..f477b0970 100644 --- a/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.html +++ b/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.html @@ -71,9 +71,9 @@ > (); @@ -65,12 +65,12 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, isFilePreview = false; tooltipPosition: IqserTooltipPosition; @Output() readonly toggleViewDocumentInfo = new EventEmitter(); - @Output() readonly toggleViewExcludedPages = new EventEmitter(); constructor( readonly permissionsService: PermissionsService, readonly appStateService: AppStateService, readonly dossiersService: DossiersService, + @Optional() readonly excludedPagesService: ExcludedPagesService, private readonly _dialogService: DossiersDialogService, private readonly _fileAssignService: FileAssignService, private readonly _loadingService: LoadingService,