diff --git a/apps/red-ui/src/app/models/file/annotation.wrapper.ts b/apps/red-ui/src/app/models/file/annotation.wrapper.ts
index f6ebdd5f3..a576bfbfe 100644
--- a/apps/red-ui/src/app/models/file/annotation.wrapper.ts
+++ b/apps/red-ui/src/app/models/file/annotation.wrapper.ts
@@ -9,8 +9,10 @@ import {
Dictionary,
Earmark,
EntityTypes,
+ EntryState,
EntryStates,
FalsePositiveSuperTypes,
+ IEntityLog,
IEntityLogEntry,
ILegalBasis,
IPoint,
@@ -209,6 +211,7 @@ export class AnnotationWrapper implements IListable {
static fromData(
logEntry: IEntityLogEntry,
+ allLogEntries: IEntityLogEntry[],
dictionary: Dictionary,
changeLogType: ChangeType,
legalBasisList: ILegalBasis[],
@@ -268,7 +271,13 @@ export class AnnotationWrapper implements IListable {
const lastRelevantManualChange = logEntry.manualChanges?.at(-1);
annotationWrapper.lastManualChange = lastRelevantManualChange?.manualRedactionType;
- annotationWrapper.pending = lastRelevantManualChange && !lastRelevantManualChange.processed;
+ annotationWrapper.pending = logEntry.state === EntryStates.PENDING;
+ if (annotationWrapper.pending) {
+ const removedEntry = allLogEntries.find(
+ (e: IEntityLogEntry) => e.id === annotationWrapper.id && e.state === EntryStates.REMOVED,
+ );
+ logEntry.oldState = removedEntry?.state;
+ }
annotationWrapper.superType = SuperTypeMapper[logEntry.entryType][logEntry.state](logEntry);
annotationWrapper.superTypeLabel = annotationTypesTranslations[annotationWrapper.superType];
@@ -277,9 +286,13 @@ export class AnnotationWrapper implements IListable {
annotationWrapper.typeLabel = dictionary?.virtual ? undefined : dictionary?.label;
- const colorKey = annotationEntityColorConfig[annotationWrapper.superType];
- const defaultColor = annotationDefaultColorConfig[annotationWrapper.superType];
- annotationWrapper.color = dictionary ? (dictionary[colorKey] as string) : (defaultColors[defaultColor] as string);
+ if (annotationWrapper.pending) {
+ annotationWrapper.color = defaultColors[annotationDefaultColorConfig.analysis] as string;
+ } else {
+ const colorKey = annotationEntityColorConfig[annotationWrapper.superType];
+ const defaultColor = annotationDefaultColorConfig[annotationWrapper.superType];
+ annotationWrapper.color = dictionary ? (dictionary[colorKey] as string) : (defaultColors[defaultColor] as string);
+ }
annotationWrapper['entry'] = logEntry;
return annotationWrapper;
diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotation-card/annotation-card.component.html b/apps/red-ui/src/app/modules/file-preview/components/annotation-card/annotation-card.component.html
index 99c2ed520..50a482417 100644
--- a/apps/red-ui/src/app/modules/file-preview/components/annotation-card/annotation-card.component.html
+++ b/apps/red-ui/src/app/modules/file-preview/components/annotation-card/annotation-card.component.html
@@ -10,7 +10,7 @@
{{ annotation.superTypeLabel | translate }}
-
+
{{ 'annotation.pending' | translate }}
diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotation-card/annotation-card.component.ts b/apps/red-ui/src/app/modules/file-preview/components/annotation-card/annotation-card.component.ts
index f62a1a538..322593075 100644
--- a/apps/red-ui/src/app/modules/file-preview/components/annotation-card/annotation-card.component.ts
+++ b/apps/red-ui/src/app/modules/file-preview/components/annotation-card/annotation-card.component.ts
@@ -18,17 +18,4 @@ export class AnnotationCardComponent {
@Input() isSelected = false;
constructor(readonly multiSelectService: MultiSelectService) {}
-
- get pending() {
- return (
- this.annotation.pending &&
- ((this.annotation.isModifyDictionary &&
- !this.annotation.isRemovedLocally &&
- !this.annotation.hasBeenForcedHint &&
- this.annotation.lastManualChange !== ManualRedactionTypes.LEGAL_BASIS_CHANGE &&
- this.annotation.lastManualChange !== ManualRedactionTypes.RESIZE_LOCALLY) ||
- this.annotation.type === ImageCategory.SIGNATURE ||
- this.annotation.IMAGE_HINT)
- );
- }
}
diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotation-details/annotation-details.component.scss b/apps/red-ui/src/app/modules/file-preview/components/annotation-details/annotation-details.component.scss
index 1110e38ca..8a2928722 100644
--- a/apps/red-ui/src/app/modules/file-preview/components/annotation-details/annotation-details.component.scss
+++ b/apps/red-ui/src/app/modules/file-preview/components/annotation-details/annotation-details.component.scss
@@ -6,7 +6,6 @@
}
.popover {
- width: 260px;
padding: 10px;
border-radius: 3px;
background-color: var(--iqser-grey-1);
diff --git a/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts b/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts
index 40599598d..2f51ba0c8 100644
--- a/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts
+++ b/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts
@@ -229,6 +229,7 @@ export class FileDataService extends EntitiesService= 0; i--) {
+ points.push(this.#bottomLeft(positions[i], pageHeight));
+ points.push(this.#topLeft(positions[i], pageHeight));
+ }
+
+ points.push(this.#topRight(positions[0], pageHeight));
+ return points;
+ }
+
+ #topLeft(rectangle: IRectangle, pageHeight: number): IPoint {
+ const x = rectangle.topLeft.x;
+ const y = pageHeight - (rectangle.topLeft.y + rectangle.height);
+ return { x, y };
+ }
+
+ #topRight(rectangle: IRectangle, pageHeight: number): IPoint {
+ const x = rectangle.topLeft.x + rectangle.width;
+ const y = pageHeight - (rectangle.topLeft.y + rectangle.height);
+ return { x, y };
+ }
+
+ #bottomRight(rectangle: IRectangle, pageHeight: number): IPoint {
+ const x = rectangle.topLeft.x + rectangle.width;
+ const y = pageHeight - rectangle.topLeft.y;
+ return { x, y };
+ }
+
+ #bottomLeft(rectangle: IRectangle, pageHeight: number): IPoint {
+ const x = rectangle.topLeft.x;
+ const y = pageHeight - rectangle.topLeft.y;
+ return { x, y };
+ }
}
diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts
index 90da413ac..09fc4f9a7 100644
--- a/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts
+++ b/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts
@@ -243,6 +243,10 @@ export class PdfViewer {
return new this.#instance.Core.Annotations.TextHighlightAnnotation();
}
+ polyline() {
+ return new this.#instance.Core.Annotations.PolylineAnnotation();
+ }
+
isTextHighlight(annotation: Annotation): annotation is TextHighlightAnnotation {
return annotation instanceof this.#instance.Core.Annotations.TextHighlightAnnotation;
}
diff --git a/libs/common-ui b/libs/common-ui
index 3ea4e45b8..ecf9c8912 160000
--- a/libs/common-ui
+++ b/libs/common-ui
@@ -1 +1 @@
-Subproject commit 3ea4e45b87b94868370492c475864390d984f65d
+Subproject commit ecf9c8912e366fdcc0a454d112c0f3252245666a
diff --git a/libs/red-domain/src/lib/files/super-types.ts b/libs/red-domain/src/lib/files/super-types.ts
index 27412a27e..02f2c80db 100644
--- a/libs/red-domain/src/lib/files/super-types.ts
+++ b/libs/red-domain/src/lib/files/super-types.ts
@@ -19,18 +19,15 @@ function wrongSuperTypeHandler(): never | undefined {
}
function resolveRedactionType(entry: IEntityLogEntry, hint = false) {
+ if (entry.state === EntryStates.PENDING && entry.oldState) {
+ return SuperTypeMapper[entry.entryType][entry.oldState](entry);
+ }
+
const redaction = hint ? SuperTypes.Hint : SuperTypes.Redaction;
const manualRedaction = hint ? SuperTypes.ManualHint : SuperTypes.ManualRedaction;
- const manualChanges = entry.manualChanges;
- const hasEngines = entry.engines.length;
- const lastRelevantManualChange = manualChanges?.at(-1);
- if (!!lastRelevantManualChange && !hasEngines) {
- const pending = lastRelevantManualChange && !lastRelevantManualChange.processed;
- if (pending && entry.dictionaryEntry) {
- return redaction;
- }
- return manualRedaction;
+ if (!entry.engines.length) {
+ return entry.state === EntryStates.PENDING && entry.dictionaryEntry ? redaction : manualRedaction;
}
return redaction;
}
@@ -44,48 +41,56 @@ export const SuperTypeMapper: Record SuperTypes.Skipped,
[EntryStates.IGNORED]: () => SuperTypes.Skipped,
[EntryStates.REMOVED]: wrongSuperTypeHandler,
+ [EntryStates.PENDING]: entry => resolveRedactionType(entry),
},
[EntityTypes.HINT]: {
[EntryStates.APPLIED]: wrongSuperTypeHandler,
[EntryStates.SKIPPED]: entry => resolveRedactionType(entry, true),
[EntryStates.IGNORED]: () => SuperTypes.IgnoredHint,
[EntryStates.REMOVED]: wrongSuperTypeHandler,
+ [EntryStates.PENDING]: entry => resolveRedactionType(entry),
},
[EntityTypes.FALSE_POSITIVE]: {
[EntryStates.APPLIED]: wrongSuperTypeHandler,
[EntryStates.SKIPPED]: wrongSuperTypeHandler,
[EntryStates.IGNORED]: wrongSuperTypeHandler,
[EntryStates.REMOVED]: wrongSuperTypeHandler,
+ [EntryStates.PENDING]: entry => resolveRedactionType(entry),
},
[EntityTypes.RECOMMENDATION]: {
[EntryStates.APPLIED]: wrongSuperTypeHandler,
[EntryStates.SKIPPED]: () => SuperTypes.Recommendation,
[EntryStates.IGNORED]: wrongSuperTypeHandler,
[EntryStates.REMOVED]: wrongSuperTypeHandler,
+ [EntryStates.PENDING]: entry => resolveRedactionType(entry),
},
[EntityTypes.FALSE_RECOMMENDATION]: {
[EntryStates.APPLIED]: wrongSuperTypeHandler,
[EntryStates.SKIPPED]: wrongSuperTypeHandler,
[EntryStates.IGNORED]: wrongSuperTypeHandler,
[EntryStates.REMOVED]: wrongSuperTypeHandler,
+ [EntryStates.PENDING]: entry => resolveRedactionType(entry),
},
[EntityTypes.AREA]: {
[EntryStates.APPLIED]: () => SuperTypes.Redaction,
[EntryStates.SKIPPED]: wrongSuperTypeHandler,
[EntryStates.IGNORED]: wrongSuperTypeHandler,
[EntryStates.REMOVED]: wrongSuperTypeHandler,
+ [EntryStates.PENDING]: entry => resolveRedactionType(entry),
},
[EntityTypes.IMAGE]: {
[EntryStates.APPLIED]: () => SuperTypes.Redaction,
[EntryStates.SKIPPED]: () => SuperTypes.Skipped,
[EntryStates.IGNORED]: () => SuperTypes.Skipped,
[EntryStates.REMOVED]: wrongSuperTypeHandler,
+ [EntryStates.PENDING]: entry => resolveRedactionType(entry),
},
[EntityTypes.IMAGE_HINT]: {
[EntryStates.APPLIED]: wrongSuperTypeHandler,
[EntryStates.SKIPPED]: () => SuperTypes.Hint,
[EntryStates.IGNORED]: () => SuperTypes.IgnoredHint,
[EntryStates.REMOVED]: wrongSuperTypeHandler,
+ [EntryStates.PENDING]: entry => resolveRedactionType(entry),
},
};
diff --git a/libs/red-domain/src/lib/redaction-log/entity-log-entry.ts b/libs/red-domain/src/lib/redaction-log/entity-log-entry.ts
index 21d94933f..2efa68491 100644
--- a/libs/red-domain/src/lib/redaction-log/entity-log-entry.ts
+++ b/libs/red-domain/src/lib/redaction-log/entity-log-entry.ts
@@ -14,6 +14,7 @@ export interface IEntityLogEntry extends ITrackable {
type: string;
entryType: EntityType;
state: EntryState;
+ oldState?: EntryState;
value: string;
reason: string;
matchedRule: string;
diff --git a/libs/red-domain/src/lib/redaction-log/entity-states.ts b/libs/red-domain/src/lib/redaction-log/entity-states.ts
index 2507f1bdb..60725eef0 100644
--- a/libs/red-domain/src/lib/redaction-log/entity-states.ts
+++ b/libs/red-domain/src/lib/redaction-log/entity-states.ts
@@ -3,6 +3,7 @@ export const EntryStates = {
SKIPPED: 'SKIPPED',
IGNORED: 'IGNORED',
REMOVED: 'REMOVED',
+ PENDING: 'PENDING',
} as const;
export type EntryState = (typeof EntryStates)[keyof typeof EntryStates];