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 7c2876e8f..51a75e509 100644
--- a/apps/red-ui/src/app/models/file/annotation.wrapper.ts
+++ b/apps/red-ui/src/app/models/file/annotation.wrapper.ts
@@ -58,6 +58,12 @@ export class AnnotationWrapper {
changeLogType?: 'ADDED' | 'REMOVED' | 'CHANGED';
engines?: string[];
+ hasBeenResized: boolean;
+ hasBeenRecategorized: boolean;
+ hasLegalBasisChanged: boolean;
+ hasBeenForced: boolean;
+ hasBeenRemovedByManualOverride: boolean;
+
private _origin: RedactionLogEntryWrapper;
get isChangeLogRemoved() {
@@ -169,6 +175,16 @@ export class AnnotationWrapper {
return this.dictionaryOperation;
}
+ get hasRedactionChanges(): boolean {
+ return (
+ this.hasBeenResized ||
+ this.hasBeenRecategorized ||
+ this.hasLegalBasisChanged ||
+ this.hasBeenForced ||
+ this.hasBeenRemovedByManualOverride
+ );
+ }
+
get isConvertedRecommendation() {
return this.isRecommendation && this.superType === 'suggestion-add-dictionary';
}
@@ -221,6 +237,11 @@ export class AnnotationWrapper {
annotationWrapper.engines = redactionLogEntry.engines;
annotationWrapper.section = redactionLogEntry.section;
annotationWrapper.rectangle = redactionLogEntry.rectangle;
+ annotationWrapper.hasBeenResized = redactionLogEntry.hasBeenResized;
+ annotationWrapper.hasBeenRecategorized = redactionLogEntry.hasBeenRecategorized;
+ annotationWrapper.hasLegalBasisChanged = redactionLogEntry.hasLegalBasisChanged;
+ annotationWrapper.hasBeenForced = redactionLogEntry.hasBeenForced;
+ annotationWrapper.hasBeenRemovedByManualOverride = redactionLogEntry.hasBeenRemovedByManualOverride;
this._createContent(annotationWrapper, redactionLogEntry);
this._setSuperType(annotationWrapper, redactionLogEntry);
diff --git a/apps/red-ui/src/app/models/file/redaction-log-entry.wrapper.ts b/apps/red-ui/src/app/models/file/redaction-log-entry.wrapper.ts
index 9dc800a87..f3bcacbd8 100644
--- a/apps/red-ui/src/app/models/file/redaction-log-entry.wrapper.ts
+++ b/apps/red-ui/src/app/models/file/redaction-log-entry.wrapper.ts
@@ -46,4 +46,10 @@ export interface RedactionLogEntryWrapper {
recategorizationType?: string;
legalBasisChangeValue?: string;
engines?: string[];
+
+ hasBeenResized?: boolean;
+ hasBeenRecategorized?: boolean;
+ hasLegalBasisChanged?: boolean;
+ hasBeenForced?: boolean;
+ hasBeenRemovedByManualOverride?: boolean;
}
diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-source/annotation-source.component.html b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-details/annotation-details.component.html
similarity index 69%
rename from apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-source/annotation-source.component.html
rename to apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-details/annotation-details.component.html
index 766e23aa6..01bdc134e 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-source/annotation-source.component.html
+++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-details/annotation-details.component.html
@@ -1,15 +1,19 @@
+
+
+
+
-
+
diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-source/annotation-source.component.scss b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-details/annotation-details.component.scss
similarity index 85%
rename from apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-source/annotation-source.component.scss
rename to apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-details/annotation-details.component.scss
index c731a1878..d8356a43f 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-source/annotation-source.component.scss
+++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-details/annotation-details.component.scss
@@ -1,5 +1,12 @@
@use '../../../../../../../assets/styles/variables';
+:host {
+ display: flex;
+ position: absolute;
+ top: 6px;
+ right: 8px;
+}
+
.popover {
width: 260px;
padding: 10px;
@@ -44,6 +51,10 @@
margin-right: 8px;
}
}
+
+ &:not(:last-child) {
+ margin-right: 2px;
+ }
}
mat-icon {
diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-details/annotation-details.component.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-details/annotation-details.component.ts
new file mode 100644
index 000000000..745b6212a
--- /dev/null
+++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-details/annotation-details.component.ts
@@ -0,0 +1,89 @@
+import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core';
+import { AnnotationWrapper } from '@models/file/annotation.wrapper';
+import { TranslateService } from '@ngx-translate/core';
+import { annotationChangesTranslations } from '../../../../../../translations/annotation-changes-translations';
+import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
+
+interface Engine {
+ readonly icon: string;
+ readonly description: string;
+ readonly show: boolean;
+}
+
+const Engines = {
+ DICTIONARY: 'DICTIONARY',
+ NER: 'NER',
+ RULE: 'RULE',
+} as const;
+
+type EngineName = keyof typeof Engines;
+
+@Component({
+ selector: 'redaction-annotation-details',
+ templateUrl: './annotation-details.component.html',
+ styleUrls: ['./annotation-details.component.scss'],
+ changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class AnnotationDetailsComponent implements OnChanges {
+ @Input() annotation: AnnotationWrapper;
+
+ isPopoverOpen = false;
+ hasEnginesToShow: boolean;
+ engines: readonly Engine[];
+
+ hasChangesToShow: boolean;
+ changesTooltip: string;
+
+ constructor(private readonly _translateService: TranslateService) {}
+
+ ngOnChanges(changes: SimpleChanges) {
+ if (changes.annotation) {
+ this._updateChanges();
+ this._updateEngines();
+ }
+ }
+
+ private _updateChanges(): void {
+ const changesProperties = [
+ 'hasBeenResized',
+ 'hasBeenRecategorized',
+ 'hasLegalBasisChanged',
+ 'hasBeenForced',
+ 'hasBeenRemovedByManualOverride',
+ ];
+ const changes = changesProperties.filter(key => this.annotation[key]);
+ const header = this._translateService.instant(_('annotation-changes.header'));
+ const details = changes
+ .map(change => this._translateService.instant(annotationChangesTranslations[change]))
+ .map(change => `• ${change}`);
+ this.changesTooltip = [header, ...details].join('\n');
+
+ this.hasChangesToShow = changes.length > 0;
+ }
+
+ private _updateEngines(): void {
+ this.engines = [
+ {
+ icon: 'red:dictionary',
+ description: this._translateService.instant('annotation-engines.dictionary', { isHint: this.annotation.hint }),
+ show: this._isBasedOn(Engines.DICTIONARY),
+ },
+ {
+ icon: 'red:ai',
+ description: this._translateService.instant('annotation-engines.ner'),
+ show: this._isBasedOn(Engines.NER),
+ },
+ {
+ icon: 'red:rule',
+ description: this._translateService.instant('annotation-engines.rule', { rule: this.annotation.legalBasisValue }),
+ show: this._isBasedOn(Engines.RULE),
+ },
+ ];
+
+ this.hasEnginesToShow = this.engines.length && this.engines.some(source => source.show);
+ }
+
+ private _isBasedOn(engineName: EngineName) {
+ return !!this.annotation.engines?.includes(engineName);
+ }
+}
diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-source/annotation-source.component.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-source/annotation-source.component.ts
deleted file mode 100644
index 434b1dd03..000000000
--- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotation-source/annotation-source.component.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
-import { AnnotationWrapper } from '@models/file/annotation.wrapper';
-import { OnChange } from '@iqser/common-ui';
-import { TranslateService } from '@ngx-translate/core';
-
-interface Engine {
- readonly icon: string;
- readonly description: string;
- readonly show: boolean;
-}
-
-const Engines = {
- DICTIONARY: 'DICTIONARY',
- NER: 'NER',
- RULE: 'RULE',
-} as const;
-
-type EngineName = keyof typeof Engines;
-
-@Component({
- selector: 'redaction-annotation-source',
- templateUrl: './annotation-source.component.html',
- styleUrls: ['./annotation-source.component.scss'],
- changeDetection: ChangeDetectionStrategy.OnPush,
-})
-export class AnnotationSourceComponent {
- @Input()
- @OnChange('updateEngines')
- annotation: AnnotationWrapper;
-
- isPopoverOpen = false;
- engines: readonly Engine[];
-
- constructor(private readonly _translateService: TranslateService) {}
-
- get hasEnginesToShow(): boolean {
- return this.engines.length && this.engines.some(source => source.show);
- }
-
- updateEngines(): void {
- this.engines = [
- {
- icon: 'red:dictionary',
- description: this._translateService.instant('annotation-engines.dictionary', { isHint: this.annotation.hint }),
- show: this._isBasedOn(Engines.DICTIONARY),
- },
- {
- icon: 'red:ai',
- description: this._translateService.instant('annotation-engines.ner'),
- show: this._isBasedOn(Engines.NER),
- },
- {
- icon: 'red:rule',
- description: this._translateService.instant('annotation-engines.rule', { rule: this.annotation.legalBasisValue }),
- show: this._isBasedOn(Engines.RULE),
- },
- ];
- }
-
- private _isBasedOn(engineName: EngineName) {
- return !!this.annotation.engines?.includes(engineName);
- }
-}
diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotations-list/annotations-list.component.html b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotations-list/annotations-list.component.html
index b4a0acb70..368df6874 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotations-list/annotations-list.component.html
+++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotations-list/annotations-list.component.html
@@ -4,8 +4,8 @@
[attr.annotation-id]="annotation.id"
[attr.annotation-page]="activeViewerPage"
[class.active]="isSelected(annotation.annotationId)"
- [class.multi-select-active]="multiSelectService.active$ | async"
[class.help-mode]="helpModeService.isHelpModeActive$ | async"
+ [class.multi-select-active]="multiSelectService.active$ | async"
class="annotation-wrapper"
>
@@ -59,5 +59,5 @@
-
+
diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotations-list/annotations-list.component.scss b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotations-list/annotations-list.component.scss
index c9df84618..e159e24af 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotations-list/annotations-list.component.scss
+++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/annotations-list/annotations-list.component.scss
@@ -90,9 +90,3 @@
}
}
}
-
-redaction-annotation-source {
- position: absolute;
- top: 6px;
- right: 8px;
-}
diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview.module.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview.module.ts
index 1943e4aae..6e9c902ae 100644
--- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview.module.ts
+++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview.module.ts
@@ -7,7 +7,7 @@ import { SharedModule } from '@shared/shared.module';
import { SharedDossiersModule } from '../../shared/shared-dossiers.module';
import { FilePreviewScreenComponent } from './file-preview-screen.component';
import { FileWorkloadComponent } from './components/file-workload/file-workload.component';
-import { AnnotationSourceComponent } from './components/annotation-source/annotation-source.component';
+import { AnnotationDetailsComponent } from './components/annotation-details/annotation-details.component';
import { AnnotationsListComponent } from './components/annotations-list/annotations-list.component';
import { PageIndicatorComponent } from './components/page-indicator/page-indicator.component';
import { PageExclusionComponent } from './components/page-exclusion/page-exclusion.component';
@@ -33,7 +33,7 @@ const routes: Routes = [
declarations: [
FilePreviewScreenComponent,
FileWorkloadComponent,
- AnnotationSourceComponent,
+ AnnotationDetailsComponent,
AnnotationsListComponent,
PageIndicatorComponent,
PageExclusionComponent,
diff --git a/apps/red-ui/src/app/modules/dossier/services/annotation-processing.service.ts b/apps/red-ui/src/app/modules/dossier/services/annotation-processing.service.ts
index 4c4ac1f28..a8c467bd8 100644
--- a/apps/red-ui/src/app/modules/dossier/services/annotation-processing.service.ts
+++ b/apps/red-ui/src/app/modules/dossier/services/annotation-processing.service.ts
@@ -19,12 +19,12 @@ export class AnnotationProcessingService {
checker: (annotation: AnnotationWrapper) => annotation?.comments?.length > 0,
},
{
- id: 'with-reason-changes',
- icon: 'red:reason',
- label: _('filter-menu.with-reason-changes'),
+ id: 'redaction-changes',
+ icon: 'red:redaction-changes',
+ label: _('filter-menu.redaction-changes'),
checked: false,
topLevelFilter: true,
- checker: (annotation: AnnotationWrapper) => annotation?.legalBasisChangeValue?.length > 0,
+ checker: (annotation: AnnotationWrapper) => annotation?.hasRedactionChanges,
},
{
id: 'unseen-pages',
diff --git a/apps/red-ui/src/app/modules/icons/icons.module.ts b/apps/red-ui/src/app/modules/icons/icons.module.ts
index 2448bfd6a..0945fd73e 100644
--- a/apps/red-ui/src/app/modules/icons/icons.module.ts
+++ b/apps/red-ui/src/app/modules/icons/icons.module.ts
@@ -50,6 +50,7 @@ export class IconsModule {
'ready-for-approval',
'reanalyse',
'reason',
+ 'redaction-changes',
'remove-from-dict',
'report',
'resize',
diff --git a/apps/red-ui/src/app/translations/annotation-changes-translations.ts b/apps/red-ui/src/app/translations/annotation-changes-translations.ts
new file mode 100644
index 000000000..7bd481fa1
--- /dev/null
+++ b/apps/red-ui/src/app/translations/annotation-changes-translations.ts
@@ -0,0 +1,11 @@
+import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
+import { AnnotationWrapper } from '../models/file/annotation.wrapper';
+import { KeysOf } from '@iqser/common-ui';
+
+export const annotationChangesTranslations: { [key in KeysOf]?: string } = {
+ hasBeenResized: _('annotation-changes.resized'),
+ hasBeenRecategorized: _('annotation-changes.recategorized'),
+ hasLegalBasisChanged: _('annotation-changes.legal-basis'),
+ hasBeenForced: _('annotation-changes.forced'),
+ hasBeenRemovedByManualOverride: _('annotation-changes.removed-manual'),
+} as const;
diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json
index aeec13bf8..ad7d27030 100644
--- a/apps/red-ui/src/assets/i18n/en.json
+++ b/apps/red-ui/src/assets/i18n/en.json
@@ -261,6 +261,14 @@
"show": "Show",
"undo": "Undo"
},
+ "annotation-changes": {
+ "forced": "Redaction forced",
+ "header": "Manual changes:",
+ "legal-basis": "Reason changed",
+ "recategorized": "Image category changed",
+ "removed-manual": "Redaction/Hint removed",
+ "resized": "Redaction area has been modified"
+ },
"annotation-engines": {
"dictionary": "{isHint, select, true{Hint} other{Redaction}} based on dictionary",
"ner": "Redaction based on AI",
@@ -1111,9 +1119,9 @@
"filter-options": "Filter options",
"filter-types": "Filter",
"label": "Filter",
+ "redaction-changes": "Only annotations with redaction changes",
"unseen-pages": "Only annotations on unseen pages",
- "with-comments": "Only annotations with comments",
- "with-reason-changes": "Only redactions with reason changes"
+ "with-comments": "Only annotations with comments"
},
"filter": {
"analysis": "Analysis pending",
diff --git a/apps/red-ui/src/assets/icons/general/redaction-changes.svg b/apps/red-ui/src/assets/icons/general/redaction-changes.svg
new file mode 100644
index 000000000..4e00eeffe
--- /dev/null
+++ b/apps/red-ui/src/assets/icons/general/redaction-changes.svg
@@ -0,0 +1,10 @@
+
+