move redaction log stuff to red-domain

This commit is contained in:
Dan Percic 2021-10-28 23:05:15 +03:00
parent 2ba635ea3c
commit e73d437c2f
51 changed files with 271 additions and 473 deletions

View File

@ -1,7 +1,7 @@
import { Comment, Point, Rectangle } from '@redaction/red-ui-http';
import { RedactionLogEntryWrapper } from './redaction-log-entry.wrapper';
import { annotationTypesTranslations } from '../../translations/annotation-types-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { IComment, IPoint, IRectangle } from '@red/domain';
export type AnnotationSuperType =
| 'add-dictionary'
@ -29,8 +29,8 @@ export class AnnotationWrapper {
typeValue: string;
recategorizationType: string;
color: string;
comments: Comment[] = [];
firstTopLeftPoint: Point;
comments: IComment[] = [];
firstTopLeftPoint: IPoint;
annotationId: string;
shortContent: string;
content: string;
@ -41,7 +41,7 @@ export class AnnotationWrapper {
redaction: boolean;
status: string;
dictionaryOperation: boolean;
positions: Rectangle[];
positions: IRectangle[];
recommendationType: string;
legalBasisValue: string;
legalBasisChangeValue?: string;

View File

@ -1,10 +1,9 @@
import { RedactionLog, RedactionLogEntry } from '@redaction/red-ui-http';
import { File } from './file';
import { AnnotationWrapper } from './annotation.wrapper';
import { RedactionLogEntryWrapper } from './redaction-log-entry.wrapper';
import { ViewMode } from './view-mode';
import * as moment from 'moment';
import { Dictionary, IViewedPage, User } from '@red/domain';
import { Dictionary, IRedactionLog, IRedactionLogEntry, IViewedPage, User } from '@red/domain';
export class AnnotationData {
visibleAnnotations: AnnotationWrapper[];
@ -16,7 +15,7 @@ export class FileDataModel {
hasChangeLog: boolean;
constructor(public file: File, public fileData: Blob, public redactionLog: RedactionLog, public viewedPages?: IViewedPage[]) {}
constructor(public file: File, public fileData: Blob, public redactionLog: IRedactionLog, public viewedPages?: IViewedPage[]) {}
getAnnotations(
dictionaryData: { [p: string]: Dictionary },
@ -103,7 +102,7 @@ export class FileDataModel {
return result;
}
private _isChangeLogEntry(redactionLogEntry: RedactionLogEntry, wrapper: RedactionLogEntryWrapper) {
private _isChangeLogEntry(redactionLogEntry: IRedactionLogEntry, wrapper: RedactionLogEntryWrapper) {
if (this.file.numberOfAnalyses > 1) {
redactionLogEntry.changes.sort((a, b) => moment(a.dateTime).valueOf() - moment(b.dateTime).valueOf());

View File

@ -1,9 +1,9 @@
import { ManualRedactionEntry } from '@redaction/red-ui-http';
import { IManualRedactionEntry } from '@red/domain';
export class ManualRedactionEntryWrapper {
constructor(
readonly quads: any,
readonly manualRedactionEntry: ManualRedactionEntry,
readonly manualRedactionEntry: IManualRedactionEntry,
readonly type: 'DICTIONARY' | 'REDACTION' | 'FALSE_POSITIVE',
readonly annotationType: 'TEXT' | 'RECTANGLE' = 'TEXT',
readonly rectId?: string,

View File

@ -1,7 +1,7 @@
import { Change, Comment, ILegalBasis, Rectangle } from '@redaction/red-ui-http';
import { IChange, IComment, ILegalBasis, IRectangle } from '@red/domain';
export interface RedactionLogEntryWrapper {
changes?: Array<Change>;
changes?: Array<IChange>;
dossierDictionaryEntry?: boolean;
endOffset?: number;
excluded?: boolean;
@ -19,7 +19,7 @@ export interface RedactionLogEntryWrapper {
manual?: boolean;
manualRedactionType?: 'ADD' | 'REMOVE' | 'UNDO' | 'LEGAL_BASIS_CHANGE' | 'FORCE_REDACT' | 'RECATEGORIZE';
matchedRule?: number;
positions?: Array<Rectangle>;
positions?: Array<IRectangle>;
reason?: string;
redacted?: boolean;
section?: string;
@ -29,7 +29,7 @@ export interface RedactionLogEntryWrapper {
textBefore?: string;
value?: string;
image?: boolean;
legalBasisList?: Array<ILegalBasis>;
legalBasisList?: ILegalBasis[];
recommendation?: boolean;
recommendationAnnotationId?: string;
@ -37,7 +37,7 @@ export interface RedactionLogEntryWrapper {
hidden?: boolean;
userId?: string;
comments?: Comment[];
comments?: IComment[];
isChangeLogEntry?: boolean;
changeLogType?: 'ADDED' | 'REMOVED' | 'CHANGED';

View File

@ -1,5 +1,5 @@
import { ILegalBasis } from '@redaction/red-ui-http';
import { IListable } from '@iqser/common-ui';
import { ILegalBasis } from '@red/domain';
export class Justification implements ILegalBasis, IListable {
readonly id: string;

View File

@ -1,4 +1,4 @@
<div *ngFor="let comment of annotation.comments" class="comment">
<div *ngFor="let comment of annotation.comments; trackBy: trackBy" class="comment">
<div class="comment-details-wrapper">
<div [matTooltipPosition]="'above'" [matTooltip]="comment.date | date: 'exactDate'" class="small-label">
<strong> {{ comment.user | name }} </strong>

View File

@ -1,10 +1,10 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostBinding, Input, ViewChild } from '@angular/core';
import { Comment } from '@redaction/red-ui-http';
import { IComment } from '@red/domain';
import { ManualAnnotationService } from '../../services/manual-annotation.service';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { UserService } from '@services/user.service';
import { PermissionsService } from '@services/permissions.service';
import { InputWithActionComponent } from '@iqser/common-ui';
import { InputWithActionComponent, trackBy } from '@iqser/common-ui';
@Component({
selector: 'redaction-comments',
@ -14,6 +14,7 @@ import { InputWithActionComponent } from '@iqser/common-ui';
})
export class CommentsComponent {
@Input() annotation: AnnotationWrapper;
readonly trackBy = trackBy();
@HostBinding('class.hidden') private _hidden = true;
@ViewChild(InputWithActionComponent) private readonly _input: InputWithActionComponent;
@ -31,10 +32,10 @@ export class CommentsComponent {
this._manualAnnotationService
.addComment(value, this.annotation.id)
.toPromise()
.then(commentResponse => {
.then(commentId => {
this.annotation.comments.push({
text: value,
id: parseInt(commentResponse.commentId, 10),
id: commentId,
user: this._userService.currentUser.id,
});
this._input.reset();
@ -47,9 +48,9 @@ export class CommentsComponent {
this._hidden = !this._hidden;
}
deleteComment(comment: Comment): void {
deleteComment(comment: IComment): void {
this._manualAnnotationService
.deleteComment(`${comment.id}`, this.annotation.id)
.deleteComment(comment.id, this.annotation.id)
.toPromise()
.then(() => {
this.annotation.comments.splice(this.annotation.comments.indexOf(comment), 1);

View File

@ -11,7 +11,7 @@ import {
SimpleChanges,
ViewChild,
} from '@angular/core';
import { ManualRedactionEntry } from '@redaction/red-ui-http';
import { IManualRedactionEntry } from '@red/domain';
import WebViewer, { Core, WebViewerInstance } from '@pdftron/webviewer';
import { TranslateService } from '@ngx-translate/core';
import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper';
@ -297,7 +297,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
}
private _setSelectionMode(): void {
const textTool = (<unknown> this.instance.Core.Tools.TextTool) as TextTool;
const textTool = (<unknown>this.instance.Core.Tools.TextTool) as TextTool;
textTool.SELECTION_MODE = this._configService.values.SELECTION_MODE;
}
@ -556,8 +556,8 @@ export class PdfViewerComponent implements OnInit, OnChanges {
}
}
private _getManualRedactionEntry(quads: any, text: string, convertQuads: boolean = false): ManualRedactionEntry {
const entry: ManualRedactionEntry = { positions: [] };
private _getManualRedactionEntry(quads: any, text: string, convertQuads: boolean = false): IManualRedactionEntry {
const entry: IManualRedactionEntry = { positions: [] };
for (const key of Object.keys(quads)) {
for (const quad of quads[key]) {
const page = parseInt(key, 10);

View File

@ -1,7 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MatDialogRef } from '@angular/material/dialog';
import { ForceRedactionRequest } from '@redaction/red-ui-http';
import { Toaster } from '@iqser/common-ui';
import { TranslateService } from '@ngx-translate/core';
import { UserService } from '@services/user.service';
@ -9,6 +8,7 @@ import { ManualAnnotationService } from '../../services/manual-annotation.servic
import { PermissionsService } from '@services/permissions.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { JustificationsService } from '@services/entity-services/justifications.service';
import { ILegalBasisChangeRequest } from '@red/domain';
export interface LegalBasisOption {
label?: string;
@ -63,8 +63,8 @@ export class ForceRedactionDialogComponent implements OnInit {
this.dialogRef.close(this._createForceRedactionRequest());
}
private _createForceRedactionRequest(): ForceRedactionRequest {
const request: ForceRedactionRequest = {};
private _createForceRedactionRequest(): ILegalBasisChangeRequest {
const request: ILegalBasisChangeRequest = {};
const legalOption: LegalBasisOption = this.redactionForm.get('reason').value;

View File

@ -2,7 +2,6 @@ import { Component, Inject, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AppStateService } from '@state/app-state.service';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { AddRedactionRequest } from '@redaction/red-ui-http';
import { Toaster } from '@iqser/common-ui';
import { TranslateService } from '@ngx-translate/core';
import { UserService } from '@services/user.service';
@ -12,7 +11,7 @@ import { ManualAnnotationResponse } from '@models/file/manual-annotation-respons
import { PermissionsService } from '@services/permissions.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { JustificationsService } from '@services/entity-services/justifications.service';
import { Dictionary } from '@red/domain';
import { Dictionary, IAddRedactionRequest } from '@red/domain';
export interface LegalBasisOption {
label?: string;
@ -112,7 +111,7 @@ export class ManualAnnotationDialogComponent implements OnInit {
);
}
private _enhanceManualRedaction(addRedactionRequest: AddRedactionRequest) {
private _enhanceManualRedaction(addRedactionRequest: IAddRedactionRequest) {
const legalOption: LegalBasisOption = this.redactionForm.get('reason').value;
addRedactionRequest.type = this.redactionForm.get('dictionary').value;
if (legalOption) {

View File

@ -4,13 +4,13 @@ import { ManualAnnotationService } from './manual-annotation.service';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { Observable } from 'rxjs';
import { TranslateService } from '@ngx-translate/core';
import { AddRedactionRequest, ForceRedactionRequest } from '@redaction/red-ui-http';
import { getFirstRelevantTextPart } from '@utils/functions';
import { AnnotationPermissions } from '@models/file/annotation.permissions';
import { DossiersDialogService } from './dossiers-dialog.service';
import { BASE_HREF } from '../../../tokens';
import { UserService } from '@services/user.service';
import { Core } from '@pdftron/webviewer';
import { IAddRedactionRequest, ILegalBasisChangeRequest } from '@red/domain';
import Annotation = Core.Annotations.Annotation;
@Injectable()
@ -44,7 +44,7 @@ export class AnnotationActionsService {
}
forceRedaction($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper>) {
this._dialogService.openDialog('forceRedaction', $event, null, (request: ForceRedactionRequest) => {
this._dialogService.openDialog('forceRedaction', $event, null, (request: ILegalBasisChangeRequest) => {
annotations.forEach(annotation => {
this._processObsAndEmit(
this._manualAnnotationService.force({
@ -323,7 +323,7 @@ export class AnnotationActionsService {
) {
$event?.stopPropagation();
const falsePositiveRequest: AddRedactionRequest = {};
const falsePositiveRequest: IAddRedactionRequest = {};
falsePositiveRequest.reason = annotation.id;
falsePositiveRequest.value = text;
falsePositiveRequest.type = 'false_positive';

View File

@ -1,13 +1,14 @@
import { Injectable } from '@angular/core';
import { Core, WebViewerInstance } from '@pdftron/webviewer';
import { Rectangle, SectionGrid, SectionRectangle } from '@redaction/red-ui-http';
import { hexToRgb } from '@utils/functions';
import { AppStateService } from '@state/app-state.service';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { UserPreferenceService } from '@services/user-preference.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { RedactionLogService } from './redaction-log.service';
import { environment } from '../../../../environments/environment';
import { environment } from '@environments/environment';
import { IRectangle, ISectionGrid, ISectionRectangle } from '@red/domain';
import Annotation = Core.Annotations.Annotation;
@Injectable()
@ -39,28 +40,6 @@ export class AnnotationDrawService {
);
}
private async _drawAnnotations(
activeViewer: WebViewerInstance,
annotationWrappers: AnnotationWrapper[],
hideSkipped = false,
compareMode = false,
) {
const annotations = annotationWrappers.map(annotation =>
this._computeAnnotation(activeViewer, annotation, hideSkipped, compareMode),
);
const annotationManager = activeViewer.Core.annotationManager;
annotationManager.addAnnotations(annotations, { imported: true });
await annotationManager.drawAnnotationsFromList(annotations);
if (this._userPreferenceService.areDevFeaturesEnabled) {
const sectionsGrid = await this._redactionLogService
.getSectionGrid(this._dossiersService.activeDossierId, this._appStateService.activeFileId)
.toPromise()
.catch(() => ({ rectanglesPerPage: {} }));
await this._drawSections(activeViewer, sectionsGrid);
}
}
getColor(activeViewer: WebViewerInstance, superType: string, dictionary?: string) {
let color;
switch (superType) {
@ -96,10 +75,32 @@ export class AnnotationDrawService {
return new activeViewer.Core.Math.Quad(x1, y1, x2, y2, x3, y3, x4, y4);
}
private async _drawSections(activeViewer: WebViewerInstance, sectionGrid: SectionGrid) {
private async _drawAnnotations(
activeViewer: WebViewerInstance,
annotationWrappers: AnnotationWrapper[],
hideSkipped = false,
compareMode = false,
) {
const annotations = annotationWrappers.map(annotation =>
this._computeAnnotation(activeViewer, annotation, hideSkipped, compareMode),
);
const annotationManager = activeViewer.Core.annotationManager;
annotationManager.addAnnotations(annotations, { imported: true });
await annotationManager.drawAnnotationsFromList(annotations);
if (this._userPreferenceService.areDevFeaturesEnabled) {
const sectionsGrid = await this._redactionLogService
.getSectionGrid(this._dossiersService.activeDossierId, this._appStateService.activeFileId)
.toPromise()
.catch(() => ({ rectanglesPerPage: {} }));
await this._drawSections(activeViewer, sectionsGrid);
}
}
private async _drawSections(activeViewer: WebViewerInstance, sectionGrid: ISectionGrid) {
const sections = [];
for (const page of Object.keys(sectionGrid.rectanglesPerPage)) {
const sectionRectangles: SectionRectangle[] = sectionGrid.rectanglesPerPage[page];
const sectionRectangles = sectionGrid.rectanglesPerPage[page];
sectionRectangles.forEach(sectionRectangle => {
sections.push(this._computeSection(activeViewer, parseInt(page, 10), sectionRectangle));
// sectionRectangle.tableCells?.forEach(cell =>{
@ -112,10 +113,10 @@ export class AnnotationDrawService {
await annotationManager.drawAnnotationsFromList(sections);
}
private _computeSection(activeViewer: WebViewerInstance, pageNumber: number, sectionRectangle: SectionRectangle) {
private _computeSection(activeViewer: WebViewerInstance, pageNumber: number, sectionRectangle: ISectionRectangle) {
const rectangleAnnot = new activeViewer.Core.Annotations.RectangleAnnotation();
const pageHeight = activeViewer.Core.documentViewer.getPageHeight(pageNumber);
const rectangle = {
const rectangle: IRectangle = {
topLeft: sectionRectangle.topLeft,
page: pageNumber,
height: sectionRectangle.height,
@ -168,12 +169,12 @@ export class AnnotationDrawService {
return highlight;
}
private _rectanglesToQuads(positions: Rectangle[], activeViewer: WebViewerInstance, pageNumber: number): any[] {
private _rectanglesToQuads(positions: IRectangle[], activeViewer: WebViewerInstance, pageNumber: number): any[] {
const pageHeight = activeViewer.Core.documentViewer.getPageHeight(pageNumber);
return positions.map(p => this._rectangleToQuad(p, activeViewer, pageHeight));
}
private _rectangleToQuad(rectangle: Rectangle, activeViewer: WebViewerInstance, pageHeight: number): any {
private _rectangleToQuad(rectangle: IRectangle, activeViewer: WebViewerInstance, pageHeight: number): any {
const x1 = rectangle.topLeft.x;
const y1 = pageHeight - (rectangle.topLeft.y + rectangle.height);

View File

@ -1,19 +1,10 @@
import { Injectable, Injector } from '@angular/core';
import { AppStateService } from '@state/app-state.service';
import {
AddRedactionRequest,
ApproveRequest,
CommentResponse,
ForceRedactionRequest,
ImageRecategorizationRequest,
LegalBasisChangeRequest,
ManualAddResponse,
RemoveRedactionRequest,
} from '@redaction/red-ui-http';
import { ApproveRequest, ImageRecategorizationRequest, ManualAddResponse, RemoveRedactionRequest } from '@redaction/red-ui-http';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { CONFLICT_ERROR_CODE, ErrorMessageService, GenericService, RequiredParam, Toaster, Validate } from '@iqser/common-ui';
import { TranslateService } from '@ngx-translate/core';
import { tap } from 'rxjs/operators';
import { map, tap } from 'rxjs/operators';
import { UserService } from '@services/user.service';
import { PermissionsService } from '@services/permissions.service';
import { AnnotationActionMode } from '../models/annotation-action-mode.model';
@ -21,6 +12,7 @@ import { annotationActionsTranslations } from '../translations/annotation-action
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { HttpErrorResponse } from '@angular/common/http';
import { IAddRedactionRequest, ILegalBasisChangeRequest } from '@red/domain';
@Injectable()
export class ManualAnnotationService extends GenericService<ManualAddResponse> {
@ -87,7 +79,7 @@ export class ManualAnnotationService extends GenericService<ManualAddResponse> {
fileId = this._appStateService.activeFileId,
) {
const url = `${this._defaultModelPath}/comment/add/${dossierId}/${fileId}/${annotationId}`;
return this._post<CommentResponse>({ text: comment }, url);
return this._post<{ commentId: string }>({ text: comment }, url).pipe(map(res => res.commentId));
}
@Validate()
@ -102,7 +94,7 @@ export class ManualAnnotationService extends GenericService<ManualAddResponse> {
}
addRecommendation(annotation: AnnotationWrapper) {
const manualRedactionEntry: AddRedactionRequest = {};
const manualRedactionEntry: IAddRedactionRequest = {};
manualRedactionEntry.addToDictionary = true;
// set the ID as reason, so we can hide the suggestion
manualRedactionEntry.reason = annotation.id;
@ -132,7 +124,7 @@ export class ManualAnnotationService extends GenericService<ManualAddResponse> {
// this wraps
// /manualRedaction/redaction/add
// /manualRedaction/request/add
addAnnotation(manualRedactionEntry: AddRedactionRequest) {
addAnnotation(manualRedactionEntry: IAddRedactionRequest) {
const mode: AnnotationActionMode = this._permissionsService.isApprover() ? 'add' : 'suggest';
return this._makeRequest(mode, manualRedactionEntry, null, manualRedactionEntry.addToDictionary);
}
@ -140,7 +132,7 @@ export class ManualAnnotationService extends GenericService<ManualAddResponse> {
// this wraps
// /manualRedaction/redaction/force
// /manualRedaction/request/force
force(request: ForceRedactionRequest) {
force(request: ILegalBasisChangeRequest) {
const mode: AnnotationActionMode = this._permissionsService.isApprover() ? 'force-redaction' : 'request-force-redaction';
return this._makeRequest(mode, request);
}
@ -222,7 +214,7 @@ export class ManualAnnotationService extends GenericService<ManualAddResponse> {
}
@Validate()
addRedaction(@RequiredParam() body: AddRedactionRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
addRedaction(@RequiredParam() body: IAddRedactionRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
const url = `${this._defaultModelPath}/redaction/add/${dossierId}/${fileId}`;
return this._post(body, url);
}
@ -248,14 +240,14 @@ export class ManualAnnotationService extends GenericService<ManualAddResponse> {
}
@Validate()
legalBasisChange(@RequiredParam() body: LegalBasisChangeRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
legalBasisChange(@RequiredParam() body: ILegalBasisChangeRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
const url = `${this._defaultModelPath}/redaction/legalBasisChange/${dossierId}/${fileId}`;
return this._post(body, url);
}
@Validate()
requestLegalBasisChange(
@RequiredParam() body: LegalBasisChangeRequest,
@RequiredParam() body: ILegalBasisChangeRequest,
@RequiredParam() dossierId: string,
@RequiredParam() fileId: string,
) {
@ -303,20 +295,20 @@ export class ManualAnnotationService extends GenericService<ManualAddResponse> {
}
@Validate()
requestAddRedaction(@RequiredParam() body: AddRedactionRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
requestAddRedaction(@RequiredParam() body: IAddRedactionRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
const url = `${this._defaultModelPath}/request/add/${dossierId}/${fileId}`;
return this._post(body, url);
}
@Validate()
forceRedaction(@RequiredParam() body: ForceRedactionRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
forceRedaction(@RequiredParam() body: ILegalBasisChangeRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
const url = `${this._defaultModelPath}/redaction/force/${dossierId}/${fileId}`;
return this._post(body, url);
}
@Validate()
requestForceRedaction(
@RequiredParam() body: ForceRedactionRequest,
@RequiredParam() body: ILegalBasisChangeRequest,
@RequiredParam() dossierId: string,
@RequiredParam() fileId: string,
) {

View File

@ -1,6 +1,6 @@
import { Injectable, Injector } from '@angular/core';
import { GenericService, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
import { RedactionLog, SectionGrid } from '@redaction/red-ui-http';
import { IRedactionLog, ISectionGrid } from '@red/domain';
@Injectable({
providedIn: 'root',
@ -17,11 +17,11 @@ export class RedactionLogService extends GenericService<unknown> {
queryParams.push({ key: 'withManualRedactions', value: withManualRedactions });
}
return this._getOne<RedactionLog>([dossierId, fileId], 'redactionLog', queryParams);
return this._getOne<IRedactionLog>([dossierId, fileId], 'redactionLog', queryParams);
}
@Validate()
getSectionGrid(@RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
return this._getOne<SectionGrid>([dossierId, fileId], 'sectionGrid');
return this._getOne<ISectionGrid>([dossierId, fileId], 'sectionGrid');
}
}

View File

@ -1,8 +1,8 @@
import { ViewMode } from '@models/file/view-mode';
import { translateQuads } from '@utils/pdf-coordinates';
import { Rectangle } from '@redaction/red-ui-http';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { Core, WebViewerInstance } from '@pdftron/webviewer';
import { IRectangle } from '@red/domain';
import Annotation = Core.Annotations.Annotation;
const DISABLED_HOTKEYS = [
@ -121,7 +121,7 @@ export class PdfViewerUtils {
return translateQuads(page, rotation, quads);
}
toPosition(page: number, selectedQuad: { x1: number; x2: number; x3: number; x4: number; y4: number; y2: number }): Rectangle {
toPosition(page: number, selectedQuad: { x1: number; x2: number; x3: number; x4: number; y4: number; y2: number }): IRectangle {
const pageHeight = this._documentViewer.getPageHeight(page);
const height = selectedQuad.y2 - selectedQuad.y4;
return {

View File

@ -1,9 +1,9 @@
import { Injectable, Injector } from '@angular/core';
import { EntitiesService, RequiredParam, Validate } from '@iqser/common-ui';
import { ILegalBasis } from '@redaction/red-ui-http';
import { Justification } from '@models/justification.model';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ILegalBasis } from '@red/domain';
@Injectable({
providedIn: 'root',

View File

@ -2,8 +2,7 @@ import { Injectable } from '@angular/core';
import { AppStateService } from '@state/app-state.service';
import { UserService } from './user.service';
import { File } from '@models/file/file';
import { Comment } from '@redaction/red-ui-http';
import { Dossier } from '@red/domain';
import { Dossier, IComment } from '@red/domain';
import { DossiersService } from './entity-services/dossiers.service';
@Injectable({
@ -147,7 +146,7 @@ export class PermissionsService {
return ['UNDER_REVIEW', 'UNDER_APPROVAL'].includes(file.status) && (this.isFileReviewer(file) || this.isApprover());
}
canDeleteComment(comment: Comment, file = this._activeFile) {
canDeleteComment(comment: IComment, file = this._activeFile) {
return (comment.user === this._userService.currentUser.id || this.isApprover()) && !file.isApproved;
}
}

@ -1 +1 @@
Subproject commit defdc2af4e226ca8bb17df6c4d1cdd85130cfce5
Subproject commit 488d3d5c2cfe4396371d3c2d78c90d120641f627

View File

@ -8,3 +8,5 @@ export * from './lib/audit';
export * from './lib/notifications';
export * from './lib/dossier-templates';
export * from './lib/dictionaries';
export * from './lib/redaction-log';
export * from './lib/geometry';

View File

@ -0,0 +1,7 @@
import { IPoint } from './point';
export interface ICellRectangle {
height: number;
topLeft: IPoint;
width: number;
}

View File

@ -0,0 +1,5 @@
export * from './point';
export * from './rectangle';
export * from './cell-rectangle';
export * from './section-rectangle';
export * from './section-grid';

View File

@ -0,0 +1,4 @@
export interface IPoint {
x: number;
y: number;
}

View File

@ -0,0 +1,5 @@
import { ICellRectangle } from './cell-rectangle';
export interface IRectangle extends ICellRectangle {
page?: number;
}

View File

@ -0,0 +1,6 @@
import { ISectionRectangle } from './section-rectangle';
import { List } from '@iqser/common-ui';
export interface ISectionGrid {
rectanglesPerPage: Record<string, List<ISectionRectangle>>;
}

View File

@ -0,0 +1,8 @@
import { ICellRectangle } from './cell-rectangle';
import { List } from '@iqser/common-ui';
export interface ISectionRectangle extends ICellRectangle {
numberOfParts?: number;
part?: number;
tableCells?: List<ICellRectangle>;
}

View File

@ -0,0 +1,13 @@
import { IRectangle } from '../geometry';
import { List } from '@iqser/common-ui';
export interface IAddRedactionRequest {
addToDictionary?: boolean;
addToDossierDictionary?: boolean;
comment?: { text: string };
legalBasis?: string;
positions?: List<IRectangle>;
reason?: string;
type?: string;
value?: string;
}

View File

@ -0,0 +1,11 @@
export interface IChange {
dateTime?: string;
type?: ChangeType;
}
export const ChangeTypes = {
ADDED: 'ADDED',
CHANGED: 'CHANGED',
REMOVED: 'REMOVED',
} as const;
export type ChangeType = keyof typeof ChangeTypes;

View File

@ -0,0 +1,9 @@
export interface IComment {
id: string;
user: string;
date?: string;
text: string;
annotationId?: string;
fileId?: string;
softDeletedTime?: string;
}

View File

@ -0,0 +1,9 @@
export * from './types';
export * from './change';
export * from './comment';
export * from './legal-basis';
export * from './add-redaction.request';
export * from './manual-redaction-entry';
export * from './redaction-log-entry';
export * from './redaction-log';
export * from './legal-basis-change.request';

View File

@ -0,0 +1,5 @@
export interface ILegalBasisChangeRequest {
annotationId?: string;
comment?: string;
legalBasis?: string;
}

View File

@ -0,0 +1,5 @@
export interface ILegalBasis {
description?: string;
name?: string;
reason?: string;
}

View File

@ -0,0 +1,19 @@
import { IRectangle } from '../geometry';
import { LogEntryStatus } from './types';
export interface IManualRedactionEntry {
addToDictionary?: boolean;
addToDossierDictionary?: boolean;
annotationId?: string;
fileId?: string;
legalBasis?: string;
positions?: IRectangle[];
processedDate?: string;
reason?: string;
requestDate?: string;
softDeletedTime?: string;
status?: LogEntryStatus;
type?: string;
user?: string;
value?: string;
}

View File

@ -0,0 +1,40 @@
import { IChange } from './change';
import { IComment } from './comment';
import { IRectangle } from '../geometry';
import { LogEntryEngine, LogEntryStatus, ManualRedactionType } from './types';
import { List } from '@iqser/common-ui';
export interface IRedactionLogEntry {
changes?: IChange[];
color?: List<number>;
comments?: List<IComment>;
dictionaryEntry?: boolean;
dossierDictionaryEntry?: boolean;
endOffset?: number;
engines?: List<LogEntryEngine>;
excluded?: boolean;
hint?: boolean;
id?: string;
image?: boolean;
imageHasTransparency?: boolean;
legalBasis?: string;
legalBasisChangeValue?: string;
manual?: boolean;
manualRedactionType?: ManualRedactionType;
manualRedactionUserId?: string;
matchedRule?: number;
positions?: List<IRectangle>;
reason?: string;
recategorizationType?: string;
recommendation?: boolean;
redacted?: boolean;
reference?: List;
section?: string;
sectionNumber?: number;
startOffset?: number;
status?: LogEntryStatus;
textAfter?: string;
textBefore?: string;
type?: string;
value?: string;
}

View File

@ -0,0 +1,12 @@
import { ILegalBasis } from './legal-basis';
import { IRedactionLogEntry } from './redaction-log-entry';
export interface IRedactionLog {
analysisVersion?: number;
dictionaryVersion?: number;
dossierDictionaryVersion?: number;
legalBasis?: ILegalBasis[];
legalBasisVersion?: number;
redactionLogEntry?: IRedactionLogEntry[];
rulesVersion?: number;
}

View File

@ -0,0 +1,23 @@
export const LogEntryEngines = {
DICTIONARY: 'DICTIONARY',
NER: 'NER',
RULE: 'RULE',
};
export type LogEntryEngine = keyof typeof LogEntryEngines;
export const ManualRedactionTypes = {
ADD: 'ADD',
FORCE_REDACT: 'FORCE_REDACT',
LEGAL_BASIS_CHANGE: 'LEGAL_BASIS_CHANGE',
RECATEGORIZE: 'RECATEGORIZE',
REMOVE: 'REMOVE',
} as const;
export type ManualRedactionType = keyof typeof ManualRedactionTypes;
export const LogEntryStatuses = {
APPROVED: 'APPROVED',
DECLINED: 'DECLINED',
REQUESTED: 'REQUESTED',
} as const;
export type LogEntryStatus = keyof typeof LogEntryStatuses;

View File

@ -1,23 +0,0 @@
/**
* API Documentation for Redaction Gateway
* Description for redaction
*
* OpenAPI spec version: 1.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { Rectangle } from './rectangle';
export interface AddRedactionRequest {
addToDictionary?: boolean;
addToDossierDictionary?: boolean;
comment?: { text: string };
legalBasis?: string;
positions?: Array<Rectangle>;
reason?: string;
type?: string;
value?: string;
}

View File

@ -1,18 +0,0 @@
/**
* API Documentation for Redaction Gateway
* Description for redaction
*
* OpenAPI spec version: 1.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { Point } from './point';
export interface CellRectangle {
height?: number;
topLeft?: Point;
width?: number;
}

View File

@ -1,25 +0,0 @@
/**
* API Documentation for Redaction Gateway
* Description for redaction
*
* OpenAPI spec version: 1.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
export interface Change {
dateTime?: string;
type?: Change.TypeEnum;
}
export namespace Change {
export type TypeEnum = 'ADDED' | 'CHANGED' | 'REMOVED';
export const TypeEnum = {
ADDED: 'ADDED' as TypeEnum,
CHANGED: 'CHANGED' as TypeEnum,
REMOVED: 'REMOVED' as TypeEnum,
};
}

View File

@ -1,21 +0,0 @@
/**
* API Documentation for Redaction Gateway
* Description for redaction
*
* OpenAPI spec version: 1.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
export interface Comment {
annotationId?: string;
date?: string;
fileId?: string;
id?: number;
softDeletedTime?: string;
text?: string;
user?: string;
}

View File

@ -1,15 +0,0 @@
/**
* API Documentation for Redaction Gateway
* Description for redaction
*
* OpenAPI spec version: 1.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
export interface CommentResponse {
commentId?: string;
}

View File

@ -1,17 +0,0 @@
/**
* API Documentation for Redaction Gateway
* Description for redaction
*
* OpenAPI spec version: 1.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
export interface ForceRedactionRequest {
annotationId?: string;
comment?: string;
legalBasis?: string;
}

View File

@ -1,17 +0,0 @@
/**
* API Documentation for Redaction Gateway
* Description for redaction
*
* OpenAPI spec version: 1.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
export interface ILegalBasis {
description?: string;
name?: string;
reason?: string;
}

View File

@ -1,17 +0,0 @@
/**
* API Documentation for Redaction Gateway
* Description for redaction
*
* OpenAPI spec version: 1.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
export interface LegalBasisChangeRequest {
annotationId?: string;
comment?: string;
legalBasis?: string;
}

View File

@ -1,38 +0,0 @@
/**
* API Documentation for Redaction Gateway
* Description for redaction
*
* OpenAPI spec version: 1.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { Rectangle } from './rectangle';
export interface ManualRedactionEntry {
addToDictionary?: boolean;
addToDossierDictionary?: boolean;
annotationId?: string;
fileId?: string;
legalBasis?: string;
positions?: Array<Rectangle>;
processedDate?: string;
reason?: string;
requestDate?: string;
softDeletedTime?: string;
status?: ManualRedactionEntry.StatusEnum;
type?: string;
user?: string;
value?: string;
}
export namespace ManualRedactionEntry {
export type StatusEnum = 'APPROVED' | 'DECLINED' | 'REQUESTED';
export const StatusEnum = {
APPROVED: 'APPROVED' as StatusEnum,
DECLINED: 'DECLINED' as StatusEnum,
REQUESTED: 'REQUESTED' as StatusEnum,
};
}

View File

@ -1,11 +1,6 @@
export * from './addRedactionRequest';
export * from './approveRequest';
export * from './categoryModel';
export * from './cellRectangle';
export * from './change';
export * from './colors';
export * from './comment';
export * from './commentResponse';
export * from './createUserRequest';
export * from './digitalSignature';
export * from './digitalSignatureViewModel';
@ -17,23 +12,14 @@ export * from './fileAttributes';
export * from './fileAttributesConfig';
export * from './file';
export * from './fileUploadResult';
export * from './forceRedactionRequest';
export * from './generalConfigurationModel';
export * from './idRemoval';
export * from './imageRecategorizationRequest';
export * from './legalBasis';
export * from './legalBasisChangeRequest';
export * from './legalBasis';
export * from './licenseReport';
export * from './licenseReportRequest';
export * from './manualAddResponse';
export * from './manualRedactionEntry';
export * from './placeholdersResponse';
export * from './point';
export * from './prepareDownloadRequest';
export * from './rectangle';
export * from './redactionLog';
export * from './redactionLogEntry';
export * from './removeDownloadRequest';
export * from './removeRedactionRequest';
export * from './reportData';
@ -41,7 +27,5 @@ export * from './reportTemplate';
export * from './resetPasswordRequest';
export * from './rules';
export * from './smtp-configuration';
export * from './sectionGrid';
export * from './sectionRectangle';
export * from './updateDictionary';
export * from './watermarkModel';

View File

@ -1,16 +0,0 @@
/**
* API Documentation for Redaction Gateway
* Description for redaction
*
* OpenAPI spec version: 1.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
export interface Point {
x?: number;
y?: number;
}

View File

@ -1,19 +0,0 @@
/**
* API Documentation for Redaction Gateway
* Description for redaction
*
* OpenAPI spec version: 1.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { Point } from './point';
export interface Rectangle {
height?: number;
page?: number;
topLeft?: Point;
width?: number;
}

View File

@ -1,23 +0,0 @@
/**
* API Documentation for Redaction Gateway
* Description for redaction
*
* OpenAPI spec version: 1.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { ILegalBasis } from './legalBasis';
import { RedactionLogEntry } from './redactionLogEntry';
export interface RedactionLog {
analysisVersion?: number;
dictionaryVersion?: number;
dossierDictionaryVersion?: number;
legalBasis?: Array<ILegalBasis>;
legalBasisVersion?: number;
redactionLogEntry?: Array<RedactionLogEntry>;
rulesVersion?: number;
}

View File

@ -1,73 +0,0 @@
/**
* API Documentation for Redaction Gateway
* Description for redaction
*
* OpenAPI spec version: 1.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { Change } from './change';
import { Comment } from './comment';
import { Rectangle } from './rectangle';
export interface RedactionLogEntry {
changes?: Array<Change>;
color?: Array<number>;
comments?: Array<Comment>;
dictionaryEntry?: boolean;
dossierDictionaryEntry?: boolean;
endOffset?: number;
engines?: Array<LogEntryEngine>;
excluded?: boolean;
hint?: boolean;
id?: string;
image?: boolean;
imageHasTransparency?: boolean;
legalBasis?: string;
legalBasisChangeValue?: string;
manual?: boolean;
manualRedactionType?: ManualRedactionType;
manualRedactionUserId?: string;
matchedRule?: number;
positions?: Array<Rectangle>;
reason?: string;
recategorizationType?: string;
recommendation?: boolean;
redacted?: boolean;
reference?: Array<string>;
section?: string;
sectionNumber?: number;
startOffset?: number;
status?: LogEntryStatus;
textAfter?: string;
textBefore?: string;
type?: string;
value?: string;
}
export const LogEntryEngines = {
DICTIONARY: 'DICTIONARY',
NER: 'NER',
RULE: 'RULE',
};
export type LogEntryEngine = keyof typeof LogEntryEngines;
export const ManualRedactionTypes = {
ADD: 'ADD',
FORCE_REDACT: 'FORCE_REDACT',
LEGAL_BASIS_CHANGE: 'LEGAL_BASIS_CHANGE',
RECATEGORIZE: 'RECATEGORIZE',
REMOVE: 'REMOVE',
} as const;
export type ManualRedactionType = keyof typeof ManualRedactionTypes;
export const LogEntryStatuses = {
APPROVED: 'APPROVED',
DECLINED: 'DECLINED',
REQUESTED: 'REQUESTED',
} as const;
export type LogEntryStatus = keyof typeof LogEntryStatuses;

View File

@ -1,16 +0,0 @@
/**
* API Documentation for Redaction Gateway
* Description for redaction
*
* OpenAPI spec version: 1.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { SectionRectangle } from './sectionRectangle';
export interface SectionGrid {
rectanglesPerPage?: { [key: string]: Array<SectionRectangle> };
}

View File

@ -1,22 +0,0 @@
/**
* API Documentation for Redaction Gateway
* Description for redaction
*
* OpenAPI spec version: 1.0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { CellRectangle } from './cellRectangle';
import { Point } from './point';
export interface SectionRectangle {
height?: number;
numberOfParts?: number;
part?: number;
tableCells?: Array<CellRectangle>;
topLeft?: Point;
width?: number;
}