re-draw requests
This commit is contained in:
parent
8b5d3ee0f6
commit
d3db348fe4
@ -29,6 +29,7 @@ import { ManualAnnotationResponse } from '../model/manual-annotation-response';
|
|||||||
import { FileDataModel } from '../model/file-data.model';
|
import { FileDataModel } from '../model/file-data.model';
|
||||||
import { AnnotationFilter } from '../../../utils/types';
|
import { AnnotationFilter } from '../../../utils/types';
|
||||||
import { FileActionService } from '../service/file-action.service';
|
import { FileActionService } from '../service/file-action.service';
|
||||||
|
import { AnnotationDrawService } from '../service/annotation-draw.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redaction-file-preview-screen',
|
selector: 'redaction-file-preview-screen',
|
||||||
@ -60,6 +61,7 @@ export class FilePreviewScreenComponent implements OnInit {
|
|||||||
private readonly _activatedRoute: ActivatedRoute,
|
private readonly _activatedRoute: ActivatedRoute,
|
||||||
private readonly _dialogService: DialogService,
|
private readonly _dialogService: DialogService,
|
||||||
private readonly _router: Router,
|
private readonly _router: Router,
|
||||||
|
private readonly _annotationDrawService: AnnotationDrawService,
|
||||||
private readonly _fileActionService: FileActionService,
|
private readonly _fileActionService: FileActionService,
|
||||||
private readonly _manualAnnotationService: ManualAnnotationService,
|
private readonly _manualAnnotationService: ManualAnnotationService,
|
||||||
private readonly _fileDownloadService: FileDownloadService,
|
private readonly _fileDownloadService: FileDownloadService,
|
||||||
@ -100,9 +102,15 @@ export class FilePreviewScreenComponent implements OnInit {
|
|||||||
.loadFileData(this.appStateService.activeProjectId, this.fileId)
|
.loadFileData(this.appStateService.activeProjectId, this.fileId)
|
||||||
.subscribe((fileDataModel) => {
|
.subscribe((fileDataModel) => {
|
||||||
this.fileData = fileDataModel;
|
this.fileData = fileDataModel;
|
||||||
this.annotations = fileDataModel.redactionLog.redactionLogEntry.map(
|
const manualRedactionAnnotations = fileDataModel.manualRedactions.entriesToAdd.map(
|
||||||
(rde) => new AnnotationWrapper(rde, null)
|
(mr) => AnnotationWrapper.fromManualRedaction(mr)
|
||||||
);
|
);
|
||||||
|
const redactionLogAnnotations = fileDataModel.redactionLog.redactionLogEntry.map(
|
||||||
|
(rde) => AnnotationWrapper.fromRedactionLog(rde)
|
||||||
|
);
|
||||||
|
|
||||||
|
this.annotations.push(...manualRedactionAnnotations);
|
||||||
|
this.annotations.push(...redactionLogAnnotations);
|
||||||
this._changeDetectorRef.detectChanges();
|
this._changeDetectorRef.detectChanges();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -177,22 +185,7 @@ export class FilePreviewScreenComponent implements OnInit {
|
|||||||
this._dialogRef = this._dialogService.openManualRedactionDialog(
|
this._dialogRef = this._dialogService.openManualRedactionDialog(
|
||||||
$event,
|
$event,
|
||||||
(response: ManualAnnotationResponse) => {
|
(response: ManualAnnotationResponse) => {
|
||||||
const manualRedactionEntry: ManualRedactionEntry =
|
// TODO REDRAW ANNOTATIONS FROM MANUAL REQUESTS
|
||||||
response.manualRedactionEntryWrapper.manualRedactionEntry;
|
|
||||||
|
|
||||||
const annotManager = this.activeViewer.annotManager;
|
|
||||||
const originalQuads = $event.quads;
|
|
||||||
for (const key of Object.keys(originalQuads)) {
|
|
||||||
const pageNumber = parseInt(key, 10);
|
|
||||||
const highlight = new this.activeViewer.Annotations.TextHighlightAnnotation();
|
|
||||||
highlight.PageNumber = pageNumber;
|
|
||||||
highlight.StrokeColor = this._getColor(manualRedactionEntry);
|
|
||||||
highlight.setContents(manualRedactionEntry.reason);
|
|
||||||
highlight.Quads = originalQuads[key];
|
|
||||||
highlight.Id = this._computeId(response);
|
|
||||||
annotManager.addAnnotation(highlight, true);
|
|
||||||
annotManager.redrawAnnotation(highlight);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -403,33 +396,10 @@ 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,
|
||||||
private _computeId(response: ManualAnnotationResponse) {
|
this.fileData.manualRedactions.entriesToAdd
|
||||||
// if owner or not set the request prefix in the id
|
);
|
||||||
const prefix = this.appStateService.isActiveProjectOwner ? '' : 'request:add:';
|
|
||||||
|
|
||||||
if (prefix.length > 0) {
|
|
||||||
return prefix + response.dictionary + ':' + response.annotationId;
|
|
||||||
} else {
|
|
||||||
const dictionaryType: 'hint' | 'redaction' =
|
|
||||||
response.manualRedactionEntryWrapper.type === 'REDACTION'
|
|
||||||
? 'redaction'
|
|
||||||
: this.appStateService.getDictionaryTypeValue(response.dictionary).hint
|
|
||||||
? 'hint'
|
|
||||||
: 'redaction';
|
|
||||||
return dictionaryType + ':' + response.dictionary + ':' + response.annotationId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _getColor(manualRedactionEntry: ManualRedactionEntry) {
|
|
||||||
// if you're the owner, use the request color, otherwise use the actual dict color
|
|
||||||
const color = this.appStateService.isActiveProjectOwner
|
|
||||||
? this.appStateService.getDictionaryColor(manualRedactionEntry.type)
|
|
||||||
: this.appStateService.getDictionaryColor('request');
|
|
||||||
|
|
||||||
const rgbColor = hexToRgb(color);
|
|
||||||
return new this.activeViewer.Annotations.Color(rgbColor.r, rgbColor.g, rgbColor.b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
filtersChanged(filters: AnnotationFilter[]) {
|
filtersChanged(filters: AnnotationFilter[]) {
|
||||||
|
|||||||
@ -1,9 +1,4 @@
|
|||||||
import {
|
import { ManualRedactionEntry, Point, RedactionLogEntry } from '@redaction/red-ui-http';
|
||||||
ManualRedactionEntry,
|
|
||||||
ManualRedactions,
|
|
||||||
Point,
|
|
||||||
RedactionLogEntry
|
|
||||||
} from '@redaction/red-ui-http';
|
|
||||||
|
|
||||||
export class AnnotationWrapper {
|
export class AnnotationWrapper {
|
||||||
superType: 'request' | 'redaction' | 'hint' | 'ignore';
|
superType: 'request' | 'redaction' | 'hint' | 'ignore';
|
||||||
@ -17,22 +12,39 @@ export class AnnotationWrapper {
|
|||||||
content: string;
|
content: string;
|
||||||
pageNumber;
|
pageNumber;
|
||||||
|
|
||||||
constructor(public redactionLogEntry: RedactionLogEntry, manualRedactions?: ManualRedactions) {
|
static fromRedactionLog(redactionLogEntry: RedactionLogEntry) {
|
||||||
this.superType = redactionLogEntry.redacted
|
const annotationWrapper = new AnnotationWrapper();
|
||||||
|
annotationWrapper.superType = redactionLogEntry.redacted
|
||||||
? 'redaction'
|
? 'redaction'
|
||||||
: redactionLogEntry.hint
|
: redactionLogEntry.hint
|
||||||
? 'hint'
|
? 'hint'
|
||||||
: 'ignore';
|
: 'ignore';
|
||||||
this.dictionary = redactionLogEntry.type;
|
annotationWrapper.dictionary = redactionLogEntry.type;
|
||||||
this.firstTopLeftPoint = redactionLogEntry.positions[0]?.topLeft;
|
annotationWrapper.firstTopLeftPoint = redactionLogEntry.positions[0]?.topLeft;
|
||||||
this.pageNumber = redactionLogEntry.positions[0]?.page;
|
annotationWrapper.pageNumber = redactionLogEntry.positions[0]?.page;
|
||||||
this.id = redactionLogEntry.id;
|
annotationWrapper.id = redactionLogEntry.id;
|
||||||
this.content =
|
annotationWrapper.content =
|
||||||
this.superType === 'redaction' || this.superType === 'ignore'
|
annotationWrapper.superType === 'redaction' || annotationWrapper.superType === 'ignore'
|
||||||
? this.createAnnotationContent(redactionLogEntry)
|
? AnnotationWrapper.createAnnotationContentForRedactionLogEntry(redactionLogEntry)
|
||||||
: null;
|
: null;
|
||||||
|
return annotationWrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fromManualRedaction(manualRedactionEntry: ManualRedactionEntry) {
|
||||||
|
const annotationWrapper = new AnnotationWrapper();
|
||||||
|
annotationWrapper.superType = 'request';
|
||||||
|
annotationWrapper.dictionary = manualRedactionEntry.type;
|
||||||
|
annotationWrapper.firstTopLeftPoint = manualRedactionEntry.positions[0]?.topLeft;
|
||||||
|
annotationWrapper.pageNumber = manualRedactionEntry.positions[0]?.page;
|
||||||
|
annotationWrapper.id = manualRedactionEntry.id;
|
||||||
|
annotationWrapper.content = manualRedactionEntry.addToDictionary
|
||||||
|
? null
|
||||||
|
: AnnotationWrapper.createAnnotationContentForManualRedaction(manualRedactionEntry);
|
||||||
|
return annotationWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
get manualRedactionOwner() {
|
get manualRedactionOwner() {
|
||||||
return this.manualRedactionEntry?.user;
|
return this.manualRedactionEntry?.user;
|
||||||
}
|
}
|
||||||
@ -45,7 +57,13 @@ export class AnnotationWrapper {
|
|||||||
return this.firstTopLeftPoint.y;
|
return this.firstTopLeftPoint.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
private createAnnotationContent(entry: RedactionLogEntry) {
|
private static createAnnotationContentForManualRedaction(entry: ManualRedactionEntry) {
|
||||||
|
return entry.reason;
|
||||||
|
// + '\n\nLegal basis:' +
|
||||||
|
// entry.legalBasis
|
||||||
|
}
|
||||||
|
|
||||||
|
private static createAnnotationContentForRedactionLogEntry(entry: RedactionLogEntry) {
|
||||||
// return "\nRule " + entry.matchedRule + " matched\n\n" + entry.reason + "\n\nLegal basis:" + entry.legalBasis + "\n\nIn section: \"" + entry.section + "\"";
|
// return "\nRule " + entry.matchedRule + " matched\n\n" + entry.reason + "\n\nLegal basis:" + entry.legalBasis + "\n\nIn section: \"" + entry.section + "\"";
|
||||||
return (
|
return (
|
||||||
entry.reason +
|
entry.reason +
|
||||||
|
|||||||
@ -129,8 +129,6 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnChanges {
|
|||||||
instance.loadDocument(pdfBlob, {
|
instance.loadDocument(pdfBlob, {
|
||||||
filename: this.fileStatus ? this.fileStatus.filename : 'document.pdf'
|
filename: this.fileStatus ? this.fileStatus.filename : 'document.pdf'
|
||||||
});
|
});
|
||||||
|
|
||||||
this.viewerReady.emit(instance);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,6 +282,7 @@ export class PdfViewerComponent implements OnInit, AfterViewInit, OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _restoreViewerState() {
|
private _restoreViewerState() {
|
||||||
|
this.viewerReady.emit(this.instance);
|
||||||
this._restoreState(this._viewerState, this.instance);
|
this._restoreState(this._viewerState, this.instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,71 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { WebViewerInstance } from '@pdftron/webviewer';
|
||||||
|
import { ManualRedactionEntry, Rectangle } from '@redaction/red-ui-http';
|
||||||
|
import { hexToRgb } from '../../../utils/functions';
|
||||||
|
import { AppStateService } from '../../../state/app-state.service';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class AnnotationDrawService {
|
||||||
|
constructor(private readonly _appStateService: AppStateService) {}
|
||||||
|
|
||||||
|
public drawAnnotations(activeViewer: WebViewerInstance, mres: ManualRedactionEntry[]) {
|
||||||
|
mres.forEach((mre) => {
|
||||||
|
this.drawAnnotation(activeViewer, mre);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public drawAnnotation(activeViewer: WebViewerInstance, mre: ManualRedactionEntry) {
|
||||||
|
const pageNumber = mre.positions[0].page;
|
||||||
|
const highlight = new activeViewer.Annotations.TextHighlightAnnotation();
|
||||||
|
highlight.PageNumber = pageNumber;
|
||||||
|
highlight.StrokeColor = this._getColor(activeViewer, mre);
|
||||||
|
highlight.setContents(mre.reason);
|
||||||
|
highlight.Quads = this._rectanglesToQuads(mre.positions, activeViewer, pageNumber);
|
||||||
|
highlight.Id = mre.id;
|
||||||
|
|
||||||
|
const annotationManager = activeViewer.annotManager;
|
||||||
|
annotationManager.addAnnotation(highlight, true);
|
||||||
|
annotationManager.redrawAnnotation(highlight);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getColor(activeViewer: WebViewerInstance, manualRedactionEntry: ManualRedactionEntry) {
|
||||||
|
// if you're the owner, use the request color, otherwise use the actual dict color
|
||||||
|
const color = this._appStateService.isActiveProjectOwner
|
||||||
|
? this._appStateService.getDictionaryColor(manualRedactionEntry.type)
|
||||||
|
: this._appStateService.getDictionaryColor('request');
|
||||||
|
|
||||||
|
const rgbColor = hexToRgb(color);
|
||||||
|
return new activeViewer.Annotations.Color(rgbColor.r, rgbColor.g, rgbColor.b);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _rectanglesToQuads(
|
||||||
|
positions: Rectangle[],
|
||||||
|
activeViewer: WebViewerInstance,
|
||||||
|
pageNumber: number
|
||||||
|
): any[] {
|
||||||
|
const pageHeight = activeViewer.docViewer.getPageHeight(pageNumber);
|
||||||
|
return positions.map((p) => this._rectangleToQuad(p, activeViewer, pageHeight));
|
||||||
|
}
|
||||||
|
|
||||||
|
private _rectangleToQuad(
|
||||||
|
rectangle: Rectangle,
|
||||||
|
activeViewer: WebViewerInstance,
|
||||||
|
pageHeight: number
|
||||||
|
): any {
|
||||||
|
const x1 = rectangle.topLeft.x;
|
||||||
|
const y1 = pageHeight - (rectangle.topLeft.y + rectangle.height);
|
||||||
|
|
||||||
|
const x2 = rectangle.topLeft.x + rectangle.width;
|
||||||
|
const y2 = pageHeight - (rectangle.topLeft.y + rectangle.height);
|
||||||
|
|
||||||
|
const x3 = rectangle.topLeft.x + rectangle.width;
|
||||||
|
const y3 = pageHeight - rectangle.topLeft.y;
|
||||||
|
|
||||||
|
const x4 = rectangle.topLeft.x;
|
||||||
|
const y4 = pageHeight - rectangle.topLeft.y;
|
||||||
|
|
||||||
|
return new activeViewer.Annotations.Quad(x1, y1, x2, y2, x3, y3, x4, y4);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,8 @@
|
|||||||
import { AnnotationWrapper } from '../screens/file/model/annotation.wrapper';
|
import { AnnotationWrapper } from '../screens/file/model/annotation.wrapper';
|
||||||
import { AnnotationFilter } from './types';
|
import { AnnotationFilter } from './types';
|
||||||
|
import { ManualRedactionEntry } from '@redaction/red-ui-http';
|
||||||
|
import { WebViewerInstance } from '@pdftron/webviewer';
|
||||||
|
import { hexToRgb } from './functions';
|
||||||
|
|
||||||
export class AnnotationUtils {
|
export class AnnotationUtils {
|
||||||
public static sortAnnotations(annotations: AnnotationWrapper[]): AnnotationWrapper[] {
|
public static sortAnnotations(annotations: AnnotationWrapper[]): AnnotationWrapper[] {
|
||||||
@ -70,8 +73,6 @@ export class AnnotationUtils {
|
|||||||
obj[page].annotations = this.sortAnnotations(obj[page].annotations);
|
obj[page].annotations = this.sortAnnotations(obj[page].annotations);
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(obj);
|
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user