improved file screen performance
This commit is contained in:
parent
31eacd1f31
commit
6947083c7c
@ -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>
|
||||||
|
|
||||||
|
|||||||
@ -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[]) {
|
||||||
|
|||||||
@ -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()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -462,6 +462,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"file-preview": {
|
"file-preview": {
|
||||||
|
"reanalyse-file": "File reanalysis in progress... ",
|
||||||
"view-toggle": {
|
"view-toggle": {
|
||||||
"label": "Redacted View"
|
"label": "Redacted View"
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user