manual redaction actions are now linked in real time to reviewer popup

This commit is contained in:
Timo Bejan 2020-11-03 09:26:30 +02:00
parent 7ca894c6d9
commit 5a3f6852ea
5 changed files with 111 additions and 72 deletions

View File

@ -74,6 +74,7 @@
<div class="flex red-content-inner">
<div class="left-container">
<redaction-pdf-viewer
[isReviewer]="appStateService.isActiveFileDocumentReviewer"
(annotationSelected)="handleAnnotationSelected($event)"
(keyUp)="handleKeyEvent($event)"
(manualAnnotationRequested)="openManualRedactionDialog($event)"

View File

@ -116,33 +116,23 @@ export class FilePreviewScreenComponent implements OnInit {
}
private _loadFileData() {
this._fileDownloadService
.loadFileData(this.appStateService.activeProjectId, this.fileId)
.subscribe((fileDataModel) => {
this.fileData = fileDataModel;
this._fileDownloadService.loadActiveFileData().subscribe((fileDataModel) => {
this.fileData = fileDataModel;
const manualRedactionAnnotations = fileDataModel.entriesToAdd.map((mr) =>
AnnotationWrapper.fromManualRedaction(
mr,
fileDataModel.manualRedactions.comments
)
);
const redactionLogAnnotations = fileDataModel.redactionLog.redactionLogEntry.map(
(rde) =>
AnnotationWrapper.fromRedactionLog(
rde,
fileDataModel.manualRedactions.comments
)
);
const manualRedactionAnnotations = fileDataModel.entriesToAdd.map((mr) =>
AnnotationWrapper.fromManualRedaction(mr, fileDataModel.manualRedactions.comments)
);
const redactionLogAnnotations = fileDataModel.redactionLog.redactionLogEntry.map(
(rde) =>
AnnotationWrapper.fromRedactionLog(rde, fileDataModel.manualRedactions.comments)
);
this.annotations.push(...manualRedactionAnnotations);
this.annotations.push(...redactionLogAnnotations);
this.filters = this._annotationProcessingService.getAnnotationFilter(
this.annotations
);
this.filtersChanged(this.filters);
this._changeDetectorRef.detectChanges();
});
this.annotations.push(...manualRedactionAnnotations);
this.annotations.push(...redactionLogAnnotations);
this.filters = this._annotationProcessingService.getAnnotationFilter(this.annotations);
this.filtersChanged(this.filters);
this._changeDetectorRef.detectChanges();
});
}
public openFileDetailsDialog($event: MouseEvent) {
@ -207,7 +197,7 @@ export class FilePreviewScreenComponent implements OnInit {
this._dialogRef = this._dialogService.openManualRedactionDialog(
$event,
(response: ManualAnnotationResponse) => {
// TODO REDRAW ANNOTATIONS FROM MANUAL REQUESTS
this._cleanupAndRedrawManualAnnotations();
}
);
});
@ -280,8 +270,7 @@ export class FilePreviewScreenComponent implements OnInit {
$event,
annotation,
() => {
// TODO DELETE ANNOTATIOn
//this.activeViewer.annotManager.deleteAnnotation(annotation, false, true);
this._cleanupAndRedrawManualAnnotations();
}
);
});
@ -449,4 +438,27 @@ export class FilePreviewScreenComponent implements OnInit {
$event.preventDefault();
}
}
private _cleanupAndRedrawManualAnnotations() {
this._fileDownloadService
.loadActiveFileManualAnnotations()
.subscribe((manualRedactions) => {
this.fileData.manualRedactions = manualRedactions;
const annotationsToRemove = [];
this.fileData.entriesToAdd.forEach((manuallyAddedEntry) => {
const annotation = this.activeViewer.annotManager.getAnnotationById(
manuallyAddedEntry.id
);
if (annotation) {
annotationsToRemove.push(annotation);
}
});
this.activeViewer.annotManager.deleteAnnotations(annotationsToRemove, false, true);
this._annotationDrawService.drawAnnotations(
this.instance,
this.fileData.entriesToAdd
);
});
}
}

View File

@ -46,6 +46,7 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnChanges {
@Input() fileData: Blob;
@Input() fileStatus: FileStatus;
@Input() isReviewer = false;
@Output() fileReady = new EventEmitter();
@Output() annotationSelected = new EventEmitter<string>();
@ -55,8 +56,6 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnChanges {
@Output() viewerReady = new EventEmitter<WebViewerInstance>();
@Input() flag = false;
@ViewChild('viewer', { static: true }) viewer: ElementRef;
instance: WebViewerInstance;
@ -77,6 +76,10 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnChanges {
if (changes.fileData && !changes.fileData.firstChange) {
this._changeDocument();
}
if (changes.isReviewer) {
this._handleCustomActions();
}
console.log(this.isReviewer);
}
ngAfterViewInit(): void {
@ -169,41 +172,52 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnChanges {
}, 250);
}
});
if (this._appStateService.isActiveFileDocumentReviewer) {
this.instance.textPopup.add(<any>{
type: 'actionButton',
img: '/assets/icons/general/add-dictionary.svg',
title: this._translateService.instant(
this._manualAnnotationService.getTitle('DICTIONARY')
),
onClick: () => {
const mre = this._getManualRedactionEntry();
this.manualAnnotationRequested.emit(
new ManualRedactionEntryWrapper(
this.instance.docViewer.getSelectedTextQuads(),
mre,
'DICTIONARY'
)
);
}
});
this.instance.textPopup.add(<any>{
type: 'actionButton',
img: '/assets/icons/general/add-redaction.svg',
title: this._translateService.instant(
this._manualAnnotationService.getTitle('REDACTION')
),
onClick: () => {
const mre = this._getManualRedactionEntry();
this.manualAnnotationRequested.emit(
new ManualRedactionEntryWrapper(
this.instance.docViewer.getSelectedTextQuads(),
mre,
'REDACTION'
)
);
}
});
this.instance.textPopup.add(<any>{
type: 'actionButton',
dataElement: 'add-dictionary',
img: '/assets/icons/general/add-dictionary.svg',
title: this._translateService.instant(
this._manualAnnotationService.getTitle('DICTIONARY')
),
onClick: () => {
const mre = this._getManualRedactionEntry();
this.manualAnnotationRequested.emit(
new ManualRedactionEntryWrapper(
this.instance.docViewer.getSelectedTextQuads(),
mre,
'DICTIONARY'
)
);
}
});
this.instance.textPopup.add(<any>{
type: 'actionButton',
dataElement: 'add-redaction',
img: '/assets/icons/general/add-redaction.svg',
title: this._translateService.instant(
this._manualAnnotationService.getTitle('REDACTION')
),
onClick: () => {
const mre = this._getManualRedactionEntry();
this.manualAnnotationRequested.emit(
new ManualRedactionEntryWrapper(
this.instance.docViewer.getSelectedTextQuads(),
mre,
'REDACTION'
)
);
}
});
this._handleCustomActions();
}
private _handleCustomActions() {
if (this.instance) {
if (this.isReviewer) {
this.instance.enableElements(['add-redaction', 'add-dictionary']);
} else {
this.instance.disableElements(['add-redaction', 'add-dictionary']);
}
}
}
@ -241,7 +255,6 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnChanges {
public selectAnnotation(annotation: AnnotationWrapper) {
this.instance.annotManager.deselectAllAnnotations();
const annotationFromViewer = this.instance.annotManager.getAnnotationById(annotation.id);
console.log(annotationFromViewer);
this.instance.annotManager.selectAnnotation(annotationFromViewer);
this.navigateToPage(annotation.pageNumber);
}

View File

@ -8,24 +8,35 @@ import {
} from '@redaction/red-ui-http';
import { FileType } from '../model/file-type';
import { FileDataModel } from '../model/file-data.model';
import { AppStateService } from '../../../state/app-state.service';
@Injectable({
providedIn: 'root'
})
export class FileDownloadService {
constructor(
private readonly _appStateService: AppStateService,
private readonly _fileUploadControllerService: FileUploadControllerService,
private readonly _manualRedactionControllerService: ManualRedactionControllerService,
private readonly _redactionLogControllerService: RedactionLogControllerService
) {}
public loadFileData(projectId: string, fileId: string): Observable<FileDataModel> {
const annotatedObs = this.loadFile('ANNOTATED', fileId);
const redactedObs = this.loadFile('REDACTED', fileId);
const reactionLogObs = this._redactionLogControllerService.getRedactionLog(fileId);
public loadActiveFileManualAnnotations() {
return this._manualRedactionControllerService.getManualRedaction(
this._appStateService.activeProjectId,
this._appStateService.activeFileId
);
}
public loadActiveFileData(): Observable<FileDataModel> {
const annotatedObs = this.loadFile('ANNOTATED', this._appStateService.activeFileId);
const redactedObs = this.loadFile('REDACTED', this._appStateService.activeFileId);
const reactionLogObs = this._redactionLogControllerService.getRedactionLog(
this._appStateService.activeFileId
);
const manualRedactionsObs = this._manualRedactionControllerService.getManualRedaction(
projectId,
fileId
this._appStateService.activeProjectId,
this._appStateService.activeFileId
);
return forkJoin([annotatedObs, redactedObs, reactionLogObs, manualRedactionsObs]).pipe(

View File

@ -21,6 +21,8 @@ export interface ManualRedactionEntry {
type?: string;
user?: string;
value?: string;
requestDate?: string;
processedDate?: string;
}
export namespace ManualRedactionEntry {
export type StatusEnum = 'REQUESTED' | 'APPROVED' | 'DECLINED';