fixed lint err

This commit is contained in:
Timo Bejan 2020-11-10 21:28:43 +02:00
parent bbb4b6fb93
commit 912fa000ff
5 changed files with 192 additions and 136 deletions

View File

@ -88,7 +88,7 @@
>
<div class="details">
<redaction-annotation-icon
[color]="annotation.manualAddToDictionary ? '#5B97DB' : null"
[color]="annotation.modifyDictionary ? '#5B97DB' : null"
[typeValue]="appStateService.getDictionaryTypeValueForAnnotation(annotation)"
></redaction-annotation-icon>
<div class="flex-1">

View File

@ -119,23 +119,22 @@ export class FilePreviewScreenComponent implements OnInit {
private _loadFileData() {
return this._fileDownloadService.loadActiveFileData().pipe(
tap((fileDataModel) => {
this.fileData = fileDataModel;
this._rebuildFilters();
if (fileDataModel.fileStatus.isWorkable) {
this.fileData = fileDataModel;
this._rebuildFilters();
} else {
if (fileDataModel.fileStatus.isError) {
this._router.navigate(['/ui/projects/' + this.appStateService.activeProjectId]);
} else {
this.loadingMessage = 'file-preview.reanalyse-file';
}
}
})
);
}
private _rebuildFilters() {
const manualRedactionAnnotations = this.fileData.entriesToAdd.map((mr) =>
AnnotationWrapper.fromManualRedaction(mr, this.fileData.manualRedactions, this.appStateService.dictionaryData, this.permissionsService.currentUser)
);
const redactionLogAnnotations = this.fileData.redactionLogEntry.map((rde) =>
AnnotationWrapper.fromRedactionLog(rde, this.fileData.manualRedactions, this.permissionsService.currentUser)
);
this.annotations = [];
this.annotations.push(...manualRedactionAnnotations);
this.annotations.push(...redactionLogAnnotations);
this.annotations = this.fileData.getAnnotations(this.appStateService.dictionaryData, this.permissionsService.currentUser);
this.filters = this._annotationProcessingService.getAnnotationFilter(this.annotations);
this.filtersChanged(this.filters);
}
@ -371,17 +370,20 @@ export class FilePreviewScreenComponent implements OnInit {
private _cleanupAndRedrawManualAnnotations() {
this._fileDownloadService.loadActiveFileManualAnnotations().subscribe((manualRedactions) => {
const annotationsToRemove = [];
this.fileData.entriesToAdd.forEach((manuallyAddedEntry) => {
const annotation = this.activeViewer.annotManager.getAnnotationById(manuallyAddedEntry.id);
const previouslyDrawnAnnotations = this.annotations.filter((a) => a.shouldDraw);
previouslyDrawnAnnotations.forEach((annotationWrapper) => {
const annotation = this.activeViewer.annotManager.getAnnotationById(annotationWrapper.id);
if (annotation) {
annotationsToRemove.push(annotation);
}
});
this.activeViewer.annotManager.deleteAnnotations(annotationsToRemove, false, true);
this.fileData.manualRedactions = manualRedactions;
this._annotationDrawService.drawAnnotations(this.instance, this.fileData.entriesToAdd);
this._rebuildFilters();
this._annotationDrawService.drawAnnotations(
this.instance,
this.annotations.filter((a) => a.shouldDraw)
);
});
}

View File

@ -1,5 +1,6 @@
import { Comment, ManualRedactionEntry, ManualRedactions, Point, RedactionLogEntry, TypeValue } from '@redaction/red-ui-http';
import { Comment, FileStatus, IdRemoval, ManualRedactionEntry, Point, Rectangle, RedactionLogEntry, TypeValue } from '@redaction/red-ui-http';
import { UserWrapper } from '../../../user/user.service';
import { FileStatusWrapper } from './file-status.wrapper';
export const SuperTypeSorter = {
redaction: 1,
@ -14,71 +15,120 @@ export class AnnotationWrapper {
dictionary: string;
color: string;
comments: Comment[] = [];
manualRedactionEntry: ManualRedactionEntry;
firstTopLeftPoint: Point;
id: string;
content: string;
manual: boolean;
userId: string;
canUndo: boolean;
manualAddToDictionary: boolean;
modifyDictionary: boolean;
typeLabel: string;
pageNumber: number;
hint: boolean;
shouldDraw: boolean;
redaction: boolean;
positions: Rectangle[];
static fromRedactionLog(redactionLogEntry: RedactionLogEntry, manualRedactions: ManualRedactions, user: UserWrapper) {
const comments: { [key: string]: Array<Comment> } = manualRedactions.comments;
static fromData(
user: UserWrapper,
dictionaryData: { [p: string]: TypeValue },
fileStatus: FileStatusWrapper,
redactionLogEntry?: RedactionLogEntry,
manualRedactionEntry?: ManualRedactionEntry,
idRemoval?: IdRemoval,
comments?: Comment[]
) {
const annotationWrapper = new AnnotationWrapper();
annotationWrapper.id = redactionLogEntry.id;
annotationWrapper.superType = redactionLogEntry.redacted ? 'redaction' : redactionLogEntry.hint ? 'hint' : 'ignore';
annotationWrapper.redaction = redactionLogEntry.redacted;
annotationWrapper.hint = redactionLogEntry.hint;
annotationWrapper.dictionary = redactionLogEntry.type;
annotationWrapper.firstTopLeftPoint = redactionLogEntry.positions[0]?.topLeft;
annotationWrapper.pageNumber = redactionLogEntry.positions[0]?.page;
annotationWrapper.manual = false;
annotationWrapper.content =
annotationWrapper.superType === 'redaction' || annotationWrapper.superType === 'ignore'
? AnnotationWrapper.createAnnotationContentForRedactionLogEntry(redactionLogEntry)
: null;
annotationWrapper.comments = comments ? comments : [];
if (redactionLogEntry) {
annotationWrapper.id = redactionLogEntry.id;
annotationWrapper.redaction = redactionLogEntry.redacted;
annotationWrapper.hint = redactionLogEntry.hint;
annotationWrapper.dictionary = redactionLogEntry.type;
annotationWrapper.firstTopLeftPoint = redactionLogEntry.positions[0]?.topLeft;
annotationWrapper.pageNumber = redactionLogEntry.positions[0]?.page;
annotationWrapper.positions = redactionLogEntry.positions;
annotationWrapper.content = AnnotationWrapper.createContentForRedactionLog(redactionLogEntry);
// either marked as manual or idRemove or manualRedactionEntry exists
annotationWrapper.manual = redactionLogEntry.manual || !!manualRedactionEntry || !!idRemoval;
annotationWrapper.modifyDictionary = !!manualRedactionEntry?.addToDictionary || !!idRemoval?.removeFromDictionary;
switch (redactionLogEntry.status) {
case 'REQUESTED':
annotationWrapper.superType = idRemoval?.status === 'REQUESTED' || idRemoval?.status === 'APPROVED' ? 'suggestion-remove' : 'suggestion';
break;
case 'APPROVED':
annotationWrapper.superType = annotationWrapper.redaction ? 'redaction' : annotationWrapper.hint ? 'hint' : 'ignore';
break;
case 'DECLINED':
// TODO check this
annotationWrapper.superType = 'ignore';
break;
default:
annotationWrapper.superType =
idRemoval?.status === 'REQUESTED' || idRemoval?.status === 'APPROVED'
? 'suggestion-remove'
: annotationWrapper.redaction
? 'redaction'
: annotationWrapper.hint
? 'hint'
: 'ignore';
break;
}
} else {
const dictionary = dictionaryData[manualRedactionEntry.type];
annotationWrapper.id = manualRedactionEntry.id;
annotationWrapper.redaction = !dictionary.hint;
annotationWrapper.hint = dictionary.hint;
annotationWrapper.dictionary = manualRedactionEntry.type;
annotationWrapper.firstTopLeftPoint = manualRedactionEntry.positions[0]?.topLeft;
annotationWrapper.pageNumber = manualRedactionEntry.positions[0]?.page;
annotationWrapper.positions = manualRedactionEntry.positions;
annotationWrapper.content = manualRedactionEntry.addToDictionary ? null : AnnotationWrapper.createContentForManualRedaction(manualRedactionEntry);
annotationWrapper.manual = true;
annotationWrapper.comments = comments[manualRedactionEntry.id] ? comments[manualRedactionEntry.id] : [];
annotationWrapper.userId = manualRedactionEntry.user;
annotationWrapper.canUndo = manualRedactionEntry?.user === user.id;
annotationWrapper.shouldDraw = AnnotationWrapper._shouldDraw(manualRedactionEntry, fileStatus);
annotationWrapper.modifyDictionary = manualRedactionEntry.addToDictionary;
switch (manualRedactionEntry.status) {
case 'REQUESTED':
annotationWrapper.superType = idRemoval?.status === 'REQUESTED' || idRemoval?.status === 'APPROVED' ? 'suggestion-remove' : 'suggestion';
break;
case 'APPROVED':
annotationWrapper.superType = redactionLogEntry.redacted ? 'redaction' : redactionLogEntry.hint ? 'hint' : 'ignore';
break;
case 'DECLINED':
// TODO check this
annotationWrapper.superType = 'ignore';
break;
default:
annotationWrapper.superType =
idRemoval?.status === 'REQUESTED' || idRemoval?.status === 'APPROVED'
? 'suggestion-remove'
: annotationWrapper.redaction
? 'redaction'
: annotationWrapper.hint
? 'hint'
: 'ignore';
break;
}
}
const toRemove = AnnotationWrapper._handleRemoveSuperType(annotationWrapper, manualRedactions, user);
annotationWrapper.manualAddToDictionary = toRemove ? toRemove.removeFromDictionary : false;
annotationWrapper.comments = comments[redactionLogEntry.id] ? comments[redactionLogEntry.id] : [];
AnnotationWrapper._setTypeLabel(annotationWrapper);
return annotationWrapper;
}
static fromManualRedaction(
manualRedactionEntry: ManualRedactionEntry,
manualRedactions: ManualRedactions,
dictionaryData: { [p: string]: TypeValue },
user: UserWrapper
) {
const comments: { [key: string]: Array<Comment> } = manualRedactions.comments;
const annotationWrapper = new AnnotationWrapper();
annotationWrapper.id = manualRedactionEntry.id;
annotationWrapper.superType = AnnotationWrapper.getManualRedactionSuperType(manualRedactionEntry, dictionaryData);
const dictionary = dictionaryData[manualRedactionEntry.type];
annotationWrapper.redaction = !dictionary.hint;
annotationWrapper.hint = dictionary.hint;
AnnotationWrapper._handleRemoveSuperType(annotationWrapper, manualRedactions, user);
annotationWrapper.dictionary = manualRedactionEntry.type;
annotationWrapper.firstTopLeftPoint = manualRedactionEntry.positions[0]?.topLeft;
annotationWrapper.pageNumber = manualRedactionEntry.positions[0]?.page;
annotationWrapper.content = manualRedactionEntry.addToDictionary
? null
: AnnotationWrapper.createAnnotationContentForManualRedaction(manualRedactionEntry);
annotationWrapper.manual = true;
annotationWrapper.comments = comments[manualRedactionEntry.id] ? comments[manualRedactionEntry.id] : [];
annotationWrapper.userId = manualRedactionEntry.user;
annotationWrapper.canUndo = !manualRedactionEntry.processedDate && manualRedactionEntry.user === user.id;
private static _shouldDraw(manualRedaction: ManualRedactionEntry, fileStatus: FileStatus): boolean {
const isRequested =
manualRedaction.status === 'REQUESTED' && new Date(manualRedaction.requestDate).getTime() > new Date(fileStatus.lastProcessed).getTime();
const isApprovedOrDeclined =
(manualRedaction.status === 'APPROVED' || manualRedaction.status === 'DECLINED') &&
new Date(manualRedaction.requestDate).getTime() > new Date(fileStatus.lastProcessed).getTime();
annotationWrapper.manualAddToDictionary = manualRedactionEntry.addToDictionary;
AnnotationWrapper._setTypeLabel(annotationWrapper);
return annotationWrapper;
return isRequested || isApprovedOrDeclined;
}
private static _setTypeLabel(annotationWrapper: AnnotationWrapper) {
@ -91,7 +141,7 @@ export class AnnotationWrapper {
}
if (annotationWrapper.redaction) {
label += '-redaction';
if (annotationWrapper.manualAddToDictionary) {
if (annotationWrapper.modifyDictionary) {
label += '-dictionary';
}
}
@ -100,35 +150,8 @@ export class AnnotationWrapper {
annotationWrapper.typeLabel = label;
}
private static _handleRemoveSuperType(annotationWrapper: AnnotationWrapper, manualRedactions: ManualRedactions, user: UserWrapper) {
const toRemove = manualRedactions.idsToRemove.find((trm) => trm.id === annotationWrapper.id);
// change super-type based on toRemove
annotationWrapper.superType = toRemove
? toRemove.status === 'REQUESTED'
? 'suggestion-remove'
: toRemove.status === 'APPROVED'
? 'ignore'
: annotationWrapper.superType
: annotationWrapper.superType;
if (toRemove) {
annotationWrapper.canUndo = !toRemove.processedDate && toRemove.user === user.id;
}
return toRemove;
}
static getManualRedactionSuperType(manualRedactionEntry: ManualRedactionEntry, dictionaryData: { [p: string]: TypeValue }) {
const dictionary = dictionaryData[manualRedactionEntry.type];
return manualRedactionEntry.status === 'REQUESTED' ? 'suggestion' : dictionary.hint ? 'hint' : 'redaction';
}
constructor() {}
get manualRedactionOwner() {
return this.manualRedactionEntry?.user;
}
get x() {
return this.firstTopLeftPoint.x;
}
@ -137,14 +160,13 @@ export class AnnotationWrapper {
return this.firstTopLeftPoint.y;
}
private static createAnnotationContentForManualRedaction(entry: ManualRedactionEntry) {
return entry.reason;
// + '\n\nLegal basis:' +
// entry.legalBasis
private static createContentForRedactionLog(entry: RedactionLogEntry) {
if (entry.redacted) {
return entry.reason + '\n\nLegal basis:' + entry.legalBasis + '\n\nIn section: "' + entry.section + '"';
}
}
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 entry.reason + '\n\nLegal basis:' + entry.legalBasis + '\n\nIn section: "' + entry.section + '"';
private static createContentForManualRedaction(entry: ManualRedactionEntry) {
return entry.reason + '\n\nLegal basis:' + entry.legalBasis;
}
}

View File

@ -1,5 +1,14 @@
import { ManualRedactionEntry, ManualRedactions, RedactionLog, RedactionLogEntry, ViewedPages } from '@redaction/red-ui-http';
import { Comment, IdRemoval, ManualRedactionEntry, ManualRedactions, RedactionLog, RedactionLogEntry, TypeValue, ViewedPages } from '@redaction/red-ui-http';
import { FileStatusWrapper } from './file-status.wrapper';
import { UserWrapper } from '../../../user/user.service';
import { AnnotationWrapper } from './annotation.wrapper';
export interface AnnotationPair {
redactionLogEntry?: RedactionLogEntry;
manualRedactionEntry?: ManualRedactionEntry;
idRemoval?: IdRemoval;
comments?: Comment[];
}
export class FileDataModel {
constructor(
@ -12,18 +21,54 @@ export class FileDataModel {
) {}
get redactionLogEntry(): RedactionLogEntry[] {
return this.redactionLog.redactionLogEntry.filter((r) => r.status !== 'REQUESTED');
return this.redactionLog.redactionLogEntry;
}
get entriesToAdd(): ManualRedactionEntry[] {
return this.manualRedactions.entriesToAdd.filter((manualRedaction) => {
const isRequested =
manualRedaction.status === 'REQUESTED' && new Date(manualRedaction.requestDate).getTime() > new Date(this.fileStatus.lastProcessed).getTime();
const isApprovedOrDeclined =
(manualRedaction.status === 'APPROVED' || manualRedaction.status === 'DECLINED') &&
new Date(manualRedaction.requestDate).getTime() > new Date(this.fileStatus.lastProcessed).getTime();
getAnnotations(dictionaryData: { [p: string]: TypeValue }, currentUser: UserWrapper): AnnotationWrapper[] {
const annotations = [];
return isRequested || isApprovedOrDeclined;
const pairs: AnnotationPair[] = this._createPairs();
pairs.forEach((pair) => {
const annotation = AnnotationWrapper.fromData(
currentUser,
dictionaryData,
this.fileStatus,
pair.redactionLogEntry,
pair.manualRedactionEntry,
pair.idRemoval,
pair.comments
);
annotations.push(annotation);
});
return annotations;
}
private _createPairs(): AnnotationPair[] {
const pairs: AnnotationPair[] = [];
this.redactionLog.redactionLogEntry.forEach((rdl) => {
pairs.push({
redactionLogEntry: rdl,
manualRedactionEntry: this.manualRedactions.entriesToAdd.find((eta) => eta.id === rdl.id),
idRemoval: this.manualRedactions.idsToRemove.find((idr) => idr.id === rdl.id),
comments: this.manualRedactions.comments[rdl.id]
});
});
this.manualRedactions.entriesToAdd.forEach((eta) => {
const redactionLogEntry = this.redactionLog.redactionLogEntry.find((rdl) => rdl.id === eta.id);
if (!redactionLogEntry) {
pairs.push({
redactionLogEntry: null,
manualRedactionEntry: eta,
idRemoval: this.manualRedactions.idsToRemove.find((idr) => idr.id === eta.id),
comments: this.manualRedactions.comments[eta.id]
});
}
});
return pairs;
}
}

View File

@ -11,55 +11,42 @@ import { AnnotationWrapper } from '../model/annotation.wrapper';
export class AnnotationDrawService {
constructor(private readonly _appStateService: AppStateService) {}
public drawAnnotations(activeViewer: WebViewerInstance, mres: ManualRedactionEntry[]) {
mres.forEach((mre) => {
public drawAnnotations(activeViewer: WebViewerInstance, annotationWrappers: AnnotationWrapper[]) {
annotationWrappers.forEach((mre) => {
this.drawAnnotation(activeViewer, mre);
});
}
public drawAnnotation(activeViewer: WebViewerInstance, mre: ManualRedactionEntry) {
const pageNumber = mre.positions[0].page;
public drawAnnotation(activeViewer: WebViewerInstance, annotationWrapper: AnnotationWrapper) {
const pageNumber = annotationWrapper.pageNumber;
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;
highlight.StrokeColor = this._getColor(activeViewer, annotationWrapper);
highlight.setContents(annotationWrapper.content);
highlight.Quads = this._rectanglesToQuads(annotationWrapper.positions, activeViewer, pageNumber);
highlight.Id = annotationWrapper.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 superType = AnnotationWrapper.getManualRedactionSuperType(
manualRedactionEntry,
this._appStateService.dictionaryData
);
private _getColor(activeViewer: WebViewerInstance, annotationWrapper: AnnotationWrapper) {
const color =
superType === 'suggestion'
? this._appStateService.getDictionaryColor(superType)
: this._appStateService.getDictionaryColor(manualRedactionEntry.type);
annotationWrapper.superType === 'suggestion' || annotationWrapper.superType === 'suggestion-remove'
? this._appStateService.getDictionaryColor(annotationWrapper.superType)
: this._appStateService.getDictionaryColor(annotationWrapper.dictionary);
const rgbColor = hexToRgb(color);
return new activeViewer.Annotations.Color(rgbColor.r, rgbColor.g, rgbColor.b);
}
private _rectanglesToQuads(
positions: Rectangle[],
activeViewer: WebViewerInstance,
pageNumber: number
): any[] {
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 {
private _rectangleToQuad(rectangle: Rectangle, activeViewer: WebViewerInstance, pageHeight: number): any {
const x1 = rectangle.topLeft.x;
const y1 = pageHeight - (rectangle.topLeft.y + rectangle.height);