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"
},