From 6947083c7cc022f9bcead23d5b5e4707656cfc2f Mon Sep 17 00:00:00 2001 From: Timo Bejan Date: Tue, 3 Nov 2020 23:02:36 +0200 Subject: [PATCH] improved file screen performance --- .../file-preview-screen.component.html | 1 + .../file-preview-screen.component.ts | 29 ++++++++++++------- .../app/screens/file/model/file-data.model.ts | 12 ++++++-- .../file/service/file-download.service.ts | 2 +- .../project-listing-screen.component.ts | 4 ++- .../project-overview-screen.component.ts | 13 ++++++--- .../red-ui/src/app/state/app-state.service.ts | 14 +++++++-- ...full-page-loading-indicator.component.html | 1 + ...full-page-loading-indicator.component.scss | 1 + .../full-page-loading-indicator.component.ts | 3 +- apps/red-ui/src/assets/i18n/en.json | 1 + 11 files changed, 60 insertions(+), 21 deletions(-) diff --git a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html index 7c2c5a804..6fd9e3d1d 100644 --- a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html +++ b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html @@ -226,6 +226,7 @@ diff --git a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts index 9f325bddc..4778f5077 100644 --- a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts @@ -29,7 +29,7 @@ import { FileActionService } from '../service/file-action.service'; import { AnnotationDrawService } from '../service/annotation-draw.service'; import { AnnotationProcessingService } from '../service/annotation-processing.service'; import { FilterModel } from '../../../common/filter/model/filter.model'; -import { MatMenuTrigger } from '@angular/material/menu'; +import { tap } from 'rxjs/operators'; const KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown']; @@ -84,6 +84,7 @@ export class FilePreviewScreenComponent implements OnInit { get activeViewerPage() { return this.instance?.docViewer?.getCurrentPage(); } + private projectId: string; private _activeViewer: 'ANNOTATED' | 'REDACTED' = 'ANNOTATED'; private instance: WebViewerInstance; @@ -103,22 +104,28 @@ export class FilePreviewScreenComponent implements OnInit { public filters: FilterModel[]; private _activeMenuAnnotation: AnnotationWrapper; + loadingMessage: string; public ngOnInit(): void { - this._loadFileData(); - this.appStateService.fileStatusChanged.subscribe((fileStatus) => { + this._loadFileData().subscribe(() => {}); + this.appStateService.fileStatusChanged.subscribe((fileStatus: FileStatus) => { if (fileStatus.fileId === this.fileId) { - // no more automatic reloads - // this._reloadFiles(); + this._loadFileData().subscribe(() => { + this.viewReady = true; + this.loadingMessage = null; + this._cleanupAndRedrawManualAnnotations(); + }); } }); } private _loadFileData() { - this._fileDownloadService.loadActiveFileData().subscribe((fileDataModel) => { - this.fileData = fileDataModel; - this._rebuildFilters(); - }); + return this._fileDownloadService.loadActiveFileData().pipe( + tap((fileDataModel) => { + this.fileData = fileDataModel; + this._rebuildFilters(); + }) + ); } private _rebuildFilters() { @@ -150,6 +157,8 @@ export class FilePreviewScreenComponent implements OnInit { public reanalyseFile($event: MouseEvent) { $event.stopPropagation(); + this.viewReady = false; + this.loadingMessage = 'file-preview.reanalyse-file'; this._reanalysisControllerService .reanalyzeFile(this.appStateService.activeProject.project.projectId, this.fileId) .subscribe(async () => { @@ -433,7 +442,7 @@ export class FilePreviewScreenComponent implements OnInit { viewerReady($event: WebViewerInstance) { this.instance = $event; this.viewReady = true; - this._annotationDrawService.drawAnnotations(this.instance, this.fileData.entriesToAdd); + this._cleanupAndRedrawManualAnnotations(); } filtersChanged(filters: FilterModel[]) { diff --git a/apps/red-ui/src/app/screens/file/model/file-data.model.ts b/apps/red-ui/src/app/screens/file/model/file-data.model.ts index f3e623d1c..f055d3aaf 100644 --- a/apps/red-ui/src/app/screens/file/model/file-data.model.ts +++ b/apps/red-ui/src/app/screens/file/model/file-data.model.ts @@ -1,7 +1,13 @@ -import { ManualRedactionEntry, ManualRedactions, RedactionLog } from '@redaction/red-ui-http'; +import { + FileStatus, + ManualRedactionEntry, + ManualRedactions, + RedactionLog +} from '@redaction/red-ui-http'; export class FileDataModel { constructor( + public fileStatus: FileStatus, public annotatedFileData: Blob, public redactedFileData: Blob, public redactionLog: RedactionLog, @@ -12,7 +18,9 @@ export class FileDataModel { return this.manualRedactions.entriesToAdd.filter( (e) => e.status !== 'DECLINED' && - !this.redactionLog.redactionLogEntry.find((r) => r.id === e.id) + !this.redactionLog.redactionLogEntry.find((r) => r.id === e.id) && + new Date(e.processedDate).getTime() > + new Date(this.fileStatus.lastUpdated).getTime() ); } } diff --git a/apps/red-ui/src/app/screens/file/service/file-download.service.ts b/apps/red-ui/src/app/screens/file/service/file-download.service.ts index 46c2e0898..9d27048e6 100644 --- a/apps/red-ui/src/app/screens/file/service/file-download.service.ts +++ b/apps/red-ui/src/app/screens/file/service/file-download.service.ts @@ -40,7 +40,7 @@ export class FileDownloadService { ); return forkJoin([annotatedObs, redactedObs, reactionLogObs, manualRedactionsObs]).pipe( - map((data) => new FileDataModel(...data)) + map((data) => new FileDataModel(this._appStateService.activeFile, ...data)) ); } diff --git a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.ts b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.ts index 3d6863f0b..7771d3457 100644 --- a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.ts +++ b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core'; import { Project } from '@redaction/red-ui-http'; import { AppStateService, ProjectWrapper } from '../../state/app-state.service'; import { UserService } from '../../user/user.service'; @@ -35,6 +35,7 @@ export class ProjectListingScreenComponent implements OnInit { constructor( public readonly appStateService: AppStateService, public readonly userService: UserService, + private readonly _changeDetectorRef: ChangeDetectorRef, private readonly _dialogService: DialogService ) {} @@ -239,6 +240,7 @@ export class ProjectListingScreenComponent implements OnInit { } this.displayedProjects = filteredProjects; + this._changeDetectorRef.detectChanges(); } private _checkFilter(project: ProjectWrapper, filters: FilterModel[], validate: Function) { diff --git a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts index 62831d654..ea5554fb3 100644 --- a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts +++ b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { FileStatus, @@ -57,6 +57,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { private readonly _uploadStatusOverlayService: UploadStatusOverlayService, private readonly _reanalysisControllerService: ReanalysisControllerService, private readonly _router: Router, + private readonly _changeDetectorRef: ChangeDetectorRef, private readonly _translateService: TranslateService, private readonly _fileDropOverlayService: FileDropOverlayService ) { @@ -147,7 +148,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { } public reloadProjects() { - this.appStateService.loadAllProjects().then(() => { + this.appStateService.getFiles().then(() => { this._calculateData(); }); } @@ -240,8 +241,11 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { } public canOpenFile(fileStatus: FileStatus): boolean { - // TODO check correct condition for this - return !this.isError(fileStatus) && !this.isProcessing(fileStatus); + return ( + !this.isError(fileStatus) && + !this.isProcessing(fileStatus) && + this.appStateService.isReviewerOrOwner(fileStatus) + ); } public sortingOptionChanged(option: SortingOption) { @@ -326,6 +330,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { } this.displayedFiles = filteredFiles; + this._changeDetectorRef.detectChanges(); } private _checkFilter(file: FileStatus, filters: FilterModel[], validate: Function) { diff --git a/apps/red-ui/src/app/state/app-state.service.ts b/apps/red-ui/src/app/state/app-state.service.ts index e3762d1b4..ed04f000a 100644 --- a/apps/red-ui/src/app/state/app-state.service.ts +++ b/apps/red-ui/src/app/state/app-state.service.ts @@ -221,6 +221,9 @@ export class AppStateService { } async getFiles(project?: ProjectWrapper) { + if (!project) { + project = this.activeProject; + } const files = await this._statusControllerService .getProjectStatus(project.project.projectId) .toPromise(); @@ -231,8 +234,8 @@ export class AppStateService { for (const oldFile of oldFiles) { if (oldFile.fileId === file.fileId) { // emit when analysis count changed - if (oldFile.numberOfAnalyses !== file.numberOfAnalyses) { - this.fileStatusChanged.emit(oldFile); + if (oldFile.lastUpdated !== file.lastUpdated) { + this.fileStatusChanged.emit(file); } found = true; break; @@ -473,4 +476,11 @@ export class AppStateService { this._appState.dictionaryVersion = result.dictionaryVersion; this._appState.ruleVersion = result.rulesVersion; } + + isReviewerOrOwner(fileStatus: FileStatus) { + return ( + fileStatus.currentReviewer === this._userService.userId || + this.isActiveProjectOwnerAndManager + ); + } } diff --git a/apps/red-ui/src/app/utils/full-page-loading-indicator/full-page-loading-indicator.component.html b/apps/red-ui/src/app/utils/full-page-loading-indicator/full-page-loading-indicator.component.html index f928bb8ba..1d0a97d28 100644 --- a/apps/red-ui/src/app/utils/full-page-loading-indicator/full-page-loading-indicator.component.html +++ b/apps/red-ui/src/app/utils/full-page-loading-indicator/full-page-loading-indicator.component.html @@ -1,4 +1,5 @@
+

{{ message | translate }} {{ message }}

diff --git a/apps/red-ui/src/app/utils/full-page-loading-indicator/full-page-loading-indicator.component.scss b/apps/red-ui/src/app/utils/full-page-loading-indicator/full-page-loading-indicator.component.scss index 3b2159b87..41151fbea 100644 --- a/apps/red-ui/src/app/utils/full-page-loading-indicator/full-page-loading-indicator.component.scss +++ b/apps/red-ui/src/app/utils/full-page-loading-indicator/full-page-loading-indicator.component.scss @@ -19,5 +19,6 @@ z-index: 1000; justify-content: center; align-items: center; + flex-direction: column; display: flex; } diff --git a/apps/red-ui/src/app/utils/full-page-loading-indicator/full-page-loading-indicator.component.ts b/apps/red-ui/src/app/utils/full-page-loading-indicator/full-page-loading-indicator.component.ts index 63b267fd1..381756d46 100644 --- a/apps/red-ui/src/app/utils/full-page-loading-indicator/full-page-loading-indicator.component.ts +++ b/apps/red-ui/src/app/utils/full-page-loading-indicator/full-page-loading-indicator.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, OnInit } from '@angular/core'; +import { Component, Input } from '@angular/core'; @Component({ selector: 'redaction-full-page-loading-indicator', @@ -7,4 +7,5 @@ import { Component, Input, OnInit } from '@angular/core'; }) export class FullPageLoadingIndicatorComponent { @Input() displayed = false; + @Input() message: string; } diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index 81d38da0c..613efa3e7 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -462,6 +462,7 @@ } }, "file-preview": { + "reanalyse-file": "File reanalysis in progress... ", "view-toggle": { "label": "Redacted View" },