improved file screen performance

This commit is contained in:
Timo Bejan 2020-11-03 23:02:36 +02:00
parent 31eacd1f31
commit 6947083c7c
11 changed files with 60 additions and 21 deletions

View File

@ -226,6 +226,7 @@
</section> </section>
<redaction-full-page-loading-indicator <redaction-full-page-loading-indicator
[message]="loadingMessage"
[displayed]="!viewReady" [displayed]="!viewReady"
></redaction-full-page-loading-indicator> ></redaction-full-page-loading-indicator>

View File

@ -29,7 +29,7 @@ import { FileActionService } from '../service/file-action.service';
import { AnnotationDrawService } from '../service/annotation-draw.service'; import { AnnotationDrawService } from '../service/annotation-draw.service';
import { AnnotationProcessingService } from '../service/annotation-processing.service'; import { AnnotationProcessingService } from '../service/annotation-processing.service';
import { FilterModel } from '../../../common/filter/model/filter.model'; 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']; const KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
@ -84,6 +84,7 @@ export class FilePreviewScreenComponent implements OnInit {
get activeViewerPage() { get activeViewerPage() {
return this.instance?.docViewer?.getCurrentPage(); return this.instance?.docViewer?.getCurrentPage();
} }
private projectId: string; private projectId: string;
private _activeViewer: 'ANNOTATED' | 'REDACTED' = 'ANNOTATED'; private _activeViewer: 'ANNOTATED' | 'REDACTED' = 'ANNOTATED';
private instance: WebViewerInstance; private instance: WebViewerInstance;
@ -103,22 +104,28 @@ export class FilePreviewScreenComponent implements OnInit {
public filters: FilterModel[]; public filters: FilterModel[];
private _activeMenuAnnotation: AnnotationWrapper; private _activeMenuAnnotation: AnnotationWrapper;
loadingMessage: string;
public ngOnInit(): void { public ngOnInit(): void {
this._loadFileData(); this._loadFileData().subscribe(() => {});
this.appStateService.fileStatusChanged.subscribe((fileStatus) => { this.appStateService.fileStatusChanged.subscribe((fileStatus: FileStatus) => {
if (fileStatus.fileId === this.fileId) { if (fileStatus.fileId === this.fileId) {
// no more automatic reloads this._loadFileData().subscribe(() => {
// this._reloadFiles(); this.viewReady = true;
this.loadingMessage = null;
this._cleanupAndRedrawManualAnnotations();
});
} }
}); });
} }
private _loadFileData() { private _loadFileData() {
this._fileDownloadService.loadActiveFileData().subscribe((fileDataModel) => { return this._fileDownloadService.loadActiveFileData().pipe(
this.fileData = fileDataModel; tap((fileDataModel) => {
this._rebuildFilters(); this.fileData = fileDataModel;
}); this._rebuildFilters();
})
);
} }
private _rebuildFilters() { private _rebuildFilters() {
@ -150,6 +157,8 @@ export class FilePreviewScreenComponent implements OnInit {
public reanalyseFile($event: MouseEvent) { public reanalyseFile($event: MouseEvent) {
$event.stopPropagation(); $event.stopPropagation();
this.viewReady = false;
this.loadingMessage = 'file-preview.reanalyse-file';
this._reanalysisControllerService this._reanalysisControllerService
.reanalyzeFile(this.appStateService.activeProject.project.projectId, this.fileId) .reanalyzeFile(this.appStateService.activeProject.project.projectId, this.fileId)
.subscribe(async () => { .subscribe(async () => {
@ -433,7 +442,7 @@ export class FilePreviewScreenComponent implements OnInit {
viewerReady($event: WebViewerInstance) { viewerReady($event: WebViewerInstance) {
this.instance = $event; this.instance = $event;
this.viewReady = true; this.viewReady = true;
this._annotationDrawService.drawAnnotations(this.instance, this.fileData.entriesToAdd); this._cleanupAndRedrawManualAnnotations();
} }
filtersChanged(filters: FilterModel[]) { filtersChanged(filters: FilterModel[]) {

View File

@ -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 { export class FileDataModel {
constructor( constructor(
public fileStatus: FileStatus,
public annotatedFileData: Blob, public annotatedFileData: Blob,
public redactedFileData: Blob, public redactedFileData: Blob,
public redactionLog: RedactionLog, public redactionLog: RedactionLog,
@ -12,7 +18,9 @@ export class FileDataModel {
return this.manualRedactions.entriesToAdd.filter( return this.manualRedactions.entriesToAdd.filter(
(e) => (e) =>
e.status !== 'DECLINED' && 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()
); );
} }
} }

View File

@ -40,7 +40,7 @@ export class FileDownloadService {
); );
return forkJoin([annotatedObs, redactedObs, reactionLogObs, manualRedactionsObs]).pipe( return forkJoin([annotatedObs, redactedObs, reactionLogObs, manualRedactionsObs]).pipe(
map((data) => new FileDataModel(...data)) map((data) => new FileDataModel(this._appStateService.activeFile, ...data))
); );
} }

View File

@ -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 { Project } from '@redaction/red-ui-http';
import { AppStateService, ProjectWrapper } from '../../state/app-state.service'; import { AppStateService, ProjectWrapper } from '../../state/app-state.service';
import { UserService } from '../../user/user.service'; import { UserService } from '../../user/user.service';
@ -35,6 +35,7 @@ export class ProjectListingScreenComponent implements OnInit {
constructor( constructor(
public readonly appStateService: AppStateService, public readonly appStateService: AppStateService,
public readonly userService: UserService, public readonly userService: UserService,
private readonly _changeDetectorRef: ChangeDetectorRef,
private readonly _dialogService: DialogService private readonly _dialogService: DialogService
) {} ) {}
@ -239,6 +240,7 @@ export class ProjectListingScreenComponent implements OnInit {
} }
this.displayedProjects = filteredProjects; this.displayedProjects = filteredProjects;
this._changeDetectorRef.detectChanges();
} }
private _checkFilter(project: ProjectWrapper, filters: FilterModel[], validate: Function) { private _checkFilter(project: ProjectWrapper, filters: FilterModel[], validate: Function) {

View File

@ -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 { ActivatedRoute, Router } from '@angular/router';
import { import {
FileStatus, FileStatus,
@ -57,6 +57,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
private readonly _uploadStatusOverlayService: UploadStatusOverlayService, private readonly _uploadStatusOverlayService: UploadStatusOverlayService,
private readonly _reanalysisControllerService: ReanalysisControllerService, private readonly _reanalysisControllerService: ReanalysisControllerService,
private readonly _router: Router, private readonly _router: Router,
private readonly _changeDetectorRef: ChangeDetectorRef,
private readonly _translateService: TranslateService, private readonly _translateService: TranslateService,
private readonly _fileDropOverlayService: FileDropOverlayService private readonly _fileDropOverlayService: FileDropOverlayService
) { ) {
@ -147,7 +148,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
} }
public reloadProjects() { public reloadProjects() {
this.appStateService.loadAllProjects().then(() => { this.appStateService.getFiles().then(() => {
this._calculateData(); this._calculateData();
}); });
} }
@ -240,8 +241,11 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
} }
public canOpenFile(fileStatus: FileStatus): boolean { public canOpenFile(fileStatus: FileStatus): boolean {
// TODO check correct condition for this return (
return !this.isError(fileStatus) && !this.isProcessing(fileStatus); !this.isError(fileStatus) &&
!this.isProcessing(fileStatus) &&
this.appStateService.isReviewerOrOwner(fileStatus)
);
} }
public sortingOptionChanged(option: SortingOption) { public sortingOptionChanged(option: SortingOption) {
@ -326,6 +330,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy {
} }
this.displayedFiles = filteredFiles; this.displayedFiles = filteredFiles;
this._changeDetectorRef.detectChanges();
} }
private _checkFilter(file: FileStatus, filters: FilterModel[], validate: Function) { private _checkFilter(file: FileStatus, filters: FilterModel[], validate: Function) {

View File

@ -221,6 +221,9 @@ export class AppStateService {
} }
async getFiles(project?: ProjectWrapper) { async getFiles(project?: ProjectWrapper) {
if (!project) {
project = this.activeProject;
}
const files = await this._statusControllerService const files = await this._statusControllerService
.getProjectStatus(project.project.projectId) .getProjectStatus(project.project.projectId)
.toPromise(); .toPromise();
@ -231,8 +234,8 @@ export class AppStateService {
for (const oldFile of oldFiles) { for (const oldFile of oldFiles) {
if (oldFile.fileId === file.fileId) { if (oldFile.fileId === file.fileId) {
// emit when analysis count changed // emit when analysis count changed
if (oldFile.numberOfAnalyses !== file.numberOfAnalyses) { if (oldFile.lastUpdated !== file.lastUpdated) {
this.fileStatusChanged.emit(oldFile); this.fileStatusChanged.emit(file);
} }
found = true; found = true;
break; break;
@ -473,4 +476,11 @@ export class AppStateService {
this._appState.dictionaryVersion = result.dictionaryVersion; this._appState.dictionaryVersion = result.dictionaryVersion;
this._appState.ruleVersion = result.rulesVersion; this._appState.ruleVersion = result.rulesVersion;
} }
isReviewerOrOwner(fileStatus: FileStatus) {
return (
fileStatus.currentReviewer === this._userService.userId ||
this.isActiveProjectOwnerAndManager
);
}
} }

View File

@ -1,4 +1,5 @@
<section class="full-page-load-section" *ngIf="displayed"></section> <section class="full-page-load-section" *ngIf="displayed"></section>
<section class="full-page-load-spinner" *ngIf="displayed"> <section class="full-page-load-spinner" *ngIf="displayed">
<mat-spinner diameter="40"></mat-spinner> <mat-spinner diameter="40"></mat-spinner>
<h1 class="heading-l" *ngIf="message">{{ message | translate }} {{ message }}</h1>
</section> </section>

View File

@ -19,5 +19,6 @@
z-index: 1000; z-index: 1000;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
flex-direction: column;
display: flex; display: flex;
} }

View File

@ -1,4 +1,4 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input } from '@angular/core';
@Component({ @Component({
selector: 'redaction-full-page-loading-indicator', selector: 'redaction-full-page-loading-indicator',
@ -7,4 +7,5 @@ import { Component, Input, OnInit } from '@angular/core';
}) })
export class FullPageLoadingIndicatorComponent { export class FullPageLoadingIndicatorComponent {
@Input() displayed = false; @Input() displayed = false;
@Input() message: string;
} }

View File

@ -462,6 +462,7 @@
} }
}, },
"file-preview": { "file-preview": {
"reanalyse-file": "File reanalysis in progress... ",
"view-toggle": { "view-toggle": {
"label": "Redacted View" "label": "Redacted View"
}, },