From 9921e868bc84395ffa5abda4cdab2c86422b2b7d Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Tue, 3 Sep 2024 12:24:04 +0300 Subject: [PATCH 001/125] RED-9950: removed more margins. --- .../editable-structured-component-value.component.scss | 6 +++--- .../structured-component-management.component.scss | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/editable-structured-component-value/editable-structured-component-value.component.scss b/apps/red-ui/src/app/modules/file-preview/components/editable-structured-component-value/editable-structured-component-value.component.scss index 0246ffeb3..4f296a8f1 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/editable-structured-component-value/editable-structured-component-value.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/components/editable-structured-component-value/editable-structured-component-value.component.scss @@ -2,7 +2,7 @@ display: flex; flex-direction: row; padding: 10px 0 10px 0; - margin-left: 26px; + margin-left: 14px; margin-right: 26px; position: relative; @@ -78,7 +78,7 @@ &:hover { .component { - margin-left: 26px; + margin-left: 14px; } .value { @@ -94,7 +94,7 @@ border-left: 4px solid var(--iqser-primary); .component { - margin-left: 22px; + margin-left: 10px; } .arrow-right { diff --git a/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.scss b/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.scss index 282b13568..783169c29 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.scss @@ -31,11 +31,10 @@ mat-icon { display: flex; flex-direction: column; margin-left: 13px; - margin-right: 13px; .header { display: flex; - padding: 10px 26px; + padding: 10px 14px; font-weight: 600; :first-child { @@ -48,6 +47,7 @@ mat-icon { border-bottom: 1px solid var(--iqser-separator); } border-bottom: 1px solid var(--iqser-separator); + margin-right: 13px; } } } From e81e8e7252358afffef1ba83d4fdb1abb5f90029 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Tue, 3 Sep 2024 13:34:48 +0300 Subject: [PATCH 002/125] RED-9454 - Differences between Add Hint- and Add Redaction-Dialog --- .../add-hint-dialog.component.html | 53 ++++++++++++++- .../add-hint-dialog.component.scss | 66 ++++++++++++++++++- .../add-hint-dialog.component.ts | 27 +++++++- 3 files changed, 140 insertions(+), 6 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/add-hint-dialog/add-hint-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/add-hint-dialog/add-hint-dialog.component.html index 3d4c41376..62cb27b02 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/add-hint-dialog/add-hint-dialog.component.html +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/add-hint-dialog/add-hint-dialog.component.html @@ -3,9 +3,56 @@
-
- - {{ form.get('selectedText').value }} +
+
+
+ +
+ + + + + + +
+
+
div { + gap: 0.5rem; + + span { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } +} + +iqser-circle-button { + padding-left: 10px; + + &.undo-button { + margin-left: 8px; + } + + ::ng-deep mat-icon { + padding: 2px; + } +} + +.w-full { + width: 100%; +} + +.fixed-height-36 { + min-height: 36px; +} + +textarea[name='value'] { + margin-top: 0; + min-height: 0; + line-height: 1; +} + +.table { + display: flex; + flex-direction: column; + min-width: calc(100% - 26px); + padding: 0 13px; + + label { + opacity: 0.7; + font-weight: normal; + } + + .row { + display: inline-flex; + flex-direction: row; + align-items: center; + background-color: var(--iqser-alt-background); + min-width: 100%; + + span { + white-space: nowrap; + text-overflow: ellipsis; + list-style-position: inside; + overflow: hidden; + } + } } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/add-hint-dialog/add-hint-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/add-hint-dialog/add-hint-dialog.component.ts index 57065e3c2..92258751a 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/add-hint-dialog/add-hint-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/add-hint-dialog/add-hint-dialog.component.ts @@ -1,4 +1,4 @@ -import { NgForOf, NgIf } from '@angular/common'; +import { NgClass, NgForOf, NgIf, NgStyle } from '@angular/common'; import { Component, OnInit } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormBuilder, ReactiveFormsModule, UntypedFormGroup } from '@angular/forms'; @@ -23,12 +23,14 @@ import { ActiveDossiersService } from '@services/dossiers/active-dossiers.servic import { DictionaryService } from '@services/entity-services/dictionary.service'; import { Roles } from '@users/roles'; import { UserPreferenceService } from '@users/user-preference.service'; -import { stringToBoolean } from '@utils/functions'; +import { calcTextWidthInPixels, stringToBoolean } from '@utils/functions'; import { tap } from 'rxjs/operators'; import { SystemDefaultOption, SystemDefaults } from '../../../account/utils/dialog-defaults'; import { getRedactOrHintOptions } from '../../utils/dialog-options'; import { AddHintData, AddHintResult, RedactOrHintOption, RedactOrHintOptions } from '../../utils/dialog-types'; +const MAXIMUM_TEXT_AREA_WIDTH = 421; + @Component({ templateUrl: './add-hint-dialog.component.html', styleUrls: ['./add-hint-dialog.component.scss'], @@ -49,6 +51,8 @@ import { AddHintData, AddHintResult, RedactOrHintOption, RedactOrHintOptions } f CircleButtonComponent, MatDialogClose, NgForOf, + NgClass, + NgStyle, ], }) export class AddHintDialogComponent extends IqserDialogComponent implements OnInit { @@ -58,9 +62,15 @@ export class AddHintDialogComponent extends IqserDialogComponent[]; + readonly initialText = this.data?.manualRedactionEntryWrapper?.manualRedactionEntry?.value; + readonly maximumTextAreaWidth = MAXIMUM_TEXT_AREA_WIDTH; + readonly maximumSelectedTextWidth = 567; dictionaryRequest = false; dictionaries: Dictionary[] = []; form!: UntypedFormGroup; + isEditingSelectedText = false; + selectedTextRows = 1; + textWidth: number; constructor( private readonly _activeDossiersService: ActiveDossiersService, @@ -83,6 +93,7 @@ export class AddHintDialogComponent extends IqserDialogComponent Date: Tue, 3 Sep 2024 14:42:59 +0300 Subject: [PATCH 003/125] RED-9987: added sendSetPasswordMail flag in add user dialog. --- .../user-details/user-details.component.html | 16 +- .../user-details/user-details.component.scss | 4 + .../user-details/user-details.component.ts | 67 ++++---- apps/red-ui/src/assets/i18n/redact/de.json | 153 +++++++++--------- apps/red-ui/src/assets/i18n/redact/en.json | 7 +- apps/red-ui/src/assets/i18n/scm/de.json | 153 +++++++++--------- apps/red-ui/src/assets/i18n/scm/en.json | 7 +- libs/common-ui | 2 +- 8 files changed, 221 insertions(+), 188 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-user-dialog/user-details/user-details.component.html b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-user-dialog/user-details/user-details.component.html index ffadbe1fe..0adcdcfab 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-user-dialog/user-details/user-details.component.html +++ b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-user-dialog/user-details/user-details.component.html @@ -1,6 +1,6 @@
+ @if (!user()) { +
+ + {{ 'add-edit-user.form.send-email' | translate }} + +
+ } + @@ -48,14 +56,14 @@
can't disable RED_USER_ADMIN as long as RED_ADMIN is checked */ - private readonly _ROLE_REQUIREMENTS = { RED_MANAGER: 'RED_USER', RED_ADMIN: 'RED_USER_ADMIN' }; - @Input() user: User; - @Output() readonly toggleResetPassword = new EventEmitter(); - @Output() readonly closeDialog = new EventEmitter(); - @Output() readonly cancel = new EventEmitter(); +export class UserDetailsComponent extends BaseFormComponent implements OnInit { + user = input(); + readonly toggleResetPassword = output(); + readonly closeDialog = output(); + readonly cancel = output(); readonly ROLES = ['RED_USER', 'RED_MANAGER', 'RED_USER_ADMIN', 'RED_ADMIN']; readonly translations = rolesTranslations; + /** e.g. a RED_ADMIN is automatically a RED_USER_ADMIN => can't disable RED_USER_ADMIN as long as RED_ADMIN is checked */ + readonly #ROLE_REQUIREMENTS = { RED_MANAGER: 'RED_USER', RED_ADMIN: 'RED_USER_ADMIN' }; constructor( private readonly _formBuilder: UntypedFormBuilder, @@ -49,13 +49,17 @@ export class UserDetailsComponent extends BaseFormComponent implements OnChanges }, []); } - private get _rolesControls(): any { + get sendSetPasswordMail() { + return !this.form.controls.sendSetPasswordMail.value; + } + + get #rolesControls() { return this.ROLES.reduce( (prev, role) => ({ ...prev, [role]: [ { - value: this.user && this.user.has(role), + value: this.user() && this.user().has(role), disabled: this.shouldBeDisabled(role), }, ], @@ -64,20 +68,20 @@ export class UserDetailsComponent extends BaseFormComponent implements OnChanges ); } - ngOnChanges() { - this.form = this._getForm(); + ngOnInit() { + this.form = this.#getForm(); this.initialFormValue = this.form.getRawValue(); } shouldBeDisabled(role: string): boolean { - const isCurrentAdminUser = this.user && this.user.isAdmin && this.user.id === this._userService.currentUser.id; + const isCurrentAdminUser = this.user() && this.user().isAdmin && this.user().id === this._userService.currentUser.id; return ( // RED_ADMIN can't remove own RED_ADMIN role (role === 'RED_ADMIN' && isCurrentAdminUser) || // only RED_ADMINs can edit RED_ADMIN roles (role === 'RED_ADMIN' && !this._userService.currentUser.isAdmin) || - Object.keys(this._ROLE_REQUIREMENTS).reduce( - (value, key) => value || (role === this._ROLE_REQUIREMENTS[key] && this.user?.roles.includes(key)), + Object.keys(this.#ROLE_REQUIREMENTS).reduce( + (value, key) => value || (role === this.#ROLE_REQUIREMENTS[key] && this.user()?.roles.includes(key)), false, ) ); @@ -85,9 +89,13 @@ export class UserDetailsComponent extends BaseFormComponent implements OnChanges async save() { this._loadingService.start(); - const userData: IProfileUpdateRequest = { ...this.form.getRawValue(), roles: this.activeRoles }; + const userData: IProfileUpdateRequest = { + ...this.form.getRawValue(), + roles: this.activeRoles, + sendSetPasswordMail: this.sendSetPasswordMail, + }; - if (!this.user) { + if (!this.user()) { await firstValueFrom(this._userService.create(userData)) .then(() => { this.closeDialog.emit(true); @@ -101,22 +109,22 @@ export class UserDetailsComponent extends BaseFormComponent implements OnChanges this._loadingService.stop(); }); } else { - await firstValueFrom(this._userService.updateProfile(userData, this.user.id)); + await firstValueFrom(this._userService.updateProfile(userData, this.user().id)); this.closeDialog.emit(true); } } delete() { - this._dialogService.deleteUsers([this.user.id], () => this.closeDialog.emit(true)); + this._dialogService.deleteUsers([this.user().id], () => this.closeDialog.emit(true)); } setRolesRequirements(checked: boolean, role: string): void { - if (Object.keys(this._ROLE_REQUIREMENTS).includes(role)) { + if (Object.keys(this.#ROLE_REQUIREMENTS).includes(role)) { if (checked) { - this.form.patchValue({ [this._ROLE_REQUIREMENTS[role]]: true }); - this.form.controls[this._ROLE_REQUIREMENTS[role]].disable(); + this.form.patchValue({ [this.#ROLE_REQUIREMENTS[role]]: true }); + this.form.controls[this.#ROLE_REQUIREMENTS[role]].disable(); } else { - this.form.controls[this._ROLE_REQUIREMENTS[role]].enable(); + this.form.controls[this.#ROLE_REQUIREMENTS[role]].enable(); } } } @@ -127,18 +135,19 @@ export class UserDetailsComponent extends BaseFormComponent implements OnChanges return user.id === this._userService.currentUser.id || (userAdmin && !currentUserAdmin); } - private _getForm(): UntypedFormGroup { + #getForm(): UntypedFormGroup { return this._formBuilder.group({ - firstName: [this.user?.firstName, Validators.required], - lastName: [this.user?.lastName, Validators.required], + firstName: [this.user()?.firstName, Validators.required], + lastName: [this.user()?.lastName, Validators.required], email: [ { - value: this.user?.email, - disabled: !!this.user?.email, + value: this.user()?.email, + disabled: !!this.user()?.email, }, [Validators.required, Validators.email], ], - ...this._rolesControls, + ...this.#rolesControls, + sendSetPasswordMail: [false], }); } } diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index f630f4d70..13967e1ce 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -207,11 +207,14 @@ "generic": "Speichern des Benutzers fehlgeschlagen." }, "form": { + "account-setup": "User account setup", "email": "E-Mail", "first-name": "Vorname", "last-name": "Nachname", "reset-password": "Passwort zurücksetzen", - "role": "Rolle" + "role": "Rolle", + "send-email": "Do not send email requesting the user to set a password", + "send-email-explanation": "Select this option if you use SSO. Please note that you will need to inform the user directly." }, "title": "{type, select, edit{Benutzer bearbeiten} create{Neuen Benutzer erstellen} other{}}" }, @@ -273,9 +276,6 @@ "watermarks": "Wasserzeichen" }, "analysis-disabled": "", - "annotation": { - "pending": "(Analyse steht aus)" - }, "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" @@ -331,14 +331,14 @@ "error": "Rekategorisierung des Bilds fehlgeschlagen: {error}", "success": "Bild wurde einer neuen Kategorie zugeordnet." }, - "remove": { - "error": "Entfernen der Schwärzung fehlgeschlagen: {error}", - "success": "Schwärzung wurde entfernt" - }, "remove-hint": { "error": "Entfernen des Hinweises fehlgeschlagen: {error}", "success": "Hinweis wurde entfernt" }, + "remove": { + "error": "Entfernen der Schwärzung fehlgeschlagen: {error}", + "success": "Schwärzung wurde entfernt" + }, "undo": { "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", "success": "Rücksetzung erfolgreich" @@ -351,15 +351,15 @@ "remove-highlights": { "label": "Ausgewählte Markierungen entfernen" }, - "resize": { - "label": "Größe ändern" - }, "resize-accept": { "label": "Neue Größe speichern" }, "resize-cancel": { "label": "Größenänderung abbrechen" }, + "resize": { + "label": "Größe ändern" + }, "see-references": { "label": "Referenzen anzeigen" }, @@ -393,6 +393,9 @@ "skipped": "Ignorierte Schwärzung", "text-highlight": "Markierung" }, + "annotation": { + "pending": "(Analyse steht aus)" + }, "annotations": "Annotationen", "archived-dossiers-listing": { "no-data": { @@ -636,18 +639,14 @@ "warning": "Warnung: Wiederherstellung des Benutzers nicht möglich." }, "confirmation-dialog": { - "approve-file": { - "question": "Dieses Dokument enthält ungesehene Änderungen, die sich durch die Reanalyse ergeben haben.

Möchten Sie es trotzdem freigeben?", - "title": "Warnung!" - }, "approve-file-without-analysis": { "confirmationText": "Ohne Analyse freigeben", "denyText": "Abbrechen", "question": "Analyse zur Erkennung neuer Schwärzungen erforderlich.", "title": "Warnung!" }, - "approve-multiple-files": { - "question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen, die im Zuge einer Reanalyse hinzugefügt wurden.

Möchen Sie die Dateien wirklich freigeben?", + "approve-file": { + "question": "Dieses Dokument enthält ungesehene Änderungen, die sich durch die Reanalyse ergeben haben.

Möchten Sie es trotzdem freigeben?", "title": "Warnung!" }, "approve-multiple-files-without-analysis": { @@ -656,6 +655,10 @@ "question": "Für mindestens eine Datei ist ein Analyselauf zur Erkennung neuer Schwärzungen erforderlich.", "title": "Warnung" }, + "approve-multiple-files": { + "question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen, die im Zuge einer Reanalyse hinzugefügt wurden.

Möchen Sie die Dateien wirklich freigeben?", + "title": "Warnung!" + }, "assign-file-to-me": { "question": { "multiple": "Dieses Dokument wird gerade von einer anderen Person geprüft.

Möchten Sie sich die Datei dennoch zuweisen?", @@ -1025,13 +1028,13 @@ "recent": "Neu ({hours} h)", "unassigned": "Keinem Bearbeiter zugewiesen" }, - "reanalyse": { - "action": "Datei analysieren" - }, "reanalyse-dossier": { "error": "Einplanung der Dateien für die Reanalyse fehlgeschlagen. Bitte versuchen Sie es noch einmal.", "success": "Dateien für Reanalyse vorgesehen." }, + "reanalyse": { + "action": "Datei analysieren" + }, "report-download": "", "start-auto-analysis": "Auto-Analyse aktivieren", "stop-auto-analysis": "Auto-Analyse anhalten", @@ -1101,14 +1104,6 @@ "total-documents": "Dokumente", "total-people": "{count} {count, plural, one{Benutzer} other {Benutzer}}" }, - "dossier-templates": { - "label": "Dossier-Vorlagen", - "status": { - "active": "Aktiv", - "inactive": "Inaktiv", - "incomplete": "Unvollständig" - } - }, "dossier-templates-listing": { "action": { "clone": "Vorlage klonen", @@ -1143,6 +1138,14 @@ "title": "{length} {length, plural, one{Dossier-Vorlage} other{Dossier-Vorlagen}}" } }, + "dossier-templates": { + "label": "Dossier-Vorlagen", + "status": { + "active": "Aktiv", + "inactive": "Inaktiv", + "incomplete": "Unvollständig" + } + }, "dossier-watermark-selector": { "heading": "Wasserzeichen auf Dokumenten", "no-watermark": "Kein Wasserzeichen in der Dossier-Vorlage verfügbar:
Bitten Sie Ihren Admin, eines zu konfigurieren.", @@ -1338,15 +1341,6 @@ "title": "{length} {length, plural, one{Wörterbuch} other{Wörterbücher}}" } }, - "entity": { - "info": { - "actions": { - "revert": "Zurücksetzen", - "save": "Änderungen speichern" - }, - "heading": "Entität bearbeiten" - } - }, "entity-rules-screen": { "error": { "generic": "Fehler: Aktualisierung der Entitätsregeln fehlgeschlagen." @@ -1360,19 +1354,28 @@ "title": "Entitätsregeln-Editor", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} in Regeln gefunden" }, + "entity": { + "info": { + "actions": { + "revert": "Zurücksetzen", + "save": "Änderungen speichern" + }, + "heading": "Entität bearbeiten" + } + }, "error": { "deleted-entity": { "dossier": { "action": "Zurück zur Übersicht", "label": "Dieses Dossier wurde gelöscht!" }, - "file": { - "action": "Zurück zum Dossier", - "label": "Diese Datei wurde gelöscht!" - }, "file-dossier": { "action": "Zurück zur Übersicht", "label": "Das Dossier dieser Datei wurde gelöscht!" + }, + "file": { + "action": "Zurück zum Dossier", + "label": "Diese Datei wurde gelöscht!" } }, "file-preview": { @@ -1390,12 +1393,6 @@ }, "exact-date": "{day}. {month} {year} um {hour}:{minute} Uhr", "file": "Datei", - "file-attribute": { - "update": { - "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", - "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." - } - }, "file-attribute-encoding-types": { "ascii": "ASCII", "iso": "ISO-8859-1", @@ -1406,6 +1403,12 @@ "number": "Nummer", "text": "Freier Text" }, + "file-attribute": { + "update": { + "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", + "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." + } + }, "file-attributes-configurations": { "cancel": "Abbrechen", "form": { @@ -1623,15 +1626,6 @@ "csv": "Die Datei-Attribute wurden erfolgreich aus der hochgeladenen CSV-Datei importiert." } }, - "filter": { - "analysis": "Analyse erforderlich", - "comment": "Kommentare", - "hint": "Nur Hinweise", - "image": "Bilder", - "none": "Keine Annotationen", - "redaction": "Schwärzungen", - "updated": "Aktualisiert" - }, "filter-menu": { "filter-options": "Filteroptionen", "filter-types": "Filter", @@ -1641,6 +1635,15 @@ "unseen-pages": "Nur Annotationen auf ungesehenen Seiten", "with-comments": "Nur Annotationen mit Kommentaren" }, + "filter": { + "analysis": "Analyse erforderlich", + "comment": "Kommentare", + "hint": "Nur Hinweise", + "image": "Bilder", + "none": "Keine Annotationen", + "redaction": "Schwärzungen", + "updated": "Aktualisiert" + }, "filters": { "assigned-people": "Bearbeiter", "documents-status": "Dokumentenstatus", @@ -1919,13 +1922,6 @@ "user-promoted-to-approver": "{user} wurde im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} zum Genehmiger ernannt!", "user-removed-as-dossier-member": "{user} wurde als Mitglied von: {dossierHref, select, null{{dossierName}} other{{dossierName}}} entfernt!" }, - "notifications": { - "button-text": "Benachrichtigungen", - "deleted-dossier": "Gelöschtes Dossier", - "label": "Benachrichtigungen", - "mark-all-as-read": "Alle als gelesen markieren", - "mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren" - }, "notifications-screen": { "category": { "email-notifications": "E-Mail-Benachrichtigungen", @@ -1939,6 +1935,7 @@ "dossier": "Benachrichtigungen zu Dossiers", "other": "Andere Benachrichtigungen" }, + "options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten", "options": { "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen werde", "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Prüfer zugewiesen werde", @@ -1956,7 +1953,6 @@ "USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde", "USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere" }, - "options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten", "schedule": { "daily": "Tägliche Zusammenfassung", "instant": "Sofort", @@ -1964,6 +1960,13 @@ }, "title": "Benachrichtigungseinstellungen" }, + "notifications": { + "button-text": "Benachrichtigungen", + "deleted-dossier": "Gelöschtes Dossier", + "label": "Benachrichtigungen", + "mark-all-as-read": "Alle als gelesen markieren", + "mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren" + }, "ocr": { "confirmation-dialog": { "cancel": "Abbrechen", @@ -2055,16 +2058,16 @@ "warnings-label": "Dialoge und Meldungen", "warnings-subtitle": "„Nicht mehr anzeigen“-Optionen" }, - "processing": { - "basic": "Verarbeitung läuft", - "ocr": "OCR" - }, "processing-status": { "ocr": "OCR", "pending": "Ausstehend", "processed": "Verarbeitet", "processing": "Verarbeitung läuft" }, + "processing": { + "basic": "Verarbeitung läuft", + "ocr": "OCR" + }, "readonly": "Lesemodus", "readonly-archived": "Lesemodus (archiviert)", "redact-text": { @@ -2300,12 +2303,6 @@ "red-user-admin": "Benutzeradmin", "regular": "regulärer Benutzer" }, - "search": { - "active-dossiers": "Dokumente in aktiven Dossiers", - "all-dossiers": "Alle Dokumente", - "placeholder": "Dokumente durchsuchen...", - "this-dossier": "In diesem Dossier" - }, "search-screen": { "cols": { "assignee": "Bearbeiter", @@ -2329,6 +2326,12 @@ "no-match": "Der Suchbegriff wurde in keinem der Dokumente gefunden.", "table-header": "{length} {length, plural, one{Suchergebnis} other{Suchergebnisse}}" }, + "search": { + "active-dossiers": "Dokumente in aktiven Dossiers", + "all-dossiers": "Alle Dokumente", + "placeholder": "Dokumente durchsuchen...", + "this-dossier": "In diesem Dossier" + }, "seconds": "Sekunden", "size": "Größe", "smtp-auth-config": { @@ -2584,4 +2587,4 @@ } }, "yesterday": "Gestern" -} \ No newline at end of file +} diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index 79faf6e1f..92474fcab 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -207,11 +207,14 @@ "generic": "Failed to save user." }, "form": { + "account-setup": "User account setup", "email": "E-mail", "first-name": "First name", "last-name": "Last name", "reset-password": "Reset password", - "role": "Role" + "role": "Role", + "send-email": "Do not send email requesting the user to set a password", + "send-email-explanation": "Select this option if you use SSO. Please note that you will need to inform the user directly." }, "title": "{type, select, edit{Edit} create{Add new} other{}} user" }, @@ -2584,4 +2587,4 @@ } }, "yesterday": "Yesterday" -} \ No newline at end of file +} diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 6adf5369f..0687b764c 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -207,11 +207,14 @@ "generic": "Benutzer konnte nicht gespeichert werden!" }, "form": { + "account-setup": "User account setup", "email": "E-Mail", "first-name": "Vorname", "last-name": "Nachname", "reset-password": "Passwort zurücksetzen", - "role": "Rolle" + "role": "Rolle", + "send-email": "Do not send email requesting the user to set a password", + "send-email-explanation": "Select this option if you use SSO. Please note that you will need to inform the user directly." }, "title": "{type, select, edit{Benutzer bearbeiten} create{Neuen Benutzer hinzufügen} other{}}" }, @@ -273,9 +276,6 @@ "watermarks": "Watermarks" }, "analysis-disabled": "Analysis disabled", - "annotation": { - "pending": "(Pending analysis)" - }, "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" @@ -331,14 +331,14 @@ "error": "Rekategorisierung des Bildes gescheitert: {error}", "success": "Bild wurde einer neuen Kategorie zugeordnet." }, - "remove": { - "error": "Fehler beim Entfernen der Schwärzung: {error}", - "success": "Schwärzung entfernt!" - }, "remove-hint": { "error": "Failed to remove hint: {error}", "success": "Hint removed!" }, + "remove": { + "error": "Fehler beim Entfernen der Schwärzung: {error}", + "success": "Schwärzung entfernt!" + }, "undo": { "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", "success": "erfolgreich Rückgängig gemacht" @@ -351,15 +351,15 @@ "remove-highlights": { "label": "Remove selected earmarks" }, - "resize": { - "label": "Größe ändern" - }, "resize-accept": { "label": "Größe speichern" }, "resize-cancel": { "label": "Größenänderung abbrechen" }, + "resize": { + "label": "Größe ändern" + }, "see-references": { "label": "See references" }, @@ -393,6 +393,9 @@ "skipped": "Übersprungen", "text-highlight": "Earmark" }, + "annotation": { + "pending": "(Pending analysis)" + }, "annotations": "Annotations", "archived-dossiers-listing": { "no-data": { @@ -636,18 +639,14 @@ "warning": "Achtung: Diese Aktion kann nicht rückgängig gemacht werden!" }, "confirmation-dialog": { - "approve-file": { - "question": "Dieses Dokument enthält ungesehene Änderungen. Möchten Sie es trotzdem genehmigen?", - "title": "Warnung!" - }, "approve-file-without-analysis": { "confirmationText": "Approve without analysis", "denyText": "Cancel", "question": "Analysis required to detect new components.", "title": "Warning!" }, - "approve-multiple-files": { - "question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen. Möchten Sie sie trotzdem genehmigen?", + "approve-file": { + "question": "Dieses Dokument enthält ungesehene Änderungen. Möchten Sie es trotzdem genehmigen?", "title": "Warnung!" }, "approve-multiple-files-without-analysis": { @@ -656,6 +655,10 @@ "question": "Analysis required to detect new components for at least one file.", "title": "Warning" }, + "approve-multiple-files": { + "question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen. Möchten Sie sie trotzdem genehmigen?", + "title": "Warnung!" + }, "assign-file-to-me": { "question": { "multiple": "Dieses Dokument wird gerade von einer anderen Person geprüft. Möchten Sie Reviewer werden und sich selbst dem Dokument zuweisen?", @@ -1025,13 +1028,13 @@ "recent": "Neu ({hours} h)", "unassigned": "Niemandem zugewiesen" }, - "reanalyse": { - "action": "Datei analysieren" - }, "reanalyse-dossier": { "error": "Die Dateien konnten nicht für eine Reanalyse eingeplant werden. Bitte versuchen Sie es erneut.", "success": "Dateien für Reanalyse vorgesehen." }, + "reanalyse": { + "action": "Datei analysieren" + }, "report-download": "Report download", "start-auto-analysis": "Enable auto-analysis", "stop-auto-analysis": "Stop auto-analysis", @@ -1101,14 +1104,6 @@ "total-documents": "Anzahl der Dokumente", "total-people": "{count} {count, plural, one{user} other {users}}" }, - "dossier-templates": { - "label": "Dossier-Vorlagen", - "status": { - "active": "Active", - "inactive": "Inactive", - "incomplete": "Incomplete" - } - }, "dossier-templates-listing": { "action": { "clone": "Clone template", @@ -1143,6 +1138,14 @@ "title": "{length} dossier {length, plural, one{template} other{templates}}" } }, + "dossier-templates": { + "label": "Dossier-Vorlagen", + "status": { + "active": "Active", + "inactive": "Inactive", + "incomplete": "Incomplete" + } + }, "dossier-watermark-selector": { "heading": "Watermarks on documents", "no-watermark": "There is no watermark defined for the dossier template.
Contact your app admin to define one.", @@ -1338,15 +1341,6 @@ "title": "{length} {length, plural, one{entity} other{entities}}" } }, - "entity": { - "info": { - "actions": { - "revert": "Revert", - "save": "Save changes" - }, - "heading": "Edit entity" - } - }, "entity-rules-screen": { "error": { "generic": "Something went wrong... Entity rules update failed!" @@ -1360,19 +1354,28 @@ "title": "Entity rule editor", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} found in rules" }, + "entity": { + "info": { + "actions": { + "revert": "Revert", + "save": "Save changes" + }, + "heading": "Edit entity" + } + }, "error": { "deleted-entity": { "dossier": { "action": "Zurück zur Übersicht", "label": "Dieses Dossier wurde gelöscht!" }, - "file": { - "action": "Zurück zum Dossier", - "label": "Diese Datei wurde gelöscht!" - }, "file-dossier": { "action": "Zurück zur Übersicht", "label": "Das Dossier dieser Datei wurde gelöscht!" + }, + "file": { + "action": "Zurück zum Dossier", + "label": "Diese Datei wurde gelöscht!" } }, "file-preview": { @@ -1390,12 +1393,6 @@ }, "exact-date": "{day} {month} {year} um {hour}:{minute} Uhr", "file": "Datei", - "file-attribute": { - "update": { - "error": "Failed to update file attribute value!", - "success": "File attribute value has been updated successfully!" - } - }, "file-attribute-encoding-types": { "ascii": "ASCII", "iso": "ISO-8859-1", @@ -1406,6 +1403,12 @@ "number": "Nummer", "text": "Freier Text" }, + "file-attribute": { + "update": { + "error": "Failed to update file attribute value!", + "success": "File attribute value has been updated successfully!" + } + }, "file-attributes-configurations": { "cancel": "Cancel", "form": { @@ -1623,15 +1626,6 @@ "csv": "File attributes were imported successfully from uploaded CSV file." } }, - "filter": { - "analysis": "Analyse erforderlich", - "comment": "Kommentare", - "hint": "Nut Hinweise", - "image": "Bilder", - "none": "Keine Anmerkungen", - "redaction": "Geschwärzt", - "updated": "Aktualisiert" - }, "filter-menu": { "filter-options": "Filteroptionen", "filter-types": "Filter", @@ -1641,6 +1635,15 @@ "unseen-pages": "Nur Anmerkungen auf unsichtbaren Seiten", "with-comments": "Nur Anmerkungen mit Kommentaren" }, + "filter": { + "analysis": "Analyse erforderlich", + "comment": "Kommentare", + "hint": "Nut Hinweise", + "image": "Bilder", + "none": "Keine Anmerkungen", + "redaction": "Geschwärzt", + "updated": "Aktualisiert" + }, "filters": { "assigned-people": "Beauftragt", "documents-status": "Documents state", @@ -1919,13 +1922,6 @@ "user-promoted-to-approver": "{user} wurde im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} zum Genehmiger ernannt!", "user-removed-as-dossier-member": "{user} wurde als Mitglied von: {dossierHref, select, null{{dossierName}} other{{dossierName}}} entfernt!" }, - "notifications": { - "button-text": "Notifications", - "deleted-dossier": "Deleted dossier", - "label": "Benachrichtigungen", - "mark-all-as-read": "Alle als gelesen markieren", - "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}" - }, "notifications-screen": { "category": { "email-notifications": "E-Mail Benachrichtigungen", @@ -1939,6 +1935,7 @@ "dossier": "Dossierbezogene Benachrichtigungen", "other": "Andere Benachrichtigungen" }, + "options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten", "options": { "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen bin", "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Überprüfer zugewiesen bin", @@ -1956,7 +1953,6 @@ "USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde", "USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere" }, - "options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten", "schedule": { "daily": "Tägliche Zusammenfassung", "instant": "Sofortig", @@ -1964,6 +1960,13 @@ }, "title": "Benachrichtigungseinstellungen" }, + "notifications": { + "button-text": "Notifications", + "deleted-dossier": "Deleted dossier", + "label": "Benachrichtigungen", + "mark-all-as-read": "Alle als gelesen markieren", + "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}" + }, "ocr": { "confirmation-dialog": { "cancel": "Cancel", @@ -2055,16 +2058,16 @@ "warnings-label": "Prompts and dialogs", "warnings-subtitle": "Do not show again options" }, - "processing": { - "basic": "Processing", - "ocr": "OCR" - }, "processing-status": { "ocr": "OCR", "pending": "Pending", "processed": "Processed", "processing": "Processing" }, + "processing": { + "basic": "Processing", + "ocr": "OCR" + }, "readonly": "Lesemodus", "readonly-archived": "Read only (archived)", "redact-text": { @@ -2300,12 +2303,6 @@ "red-user-admin": "Benutzer-Admin", "regular": "Regulär" }, - "search": { - "active-dossiers": "ganze Plattform", - "all-dossiers": "all documents", - "placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen", - "this-dossier": "in diesem Dossier" - }, "search-screen": { "cols": { "assignee": "Bevollmächtigter", @@ -2329,6 +2326,12 @@ "no-match": "Keine Dokumente entsprechen Ihren aktuellen Filtern.", "table-header": "{length} search {length, plural, one{result} other{results}}" }, + "search": { + "active-dossiers": "ganze Plattform", + "all-dossiers": "all documents", + "placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen", + "this-dossier": "in diesem Dossier" + }, "seconds": "seconds", "size": "Size", "smtp-auth-config": { @@ -2584,4 +2587,4 @@ } }, "yesterday": "Gestern" -} \ No newline at end of file +} diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index b828a2d39..c0895025d 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -207,11 +207,14 @@ "generic": "Failed to save user!" }, "form": { + "account-setup": "User account setup", "email": "E-mail", "first-name": "First name", "last-name": "Last name", "reset-password": "Reset password", - "role": "Role" + "role": "Role", + "send-email": "Do not send email requesting the user to set a password", + "send-email-explanation": "Select this option if you use SSO. Please note that you will need to inform the user directly." }, "title": "{type, select, edit{Edit} create{Add new} other{}} user" }, @@ -2584,4 +2587,4 @@ } }, "yesterday": "Yesterday" -} \ No newline at end of file +} diff --git a/libs/common-ui b/libs/common-ui index 007e761bd..9bc05f116 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 007e761bd597a1534599b05d28826258bfc52570 +Subproject commit 9bc05f11657da806743718dc9cbd1cc4f5af10a7 From 01b8948b6a408c3de4ce1972ebb05f6f74ed1f4d Mon Sep 17 00:00:00 2001 From: project_703_bot_497bb7eb186ca592c63b3e50cd5c69e1 Date: Wed, 4 Sep 2024 01:03:33 +0000 Subject: [PATCH 004/125] push back localazy update --- apps/red-ui/src/assets/i18n/redact/de.json | 153 ++++++++++----------- apps/red-ui/src/assets/i18n/redact/en.json | 2 +- apps/red-ui/src/assets/i18n/scm/de.json | 153 ++++++++++----------- apps/red-ui/src/assets/i18n/scm/en.json | 2 +- 4 files changed, 152 insertions(+), 158 deletions(-) diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index 13967e1ce..f630f4d70 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -207,14 +207,11 @@ "generic": "Speichern des Benutzers fehlgeschlagen." }, "form": { - "account-setup": "User account setup", "email": "E-Mail", "first-name": "Vorname", "last-name": "Nachname", "reset-password": "Passwort zurücksetzen", - "role": "Rolle", - "send-email": "Do not send email requesting the user to set a password", - "send-email-explanation": "Select this option if you use SSO. Please note that you will need to inform the user directly." + "role": "Rolle" }, "title": "{type, select, edit{Benutzer bearbeiten} create{Neuen Benutzer erstellen} other{}}" }, @@ -276,6 +273,9 @@ "watermarks": "Wasserzeichen" }, "analysis-disabled": "", + "annotation": { + "pending": "(Analyse steht aus)" + }, "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" @@ -331,14 +331,14 @@ "error": "Rekategorisierung des Bilds fehlgeschlagen: {error}", "success": "Bild wurde einer neuen Kategorie zugeordnet." }, - "remove-hint": { - "error": "Entfernen des Hinweises fehlgeschlagen: {error}", - "success": "Hinweis wurde entfernt" - }, "remove": { "error": "Entfernen der Schwärzung fehlgeschlagen: {error}", "success": "Schwärzung wurde entfernt" }, + "remove-hint": { + "error": "Entfernen des Hinweises fehlgeschlagen: {error}", + "success": "Hinweis wurde entfernt" + }, "undo": { "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", "success": "Rücksetzung erfolgreich" @@ -351,15 +351,15 @@ "remove-highlights": { "label": "Ausgewählte Markierungen entfernen" }, + "resize": { + "label": "Größe ändern" + }, "resize-accept": { "label": "Neue Größe speichern" }, "resize-cancel": { "label": "Größenänderung abbrechen" }, - "resize": { - "label": "Größe ändern" - }, "see-references": { "label": "Referenzen anzeigen" }, @@ -393,9 +393,6 @@ "skipped": "Ignorierte Schwärzung", "text-highlight": "Markierung" }, - "annotation": { - "pending": "(Analyse steht aus)" - }, "annotations": "Annotationen", "archived-dossiers-listing": { "no-data": { @@ -639,14 +636,18 @@ "warning": "Warnung: Wiederherstellung des Benutzers nicht möglich." }, "confirmation-dialog": { + "approve-file": { + "question": "Dieses Dokument enthält ungesehene Änderungen, die sich durch die Reanalyse ergeben haben.

Möchten Sie es trotzdem freigeben?", + "title": "Warnung!" + }, "approve-file-without-analysis": { "confirmationText": "Ohne Analyse freigeben", "denyText": "Abbrechen", "question": "Analyse zur Erkennung neuer Schwärzungen erforderlich.", "title": "Warnung!" }, - "approve-file": { - "question": "Dieses Dokument enthält ungesehene Änderungen, die sich durch die Reanalyse ergeben haben.

Möchten Sie es trotzdem freigeben?", + "approve-multiple-files": { + "question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen, die im Zuge einer Reanalyse hinzugefügt wurden.

Möchen Sie die Dateien wirklich freigeben?", "title": "Warnung!" }, "approve-multiple-files-without-analysis": { @@ -655,10 +656,6 @@ "question": "Für mindestens eine Datei ist ein Analyselauf zur Erkennung neuer Schwärzungen erforderlich.", "title": "Warnung" }, - "approve-multiple-files": { - "question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen, die im Zuge einer Reanalyse hinzugefügt wurden.

Möchen Sie die Dateien wirklich freigeben?", - "title": "Warnung!" - }, "assign-file-to-me": { "question": { "multiple": "Dieses Dokument wird gerade von einer anderen Person geprüft.

Möchten Sie sich die Datei dennoch zuweisen?", @@ -1028,13 +1025,13 @@ "recent": "Neu ({hours} h)", "unassigned": "Keinem Bearbeiter zugewiesen" }, + "reanalyse": { + "action": "Datei analysieren" + }, "reanalyse-dossier": { "error": "Einplanung der Dateien für die Reanalyse fehlgeschlagen. Bitte versuchen Sie es noch einmal.", "success": "Dateien für Reanalyse vorgesehen." }, - "reanalyse": { - "action": "Datei analysieren" - }, "report-download": "", "start-auto-analysis": "Auto-Analyse aktivieren", "stop-auto-analysis": "Auto-Analyse anhalten", @@ -1104,6 +1101,14 @@ "total-documents": "Dokumente", "total-people": "{count} {count, plural, one{Benutzer} other {Benutzer}}" }, + "dossier-templates": { + "label": "Dossier-Vorlagen", + "status": { + "active": "Aktiv", + "inactive": "Inaktiv", + "incomplete": "Unvollständig" + } + }, "dossier-templates-listing": { "action": { "clone": "Vorlage klonen", @@ -1138,14 +1143,6 @@ "title": "{length} {length, plural, one{Dossier-Vorlage} other{Dossier-Vorlagen}}" } }, - "dossier-templates": { - "label": "Dossier-Vorlagen", - "status": { - "active": "Aktiv", - "inactive": "Inaktiv", - "incomplete": "Unvollständig" - } - }, "dossier-watermark-selector": { "heading": "Wasserzeichen auf Dokumenten", "no-watermark": "Kein Wasserzeichen in der Dossier-Vorlage verfügbar:
Bitten Sie Ihren Admin, eines zu konfigurieren.", @@ -1341,6 +1338,15 @@ "title": "{length} {length, plural, one{Wörterbuch} other{Wörterbücher}}" } }, + "entity": { + "info": { + "actions": { + "revert": "Zurücksetzen", + "save": "Änderungen speichern" + }, + "heading": "Entität bearbeiten" + } + }, "entity-rules-screen": { "error": { "generic": "Fehler: Aktualisierung der Entitätsregeln fehlgeschlagen." @@ -1354,28 +1360,19 @@ "title": "Entitätsregeln-Editor", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} in Regeln gefunden" }, - "entity": { - "info": { - "actions": { - "revert": "Zurücksetzen", - "save": "Änderungen speichern" - }, - "heading": "Entität bearbeiten" - } - }, "error": { "deleted-entity": { "dossier": { "action": "Zurück zur Übersicht", "label": "Dieses Dossier wurde gelöscht!" }, - "file-dossier": { - "action": "Zurück zur Übersicht", - "label": "Das Dossier dieser Datei wurde gelöscht!" - }, "file": { "action": "Zurück zum Dossier", "label": "Diese Datei wurde gelöscht!" + }, + "file-dossier": { + "action": "Zurück zur Übersicht", + "label": "Das Dossier dieser Datei wurde gelöscht!" } }, "file-preview": { @@ -1393,6 +1390,12 @@ }, "exact-date": "{day}. {month} {year} um {hour}:{minute} Uhr", "file": "Datei", + "file-attribute": { + "update": { + "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", + "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." + } + }, "file-attribute-encoding-types": { "ascii": "ASCII", "iso": "ISO-8859-1", @@ -1403,12 +1406,6 @@ "number": "Nummer", "text": "Freier Text" }, - "file-attribute": { - "update": { - "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", - "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." - } - }, "file-attributes-configurations": { "cancel": "Abbrechen", "form": { @@ -1626,15 +1623,6 @@ "csv": "Die Datei-Attribute wurden erfolgreich aus der hochgeladenen CSV-Datei importiert." } }, - "filter-menu": { - "filter-options": "Filteroptionen", - "filter-types": "Filter", - "label": "Filter", - "pages-without-annotations": "Nur Seiten ohne Annotationen", - "redaction-changes": "Nur Annotationen mit lokalen manuellen Änderungen", - "unseen-pages": "Nur Annotationen auf ungesehenen Seiten", - "with-comments": "Nur Annotationen mit Kommentaren" - }, "filter": { "analysis": "Analyse erforderlich", "comment": "Kommentare", @@ -1644,6 +1632,15 @@ "redaction": "Schwärzungen", "updated": "Aktualisiert" }, + "filter-menu": { + "filter-options": "Filteroptionen", + "filter-types": "Filter", + "label": "Filter", + "pages-without-annotations": "Nur Seiten ohne Annotationen", + "redaction-changes": "Nur Annotationen mit lokalen manuellen Änderungen", + "unseen-pages": "Nur Annotationen auf ungesehenen Seiten", + "with-comments": "Nur Annotationen mit Kommentaren" + }, "filters": { "assigned-people": "Bearbeiter", "documents-status": "Dokumentenstatus", @@ -1922,6 +1919,13 @@ "user-promoted-to-approver": "{user} wurde im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} zum Genehmiger ernannt!", "user-removed-as-dossier-member": "{user} wurde als Mitglied von: {dossierHref, select, null{{dossierName}} other{{dossierName}}} entfernt!" }, + "notifications": { + "button-text": "Benachrichtigungen", + "deleted-dossier": "Gelöschtes Dossier", + "label": "Benachrichtigungen", + "mark-all-as-read": "Alle als gelesen markieren", + "mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren" + }, "notifications-screen": { "category": { "email-notifications": "E-Mail-Benachrichtigungen", @@ -1935,7 +1939,6 @@ "dossier": "Benachrichtigungen zu Dossiers", "other": "Andere Benachrichtigungen" }, - "options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten", "options": { "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen werde", "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Prüfer zugewiesen werde", @@ -1953,6 +1956,7 @@ "USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde", "USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere" }, + "options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten", "schedule": { "daily": "Tägliche Zusammenfassung", "instant": "Sofort", @@ -1960,13 +1964,6 @@ }, "title": "Benachrichtigungseinstellungen" }, - "notifications": { - "button-text": "Benachrichtigungen", - "deleted-dossier": "Gelöschtes Dossier", - "label": "Benachrichtigungen", - "mark-all-as-read": "Alle als gelesen markieren", - "mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren" - }, "ocr": { "confirmation-dialog": { "cancel": "Abbrechen", @@ -2058,16 +2055,16 @@ "warnings-label": "Dialoge und Meldungen", "warnings-subtitle": "„Nicht mehr anzeigen“-Optionen" }, + "processing": { + "basic": "Verarbeitung läuft", + "ocr": "OCR" + }, "processing-status": { "ocr": "OCR", "pending": "Ausstehend", "processed": "Verarbeitet", "processing": "Verarbeitung läuft" }, - "processing": { - "basic": "Verarbeitung läuft", - "ocr": "OCR" - }, "readonly": "Lesemodus", "readonly-archived": "Lesemodus (archiviert)", "redact-text": { @@ -2303,6 +2300,12 @@ "red-user-admin": "Benutzeradmin", "regular": "regulärer Benutzer" }, + "search": { + "active-dossiers": "Dokumente in aktiven Dossiers", + "all-dossiers": "Alle Dokumente", + "placeholder": "Dokumente durchsuchen...", + "this-dossier": "In diesem Dossier" + }, "search-screen": { "cols": { "assignee": "Bearbeiter", @@ -2326,12 +2329,6 @@ "no-match": "Der Suchbegriff wurde in keinem der Dokumente gefunden.", "table-header": "{length} {length, plural, one{Suchergebnis} other{Suchergebnisse}}" }, - "search": { - "active-dossiers": "Dokumente in aktiven Dossiers", - "all-dossiers": "Alle Dokumente", - "placeholder": "Dokumente durchsuchen...", - "this-dossier": "In diesem Dossier" - }, "seconds": "Sekunden", "size": "Größe", "smtp-auth-config": { @@ -2587,4 +2584,4 @@ } }, "yesterday": "Gestern" -} +} \ No newline at end of file diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index 92474fcab..27acfb116 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -2587,4 +2587,4 @@ } }, "yesterday": "Yesterday" -} +} \ No newline at end of file diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 0687b764c..6adf5369f 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -207,14 +207,11 @@ "generic": "Benutzer konnte nicht gespeichert werden!" }, "form": { - "account-setup": "User account setup", "email": "E-Mail", "first-name": "Vorname", "last-name": "Nachname", "reset-password": "Passwort zurücksetzen", - "role": "Rolle", - "send-email": "Do not send email requesting the user to set a password", - "send-email-explanation": "Select this option if you use SSO. Please note that you will need to inform the user directly." + "role": "Rolle" }, "title": "{type, select, edit{Benutzer bearbeiten} create{Neuen Benutzer hinzufügen} other{}}" }, @@ -276,6 +273,9 @@ "watermarks": "Watermarks" }, "analysis-disabled": "Analysis disabled", + "annotation": { + "pending": "(Pending analysis)" + }, "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" @@ -331,14 +331,14 @@ "error": "Rekategorisierung des Bildes gescheitert: {error}", "success": "Bild wurde einer neuen Kategorie zugeordnet." }, - "remove-hint": { - "error": "Failed to remove hint: {error}", - "success": "Hint removed!" - }, "remove": { "error": "Fehler beim Entfernen der Schwärzung: {error}", "success": "Schwärzung entfernt!" }, + "remove-hint": { + "error": "Failed to remove hint: {error}", + "success": "Hint removed!" + }, "undo": { "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", "success": "erfolgreich Rückgängig gemacht" @@ -351,15 +351,15 @@ "remove-highlights": { "label": "Remove selected earmarks" }, + "resize": { + "label": "Größe ändern" + }, "resize-accept": { "label": "Größe speichern" }, "resize-cancel": { "label": "Größenänderung abbrechen" }, - "resize": { - "label": "Größe ändern" - }, "see-references": { "label": "See references" }, @@ -393,9 +393,6 @@ "skipped": "Übersprungen", "text-highlight": "Earmark" }, - "annotation": { - "pending": "(Pending analysis)" - }, "annotations": "Annotations", "archived-dossiers-listing": { "no-data": { @@ -639,14 +636,18 @@ "warning": "Achtung: Diese Aktion kann nicht rückgängig gemacht werden!" }, "confirmation-dialog": { + "approve-file": { + "question": "Dieses Dokument enthält ungesehene Änderungen. Möchten Sie es trotzdem genehmigen?", + "title": "Warnung!" + }, "approve-file-without-analysis": { "confirmationText": "Approve without analysis", "denyText": "Cancel", "question": "Analysis required to detect new components.", "title": "Warning!" }, - "approve-file": { - "question": "Dieses Dokument enthält ungesehene Änderungen. Möchten Sie es trotzdem genehmigen?", + "approve-multiple-files": { + "question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen. Möchten Sie sie trotzdem genehmigen?", "title": "Warnung!" }, "approve-multiple-files-without-analysis": { @@ -655,10 +656,6 @@ "question": "Analysis required to detect new components for at least one file.", "title": "Warning" }, - "approve-multiple-files": { - "question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen. Möchten Sie sie trotzdem genehmigen?", - "title": "Warnung!" - }, "assign-file-to-me": { "question": { "multiple": "Dieses Dokument wird gerade von einer anderen Person geprüft. Möchten Sie Reviewer werden und sich selbst dem Dokument zuweisen?", @@ -1028,13 +1025,13 @@ "recent": "Neu ({hours} h)", "unassigned": "Niemandem zugewiesen" }, + "reanalyse": { + "action": "Datei analysieren" + }, "reanalyse-dossier": { "error": "Die Dateien konnten nicht für eine Reanalyse eingeplant werden. Bitte versuchen Sie es erneut.", "success": "Dateien für Reanalyse vorgesehen." }, - "reanalyse": { - "action": "Datei analysieren" - }, "report-download": "Report download", "start-auto-analysis": "Enable auto-analysis", "stop-auto-analysis": "Stop auto-analysis", @@ -1104,6 +1101,14 @@ "total-documents": "Anzahl der Dokumente", "total-people": "{count} {count, plural, one{user} other {users}}" }, + "dossier-templates": { + "label": "Dossier-Vorlagen", + "status": { + "active": "Active", + "inactive": "Inactive", + "incomplete": "Incomplete" + } + }, "dossier-templates-listing": { "action": { "clone": "Clone template", @@ -1138,14 +1143,6 @@ "title": "{length} dossier {length, plural, one{template} other{templates}}" } }, - "dossier-templates": { - "label": "Dossier-Vorlagen", - "status": { - "active": "Active", - "inactive": "Inactive", - "incomplete": "Incomplete" - } - }, "dossier-watermark-selector": { "heading": "Watermarks on documents", "no-watermark": "There is no watermark defined for the dossier template.
Contact your app admin to define one.", @@ -1341,6 +1338,15 @@ "title": "{length} {length, plural, one{entity} other{entities}}" } }, + "entity": { + "info": { + "actions": { + "revert": "Revert", + "save": "Save changes" + }, + "heading": "Edit entity" + } + }, "entity-rules-screen": { "error": { "generic": "Something went wrong... Entity rules update failed!" @@ -1354,28 +1360,19 @@ "title": "Entity rule editor", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} found in rules" }, - "entity": { - "info": { - "actions": { - "revert": "Revert", - "save": "Save changes" - }, - "heading": "Edit entity" - } - }, "error": { "deleted-entity": { "dossier": { "action": "Zurück zur Übersicht", "label": "Dieses Dossier wurde gelöscht!" }, - "file-dossier": { - "action": "Zurück zur Übersicht", - "label": "Das Dossier dieser Datei wurde gelöscht!" - }, "file": { "action": "Zurück zum Dossier", "label": "Diese Datei wurde gelöscht!" + }, + "file-dossier": { + "action": "Zurück zur Übersicht", + "label": "Das Dossier dieser Datei wurde gelöscht!" } }, "file-preview": { @@ -1393,6 +1390,12 @@ }, "exact-date": "{day} {month} {year} um {hour}:{minute} Uhr", "file": "Datei", + "file-attribute": { + "update": { + "error": "Failed to update file attribute value!", + "success": "File attribute value has been updated successfully!" + } + }, "file-attribute-encoding-types": { "ascii": "ASCII", "iso": "ISO-8859-1", @@ -1403,12 +1406,6 @@ "number": "Nummer", "text": "Freier Text" }, - "file-attribute": { - "update": { - "error": "Failed to update file attribute value!", - "success": "File attribute value has been updated successfully!" - } - }, "file-attributes-configurations": { "cancel": "Cancel", "form": { @@ -1626,15 +1623,6 @@ "csv": "File attributes were imported successfully from uploaded CSV file." } }, - "filter-menu": { - "filter-options": "Filteroptionen", - "filter-types": "Filter", - "label": "Filter", - "pages-without-annotations": "Only pages without annotations", - "redaction-changes": "Nur Anmerkungen mit Schwärzungsänderungen", - "unseen-pages": "Nur Anmerkungen auf unsichtbaren Seiten", - "with-comments": "Nur Anmerkungen mit Kommentaren" - }, "filter": { "analysis": "Analyse erforderlich", "comment": "Kommentare", @@ -1644,6 +1632,15 @@ "redaction": "Geschwärzt", "updated": "Aktualisiert" }, + "filter-menu": { + "filter-options": "Filteroptionen", + "filter-types": "Filter", + "label": "Filter", + "pages-without-annotations": "Only pages without annotations", + "redaction-changes": "Nur Anmerkungen mit Schwärzungsänderungen", + "unseen-pages": "Nur Anmerkungen auf unsichtbaren Seiten", + "with-comments": "Nur Anmerkungen mit Kommentaren" + }, "filters": { "assigned-people": "Beauftragt", "documents-status": "Documents state", @@ -1922,6 +1919,13 @@ "user-promoted-to-approver": "{user} wurde im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} zum Genehmiger ernannt!", "user-removed-as-dossier-member": "{user} wurde als Mitglied von: {dossierHref, select, null{{dossierName}} other{{dossierName}}} entfernt!" }, + "notifications": { + "button-text": "Notifications", + "deleted-dossier": "Deleted dossier", + "label": "Benachrichtigungen", + "mark-all-as-read": "Alle als gelesen markieren", + "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}" + }, "notifications-screen": { "category": { "email-notifications": "E-Mail Benachrichtigungen", @@ -1935,7 +1939,6 @@ "dossier": "Dossierbezogene Benachrichtigungen", "other": "Andere Benachrichtigungen" }, - "options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten", "options": { "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen bin", "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Überprüfer zugewiesen bin", @@ -1953,6 +1956,7 @@ "USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde", "USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere" }, + "options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten", "schedule": { "daily": "Tägliche Zusammenfassung", "instant": "Sofortig", @@ -1960,13 +1964,6 @@ }, "title": "Benachrichtigungseinstellungen" }, - "notifications": { - "button-text": "Notifications", - "deleted-dossier": "Deleted dossier", - "label": "Benachrichtigungen", - "mark-all-as-read": "Alle als gelesen markieren", - "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}" - }, "ocr": { "confirmation-dialog": { "cancel": "Cancel", @@ -2058,16 +2055,16 @@ "warnings-label": "Prompts and dialogs", "warnings-subtitle": "Do not show again options" }, + "processing": { + "basic": "Processing", + "ocr": "OCR" + }, "processing-status": { "ocr": "OCR", "pending": "Pending", "processed": "Processed", "processing": "Processing" }, - "processing": { - "basic": "Processing", - "ocr": "OCR" - }, "readonly": "Lesemodus", "readonly-archived": "Read only (archived)", "redact-text": { @@ -2303,6 +2300,12 @@ "red-user-admin": "Benutzer-Admin", "regular": "Regulär" }, + "search": { + "active-dossiers": "ganze Plattform", + "all-dossiers": "all documents", + "placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen", + "this-dossier": "in diesem Dossier" + }, "search-screen": { "cols": { "assignee": "Bevollmächtigter", @@ -2326,12 +2329,6 @@ "no-match": "Keine Dokumente entsprechen Ihren aktuellen Filtern.", "table-header": "{length} search {length, plural, one{result} other{results}}" }, - "search": { - "active-dossiers": "ganze Plattform", - "all-dossiers": "all documents", - "placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen", - "this-dossier": "in diesem Dossier" - }, "seconds": "seconds", "size": "Size", "smtp-auth-config": { @@ -2587,4 +2584,4 @@ } }, "yesterday": "Gestern" -} +} \ No newline at end of file diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index c0895025d..5934e1f48 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -2587,4 +2587,4 @@ } }, "yesterday": "Yesterday" -} +} \ No newline at end of file From 24e793582db1fb4b20c4bf321ac0f8e9e7fb8f8a Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Wed, 4 Sep 2024 13:29:36 +0300 Subject: [PATCH 005/125] RED-9937: made preview tab available & trigger reanalysis when required. --- .../components/view-switch/view-switch.component.ts | 2 +- .../file-preview/file-preview-screen.component.ts | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/view-switch/view-switch.component.ts b/apps/red-ui/src/app/modules/file-preview/components/view-switch/view-switch.component.ts index 21cc039be..d7a593c9c 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/view-switch/view-switch.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/view-switch/view-switch.component.ts @@ -27,7 +27,7 @@ export class ViewSwitchComponent { }); protected readonly canSwitchToRedactedView = computed(() => { const file = this._state.file(); - return !file.analysisRequired && !file.excluded && !file.isError; + return !file.excluded && !file.isError; }); protected readonly canSwitchToEarmarksView = computed(() => { const file = this._state.file(); diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts index 565b97eec..958ee18f9 100644 --- a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts @@ -152,6 +152,13 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this._fileDataService.loadAnnotations(file).then(); }); + effect(() => { + const file = this.state.file(); + if (file.analysisRequired && !file.excludedFromAutomaticAnalysis) { + this._reanalysisService.reanalyzeFilesForDossier([file], file.dossierId, { force: true }).then(); + } + }); + effect( () => { if (this._documentViewer.loaded()) { @@ -350,10 +357,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this.userPreferenceService.saveLastOpenedFileForDossier(this.dossierId, this.fileId).then(); this.#subscribeToFileUpdates(); - if (file?.analysisRequired && !file.excludedFromAutomaticAnalysis) { - await this._reanalysisService.reanalyzeFilesForDossier([file], this.dossierId, { force: true }); - } - this.pdfProxyService.configureElements(); this.#restoreOldFilters(); this.pdf.instance.UI.hotkeys.on('esc', this.handleEscInsideViewer); From 3677b7d761736a474db866ef5417b48a49c799ae Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Wed, 4 Sep 2024 14:39:44 +0300 Subject: [PATCH 006/125] RED-9950: decreased component management width. --- .../editable-structured-component-value.component.scss | 5 +++-- .../components/file-workload/file-workload.component.scss | 2 +- .../structured-component-management.component.scss | 3 ++- .../file-preview/file-preview-screen.component.scss | 2 +- apps/red-ui/src/styles.scss | 8 +++++--- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/editable-structured-component-value/editable-structured-component-value.component.scss b/apps/red-ui/src/app/modules/file-preview/components/editable-structured-component-value/editable-structured-component-value.component.scss index 4f296a8f1..8e4b4194b 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/editable-structured-component-value/editable-structured-component-value.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/components/editable-structured-component-value/editable-structured-component-value.component.scss @@ -3,11 +3,12 @@ flex-direction: row; padding: 10px 0 10px 0; margin-left: 14px; - margin-right: 26px; + margin-right: 20px; position: relative; .component { width: 40%; + margin-right: 8px; } .value { @@ -72,7 +73,7 @@ } .value { - margin-right: 26px; + margin-right: 20px; } } diff --git a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.scss b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.scss index 87df23079..78536d529 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.scss @@ -43,7 +43,7 @@ flex-direction: column; &.documine-width { - width: calc(var(--documine-workload-content-width) - 50px); + width: calc(var(--documine-workload-content-width) - 55px); border-right: 1px solid var(--iqser-separator); z-index: 1; diff --git a/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.scss b/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.scss index 783169c29..a7249fb59 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.scss @@ -24,7 +24,8 @@ mat-icon { display: flex; flex-direction: column; font-size: 12px; - overflow: scroll; + overflow-x: hidden; + overflow-y: scroll; height: calc(100% - 40px); .component-row { diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.scss b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.scss index caada04ca..a31b3ef87 100644 --- a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.scss @@ -39,7 +39,7 @@ } &.documine-container { - width: 60%; + width: 70%; // this and --structured-component-management-width should sum up to 100% } } diff --git a/apps/red-ui/src/styles.scss b/apps/red-ui/src/styles.scss index 3af183e3e..4b3f0586b 100644 --- a/apps/red-ui/src/styles.scss +++ b/apps/red-ui/src/styles.scss @@ -164,13 +164,13 @@ $dark-accent-10: darken(vars.$accent, 10%); body { --workload-width: 350px; --documine-workload-content-width: 287px; - --structured-component-management-width: 40%; + --structured-component-management-width: 30%; --quick-navigation-width: 61px; --iqser-app-name-font-family: OpenSans Extrabold, sans-serif; --iqser-app-name-font-size: 13px; --iqser-logo-size: 28px; --documine-viewer-width: calc( - 100% - var(--structured-component-management-width) - calc(var(--documine-workload-content-width) - 50px) - var( + 100% - var(--structured-component-management-width) - calc(var(--documine-workload-content-width) - 55px) - var( --quick-navigation-width ) - 3px ); @@ -196,7 +196,9 @@ body { &.document-info { width: calc( - 100% - var(--structured-component-management-width) - var(--documine-workload-content-width) - var(--workload-width) - 3px + 100% - var(--structured-component-management-width) - calc(var(--documine-workload-content-width) - 55px) - var( + --workload-width + ) - 3px ); right: calc(var(--workload-width) + 1px); } From 66cd961fc34a282f16104050e23d71d4e9c0b5ec Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Wed, 4 Sep 2024 15:49:41 +0300 Subject: [PATCH 007/125] WIP on master RED-9962 - RM-163: Components values are not updated in the UI until page is refreshed --- .../structured-component-management.component.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.ts b/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.ts index 0ec8d38ea..20a3313e2 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, OnInit, signal, ViewChildren } from '@angular/core'; +import { Component, effect, Input, OnInit, signal, ViewChildren } from '@angular/core'; import { List } from '@common-ui/utils'; import { IconButtonTypes, LoadingService } from '@iqser/common-ui'; import { ComponentLogEntry, Dictionary, File, IComponentLogEntry, WorkflowFileStatuses } from '@red/domain'; @@ -11,6 +11,7 @@ import { map } from 'rxjs/operators'; import { toObservable } from '@angular/core/rxjs-interop'; import { AsyncPipe, NgForOf, NgIf } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; +import { FilePreviewStateService } from '../../services/file-preview-state.service'; @Component({ selector: 'redaction-structured-component-management', @@ -33,7 +34,13 @@ export class StructuredComponentManagementComponent implements OnInit { private readonly _loadingService: LoadingService, private readonly _componentLogFilterService: ComponentLogFilterService, private readonly _filterService: FilterService, - ) {} + private readonly _state: FilePreviewStateService, + ) { + effect(async () => { + this._state.file(); + await this.#loadData(); + }); + } get canEdit() { return this.file.workflowStatus !== WorkflowFileStatuses.APPROVED; @@ -75,7 +82,6 @@ export class StructuredComponentManagementComponent implements OnInit { } async #loadData(): Promise { - this._loadingService.start(); const componentLogData = await firstValueFrom( this._componentLogService.getComponentLogData( this.file.dossierTemplateId, @@ -86,7 +92,6 @@ export class StructuredComponentManagementComponent implements OnInit { ); this.#computeFilters(componentLogData); this.componentLogData.set(componentLogData); - this._loadingService.stop(); } #computeFilters(componentLogs: ComponentLogEntry[]) { From e752e4607c91facb8d137a5934618bb820f86a2e Mon Sep 17 00:00:00 2001 From: project_703_bot_497bb7eb186ca592c63b3e50cd5c69e1 Date: Thu, 5 Sep 2024 01:03:30 +0000 Subject: [PATCH 008/125] push back localazy update --- apps/red-ui/src/assets/i18n/redact/de.json | 5 ++++- apps/red-ui/src/assets/i18n/scm/de.json | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index f630f4d70..09ccabbb5 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -207,11 +207,14 @@ "generic": "Speichern des Benutzers fehlgeschlagen." }, "form": { + "account-setup": "User account setup", "email": "E-Mail", "first-name": "Vorname", "last-name": "Nachname", "reset-password": "Passwort zurücksetzen", - "role": "Rolle" + "role": "Rolle", + "send-email": "Do not send email requesting the user to set a password", + "send-email-explanation": "Select this option if you use SSO. Please note that you will need to inform the user directly." }, "title": "{type, select, edit{Benutzer bearbeiten} create{Neuen Benutzer erstellen} other{}}" }, diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 6adf5369f..3348899e0 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -207,11 +207,14 @@ "generic": "Benutzer konnte nicht gespeichert werden!" }, "form": { + "account-setup": "User account setup", "email": "E-Mail", "first-name": "Vorname", "last-name": "Nachname", "reset-password": "Passwort zurücksetzen", - "role": "Rolle" + "role": "Rolle", + "send-email": "Do not send email requesting the user to set a password", + "send-email-explanation": "Select this option if you use SSO. Please note that you will need to inform the user directly." }, "title": "{type, select, edit{Benutzer bearbeiten} create{Neuen Benutzer hinzufügen} other{}}" }, From 34be5155c48d4051ebe234b03a57a1609eddd6eb Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Thu, 5 Sep 2024 14:23:41 +0300 Subject: [PATCH 009/125] RED-9548 - updated isModifyDictionary check --- apps/red-ui/src/app/models/file/annotation-permissions.utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/red-ui/src/app/models/file/annotation-permissions.utils.ts b/apps/red-ui/src/app/models/file/annotation-permissions.utils.ts index be5b01235..0924121ca 100644 --- a/apps/red-ui/src/app/models/file/annotation-permissions.utils.ts +++ b/apps/red-ui/src/app/models/file/annotation-permissions.utils.ts @@ -28,7 +28,7 @@ export const canRemoveOnlyHere = (annotation: AnnotationWrapper, canAddRedaction (annotation.isRedacted || (annotation.isHint && !annotation.isImage)); export const canRemoveFromDictionary = (annotation: AnnotationWrapper, autoAnalysisDisabled: boolean) => - annotation.isModifyDictionary && + (annotation.isModifyDictionary || annotation.engines.includes('DICTIONARY') || annotation.engines.includes('DOSSIER_DICTIONARY')) && (annotation.isRedacted || annotation.isSkipped || annotation.isHint || (annotation.isIgnoredHint && !annotation.isRuleBased)) && (autoAnalysisDisabled || !annotation.pending) && annotation.isDictBased; From 24c433dd5bab725c8b6805a3dbf6610c412a1398 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Thu, 5 Sep 2024 14:58:44 +0300 Subject: [PATCH 010/125] RED-9950: increased component management section width by 5%. --- .../app/modules/file-preview/file-preview-screen.component.scss | 2 +- apps/red-ui/src/styles.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.scss b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.scss index a31b3ef87..aab876db5 100644 --- a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.scss @@ -39,7 +39,7 @@ } &.documine-container { - width: 70%; // this and --structured-component-management-width should sum up to 100% + width: calc(100% - var(--structured-component-management-width)); } } diff --git a/apps/red-ui/src/styles.scss b/apps/red-ui/src/styles.scss index 4b3f0586b..071efef6e 100644 --- a/apps/red-ui/src/styles.scss +++ b/apps/red-ui/src/styles.scss @@ -164,7 +164,7 @@ $dark-accent-10: darken(vars.$accent, 10%); body { --workload-width: 350px; --documine-workload-content-width: 287px; - --structured-component-management-width: 30%; + --structured-component-management-width: 35%; --quick-navigation-width: 61px; --iqser-app-name-font-family: OpenSans Extrabold, sans-serif; --iqser-app-name-font-size: 13px; From 8f938c825d323710a93367778815ed355606d12a Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Thu, 5 Sep 2024 17:17:32 +0300 Subject: [PATCH 011/125] RED-9372: fixed annotation details moving on hover. --- .../annotation-details.component.scss | 2 +- .../annotations-list/annotations-list.component.scss | 12 ++---------- .../structured-component-management.component.scss | 4 ++++ 3 files changed, 7 insertions(+), 11 deletions(-) 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 8a2928722..b2bdcbeb9 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 @@ -2,7 +2,7 @@ display: flex; position: absolute; top: 6px; - right: 19px; + right: 8px; } .popover { diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.scss b/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.scss index 1623da0aa..3913c6b0a 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.scss @@ -3,21 +3,13 @@ :host { width: 100%; position: relative; - overflow: hidden; - - &:hover { - overflow-y: auto; - @include common-mixins.scroll-bar; - } + overflow-y: auto; + @include common-mixins.scroll-bar; &.has-scrollbar:hover redaction-annotation-wrapper::ng-deep, &::ng-deep.documine-wrapper { .annotation { padding-right: 5px; } - - redaction-annotation-details { - right: 8px; - } } } diff --git a/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.scss b/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.scss index a7249fb59..ffc3f5364 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.scss @@ -1,3 +1,5 @@ +@use 'common-mixins'; + .components-header { display: flex; flex-direction: row; @@ -27,6 +29,7 @@ mat-icon { overflow-x: hidden; overflow-y: scroll; height: calc(100% - 40px); + @include common-mixins.scroll-bar; .component-row { display: flex; @@ -47,6 +50,7 @@ mat-icon { &:not(:last-child) { border-bottom: 1px solid var(--iqser-separator); } + border-bottom: 1px solid var(--iqser-separator); margin-right: 13px; } From ef8b1bc58eba0dd94f161a202125314c69e344e8 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Thu, 5 Sep 2024 17:17:49 +0300 Subject: [PATCH 012/125] RED-9372: update common ui. --- libs/common-ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/common-ui b/libs/common-ui index 9bc05f116..81513d34d 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 9bc05f11657da806743718dc9cbd1cc4f5af10a7 +Subproject commit 81513d34dc3bf6c80313b2e38f50d1a6d6805280 From 93321437c177c38b39686af437a870c8e3e96576 Mon Sep 17 00:00:00 2001 From: project_703_bot_497bb7eb186ca592c63b3e50cd5c69e1 Date: Tue, 10 Sep 2024 01:03:26 +0000 Subject: [PATCH 013/125] push back localazy update --- apps/red-ui/src/assets/i18n/redact/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index 27acfb116..765ae48f9 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -1542,7 +1542,7 @@ }, "reanalyse-notification": "Start reanalysis", "redacted": "Preview", - "redacted-tooltip": "Redaction preview shows only redactions. Consider this a preview for the final redacted version. This view is only available if the file has no pending changes & doesn't require a reanalysis", + "redacted-tooltip": "The preview shows only the redactions. It is a preview of the final redacted version.", "standard": "Standard", "standard-tooltip": "Standard shows all annotation types and allows for editing.", "tabs": { From 4475f5979e35608faa91fbd318fb15079d7af56b Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Tue, 10 Sep 2024 09:45:35 +0300 Subject: [PATCH 014/125] RED-10016 - DM: Permanent loading triggerd when trying to edit the component --- .../structured-component-management.component.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.ts b/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.ts index 20a3313e2..9f1d4c66e 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.ts @@ -92,6 +92,7 @@ export class StructuredComponentManagementComponent implements OnInit { ); this.#computeFilters(componentLogData); this.componentLogData.set(componentLogData); + this._loadingService.stop(); } #computeFilters(componentLogs: ComponentLogEntry[]) { From e6f3cd77de53f1d705711371c3268fbcf7f85a21 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Tue, 10 Sep 2024 11:36:29 +0300 Subject: [PATCH 015/125] RED-9372: fixed scrolling on dossier details. --- .../screen/dossier-overview-screen.component.html | 2 +- .../screen/dossier-overview-screen.component.scss | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/apps/red-ui/src/app/modules/dossier-overview/screen/dossier-overview-screen.component.html b/apps/red-ui/src/app/modules/dossier-overview/screen/dossier-overview-screen.component.html index f5976b5ed..63002d513 100644 --- a/apps/red-ui/src/app/modules/dossier-overview/screen/dossier-overview-screen.component.html +++ b/apps/red-ui/src/app/modules/dossier-overview/screen/dossier-overview-screen.component.html @@ -56,7 +56,7 @@
-
+
Date: Tue, 10 Sep 2024 11:38:23 +0300 Subject: [PATCH 016/125] RED-9372: update common ui. --- libs/common-ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/common-ui b/libs/common-ui index 81513d34d..2faecb44a 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 81513d34dc3bf6c80313b2e38f50d1a6d6805280 +Subproject commit 2faecb44a926f02a6d4186e58751ac615f2bfd47 From feb3aa34e955d6217c645ad70dbecea56eb9d7a7 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Fri, 13 Sep 2024 10:58:25 +0300 Subject: [PATCH 017/125] RED-9993: fixed license information. --- .../license-analysis-capacity-usage.component.ts | 7 ++----- .../license-page-usage/license-page-usage.component.ts | 7 ++----- .../app/modules/admin/screens/license/utils/functions.ts | 5 ++--- apps/red-ui/src/app/modules/shared/CustomDateAdapter.ts | 2 ++ 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/screens/license/components/license-analysis-capacity-usage/license-analysis-capacity-usage.component.ts b/apps/red-ui/src/app/modules/admin/screens/license/components/license-analysis-capacity-usage/license-analysis-capacity-usage.component.ts index e6ad9de2f..7995cd9bb 100644 --- a/apps/red-ui/src/app/modules/admin/screens/license/components/license-analysis-capacity-usage/license-analysis-capacity-usage.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/license/components/license-analysis-capacity-usage/license-analysis-capacity-usage.component.ts @@ -60,11 +60,8 @@ export class LicenseAnalysisCapacityUsageComponent { }, { - data: dataUntilCurrentMonth.map((month, monthIndex) => - month.analysedFilesBytes - ? month.analysedFilesBytes + - monthlyData.slice(0, monthIndex).reduce((acc, curr) => acc + (curr.analysedFilesBytes ?? 0), 0) - : 0, + data: dataUntilCurrentMonth.map((_, monthIndex) => + monthlyData.slice(0, monthIndex + 1).reduce((acc, curr) => acc + (curr.analysedFilesBytes ?? 0), 0), ), label: this._translateService.instant('license-info-screen.analysis-capacity-usage.analyzed-cumulative'), yAxisID: 'y1', diff --git a/apps/red-ui/src/app/modules/admin/screens/license/components/license-page-usage/license-page-usage.component.ts b/apps/red-ui/src/app/modules/admin/screens/license/components/license-page-usage/license-page-usage.component.ts index 9321df252..7a3c1d3ab 100644 --- a/apps/red-ui/src/app/modules/admin/screens/license/components/license-page-usage/license-page-usage.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/license/components/license-page-usage/license-page-usage.component.ts @@ -63,11 +63,8 @@ export class LicensePageUsageComponent { order: 1, }, { - data: dataUntilCurrentMonth.map((month, monthIndex) => - month.numberOfAnalyzedPages - ? month.numberOfAnalyzedPages + - monthlyData.slice(0, monthIndex).reduce((acc, curr) => acc + (curr.numberOfAnalyzedPages ?? 0), 0) - : 0, + data: dataUntilCurrentMonth.map((_, monthIndex) => + monthlyData.slice(0, monthIndex + 1).reduce((acc, curr) => acc + (curr.numberOfAnalyzedPages ?? 0), 0), ), label: this._translateService.instant('license-info-screen.page-usage.cumulative-pages'), yAxisID: 'y1', diff --git a/apps/red-ui/src/app/modules/admin/screens/license/utils/functions.ts b/apps/red-ui/src/app/modules/admin/screens/license/utils/functions.ts index 6ea6bf796..2c3a9ce3e 100644 --- a/apps/red-ui/src/app/modules/admin/screens/license/utils/functions.ts +++ b/apps/red-ui/src/app/modules/admin/screens/license/utils/functions.ts @@ -6,7 +6,6 @@ import { ComplexFillTarget } from 'chart.js/dist/types'; const monthNames = dayjs.monthsShort(); const currentMonth = dayjs(Date.now()).month(); -const currentYear = dayjs(Date.now()).year(); export const verboseDate = (date: Dayjs) => `${monthNames[date.month()]} ${date.year()}`; @@ -53,9 +52,9 @@ export const getLabelsFromLicense = (license: ILicenseReport) => { }; export const getDataUntilCurrentMonth = (monthlyData: ILicenseData[]) => { - return monthlyData.filter(data => dayjs(data.startDate).month() <= currentMonth && dayjs(data.startDate).year() <= currentYear); + return monthlyData.filter(data => dayjs(data.startDate).isSameOrBefore(dayjs(Date.now()), 'month')); }; export const isCurrentMonthAndYear = (date: Date | string) => { - return dayjs(date).month() === currentMonth && dayjs(date).year() === currentYear; + return dayjs(date).isSame(dayjs(Date.now()), 'month') && dayjs(date).isSame(dayjs(Date.now()), 'year'); }; diff --git a/apps/red-ui/src/app/modules/shared/CustomDateAdapter.ts b/apps/red-ui/src/app/modules/shared/CustomDateAdapter.ts index e2a9337cf..3c19554ca 100644 --- a/apps/red-ui/src/app/modules/shared/CustomDateAdapter.ts +++ b/apps/red-ui/src/app/modules/shared/CustomDateAdapter.ts @@ -10,6 +10,7 @@ import utc from 'dayjs/plugin/utc'; import localeData from 'dayjs/plugin/localeData'; import localizedFormat from 'dayjs/plugin/localizedFormat'; import customParseFormat from 'dayjs/plugin/customParseFormat'; +import isSameOrBefore from 'dayjs/plugin/isSameOrBefore'; export interface DayJsDateAdapterOptions { /** @@ -232,6 +233,7 @@ export class CustomDateAdapter extends DateAdapter { dayjs.extend(localizedFormat); dayjs.extend(customParseFormat); dayjs.extend(localeData); + dayjs.extend(isSameOrBefore); this.setLocale(dateLocale); } From 2f6d4604427ff16ce8e1dc69e50a1ae8a0f55af9 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Mon, 16 Sep 2024 21:16:06 +0300 Subject: [PATCH 018/125] RED-7345 - WIP Add/Remove bulk-local text redaction option in dialogs --- .../modules/account/utils/dialog-defaults.ts | 7 +- .../force-annotation-dialog.component.html | 58 ++++--- .../force-annotation-dialog.component.ts | 10 ++ .../redact-recommendation-dialog.component.ts | 9 +- .../redact-text-dialog.component.scss | 2 +- .../redact-text-dialog.component.ts | 19 ++- .../remove-redaction-dialog.component.ts | 13 +- .../file-preview-screen.component.ts | 1 + .../services/annotation-actions.service.ts | 28 ++- .../services/manual-redaction.service.ts | 22 ++- .../services/pdf-proxy.service.ts | 1 + .../file-preview/utils/dialog-options.ts | 40 +++++ .../file-preview/utils/dialog-types.ts | 12 ++ .../translations/redact-text-translations.ts | 6 +- .../remove-annotation-translations.ts | 4 + .../remove-redaction-translations.ts | 4 + apps/red-ui/src/assets/config/config.json | 4 +- apps/red-ui/src/assets/i18n/redact/de.json | 161 ++++++++++-------- apps/red-ui/src/assets/i18n/redact/en.json | 15 +- apps/red-ui/src/assets/i18n/scm/de.json | 161 ++++++++++-------- apps/red-ui/src/assets/i18n/scm/en.json | 15 +- libs/common-ui | 2 +- .../legal-basis/legal-basis-change.request.ts | 3 + .../redaction-log/remove-redaction.request.ts | 1 + 24 files changed, 391 insertions(+), 207 deletions(-) diff --git a/apps/red-ui/src/app/modules/account/utils/dialog-defaults.ts b/apps/red-ui/src/app/modules/account/utils/dialog-defaults.ts index a723d5878..b5090ec0d 100644 --- a/apps/red-ui/src/app/modules/account/utils/dialog-defaults.ts +++ b/apps/red-ui/src/app/modules/account/utils/dialog-defaults.ts @@ -2,11 +2,12 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { addHintTranslations } from '@translations/add-hint-translations'; import { redactTextTranslations } from '@translations/redact-text-translations'; import { removeRedactionTranslations } from '@translations/remove-redaction-translations'; -import { RedactOrHintOptions, RemoveRedactionOptions } from '../../file-preview/utils/dialog-types'; +import { ForceAnnotationOptions, RedactOrHintOptions, RemoveRedactionOptions } from '../../file-preview/utils/dialog-types'; export const SystemDefaults = { ADD_REDACTION_DEFAULT: RedactOrHintOptions.IN_DOSSIER, ADD_HINT_DEFAULT: RedactOrHintOptions.IN_DOSSIER, + FORCE_REDACTION_DEFAULT: ForceAnnotationOptions.ONLY_HERE, REMOVE_REDACTION_DEFAULT: RemoveRedactionOptions.ONLY_HERE, REMOVE_HINT_DEFAULT: RemoveRedactionOptions.ONLY_HERE, REMOVE_RECOMMENDATION_DEFAULT: RemoveRedactionOptions.DO_NOT_RECOMMEND, @@ -28,6 +29,10 @@ export const redactionAddOptions = [ label: redactTextTranslations.onlyHere.label, value: RedactOrHintOptions.ONLY_HERE, }, + { + label: redactTextTranslations.inDocument.label, + value: RedactOrHintOptions.IN_DOCUMENT, + }, { label: redactTextTranslations.inDossier.label, value: RedactOrHintOptions.IN_DOSSIER, diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.html index 8d9139b12..9a34be925 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.html +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.html @@ -2,32 +2,40 @@
-
- -
- - - - - {{ option.label }} - - - -
+
+ @if (!isImageHint) { + + } -
- - -
+ @if (!isHintDialog && !isDocumine) { + + +
+ + + + @for (option of legalOptions; track option) { + + {{ option.label }} + + } + + +
+ +
+ + +
+ }
diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts index 28630826d..2bf000c19 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts @@ -25,6 +25,11 @@ import { MatFormField } from '@angular/material/form-field'; import { MatOption, MatSelect, MatSelectTrigger } from '@angular/material/select'; import { MatTooltip } from '@angular/material/tooltip'; import { TranslateModule } from '@ngx-translate/core'; +import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option'; +import { ForceAnnotationOption, RedactOrHintOption } from '../../utils/dialog-types'; +import { getForceAnnotationOptions, getRedactOrHintOptions } from '../../utils/dialog-options'; +import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component'; +import { SystemDefaults } from '../../../account/utils/dialog-defaults'; export interface LegalBasisOption { label?: string; @@ -55,10 +60,12 @@ const DOCUMINE_LEGAL_BASIS = 'n-a.'; CircleButtonComponent, NgForOf, HelpButtonComponent, + DetailsRadioComponent, ], }) export class ForceAnnotationDialogComponent extends BaseDialogComponent implements OnInit { readonly isDocumine = getConfig().IS_DOCUMINE; + readonly options: DetailsRadioOption[]; readonly tableColumns = [ { @@ -85,6 +92,7 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen private readonly _data: { readonly dossier: Dossier; readonly hint: boolean; annotations: AnnotationWrapper[] }, ) { super(_dialogRef); + this.options = getForceAnnotationOptions(this.isDocumine, this.isHintDialog); this.form = this.#getForm(); } @@ -137,6 +145,7 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen return this._formBuilder.group({ reason: this._data.hint ? ['Forced Hint'] : [null, !this.isDocumine ? Validators.required : null], comment: [null], + option: this.options.find(o => o.value === SystemDefaults.FORCE_REDACTION_DEFAULT), }); } @@ -145,6 +154,7 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen request.legalBasis = !this.isDocumine ? this.form.get('reason').value.legalBasis : DOCUMINE_LEGAL_BASIS; request.comment = this.form.get('comment').value; + request.option = this.form.get('option').value.value; return request; } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts index dc50676e2..ef4ce7d20 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts @@ -22,7 +22,13 @@ import { ValueColumn, } from '../../components/selected-annotations-table/selected-annotations-table.component'; import { getRedactOrHintOptions } from '../../utils/dialog-options'; -import { RedactOrHintOption, RedactOrHintOptions, RedactRecommendationData, RedactRecommendationResult } from '../../utils/dialog-types'; +import { + RedactOrHintOption, + RedactOrHintOptions, + RedactRecommendationData, + RedactRecommendationResult, + ResizeOptions, +} from '../../utils/dialog-types'; import { LegalBasisOption } from '../manual-redaction-dialog/manual-annotation-dialog.component'; @Component({ @@ -156,6 +162,7 @@ export class RedactRecommendationDialogComponent this.close({ redaction, isMulti: this.isMulti, + bulkLocal: this.form.controls.option.value.value === ResizeOptions.IN_DOCUMENT, }); } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.scss b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.scss index 22fe3116d..64afce14d 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.scss @@ -1,5 +1,5 @@ .dialog-content { - height: 493px; + height: 530px; overflow-y: auto; } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts index ceea04f86..df94ab8bb 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts @@ -21,7 +21,7 @@ import { firstValueFrom, Observable } from 'rxjs'; import { map, tap } from 'rxjs/operators'; import { SystemDefaultOption, SystemDefaults } from '../../../account/utils/dialog-defaults'; import { getRedactOrHintOptions } from '../../utils/dialog-options'; -import { RedactOrHintOption, RedactOrHintOptions, RedactTextData, RedactTextResult } from '../../utils/dialog-types'; +import { RedactOrHintOption, RedactOrHintOptions, RedactTextData, RedactTextResult, ResizeOptions } from '../../utils/dialog-types'; import { LegalBasisOption } from '../manual-redaction-dialog/manual-annotation-dialog.component'; const MAXIMUM_TEXT_AREA_WIDTH = 421; @@ -165,7 +165,7 @@ export class RedactTextDialogComponent if (!this.#applyToAllDossiers) { const selectedDictionaryType = this.form.controls.dictionary.value; const selectedDictionary = this.dictionaries.find(d => d.type === selectedDictionaryType); - this.options[1].extraOption.disabled = selectedDictionary.dossierDictionaryOnly; + this.options[2].extraOption.disabled = selectedDictionary.dossierDictionaryOnly; } } @@ -175,6 +175,7 @@ export class RedactTextDialogComponent this.close({ redaction, dictionary: this.dictionaries.find(d => d.type === this.form.controls.dictionary.value), + bulkLocal: this.form.controls.option.value.value === ResizeOptions.IN_DOCUMENT, }); } @@ -188,14 +189,18 @@ export class RedactTextDialogComponent #setupValidators(option: RedactOrHintOption) { switch (option) { - case RedactOrHintOptions.IN_DOSSIER: - this.form.controls.reason.clearValidators(); - this.form.controls.dictionary.addValidators(Validators.required); - break; case RedactOrHintOptions.ONLY_HERE: this.form.controls.dictionary.clearValidators(); this.form.controls.reason.addValidators(Validators.required); break; + case RedactOrHintOptions.IN_DOCUMENT: + this.form.controls.dictionary.clearValidators(); + this.form.controls.reason.addValidators(Validators.required); + break; + case RedactOrHintOptions.IN_DOSSIER: + this.form.controls.reason.clearValidators(); + this.form.controls.dictionary.addValidators(Validators.required); + break; } this.form.controls.reason.updateValueAndValidity(); @@ -251,7 +256,7 @@ export class RedactTextDialogComponent #resetValues() { this.#applyToAllDossiers = this.applyToAll; - this.options[1].extraOption.checked = this.#applyToAllDossiers; + this.options[2].extraOption.checked = this.#applyToAllDossiers; if (this.dictionaryRequest) { this.form.controls.reason.setValue(null); this.form.controls.dictionary.setValue(null); diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts index 431d41fbc..48e4d99d2 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts @@ -26,7 +26,13 @@ import { } from '../../components/selected-annotations-table/selected-annotations-table.component'; import { DialogHelpModeKeys } from '../../utils/constants'; import { getRemoveRedactionOptions } from '../../utils/dialog-options'; -import { RemoveRedactionData, RemoveRedactionOption, RemoveRedactionOptions, RemoveRedactionResult } from '../../utils/dialog-types'; +import { + RemoveRedactionData, + RemoveRedactionOption, + RemoveRedactionOptions, + RemoveRedactionResult, + ResizeOptions, +} from '../../utils/dialog-types'; @Component({ templateUrl: './remove-redaction-dialog.component.html', @@ -174,7 +180,10 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< } save(): void { - this.close(this.form.getRawValue()); + this.close({ + ...this.form.getRawValue(), + bulkLocal: this.form.controls.option.value.value === ResizeOptions.IN_DOCUMENT, + }); } #getOption(option: RemoveRedactionOption): DetailsRadioOption { diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts index 958ee18f9..7701d687c 100644 --- a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts @@ -468,6 +468,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni const add$ = this._manualRedactionService.addAnnotation([result.redaction], this.dossierId, this.fileId, { hint, dictionaryLabel: result.dictionary?.label, + bulkLocal: result.bulkLocal, }); const addAndReload$ = add$.pipe( diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts index 7673762e6..519cf8c7a 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts @@ -32,6 +32,7 @@ import { ResizeRedactionDialogComponent } from '../dialogs/resize-redaction-dial import { EditRedactionData, EditRedactResult, + ForceAnnotationOptions, RemoveRedactionData, RemoveRedactionOptions, RemoveRedactionPermissions, @@ -80,14 +81,22 @@ export class AnnotationActionsService { const { dossierId, fileId } = this._state; const data = { dossier: this._state.dossier(), annotations, hint }; this._dialogService.openDialog('forceAnnotation', data, (request: ILegalBasisChangeRequest) => { - this.#processObsAndEmit( - this._manualRedactionService.bulkForce( + let obs$; + if (request.option === ForceAnnotationOptions.ONLY_HERE) { + obs$ = this._manualRedactionService.bulkForce( annotations.map(a => ({ ...request, annotationId: a.id })), dossierId, fileId, annotations[0].isIgnoredHint, - ), - ).then(); + ); + } else { + console.log('annotation: ', annotations[0]); + obs$ = this._manualRedactionService.addAnnotation(annotations, dossierId, fileId, { + hint, + bulkLocal: true, + }); + } + this.#processObsAndEmit(obs$).then(); }); } @@ -436,6 +445,7 @@ export class AnnotationActionsService { const includeUnprocessed = redactions.every(redaction => this.#includeUnprocessed(redaction, true)); const body = redactions.map(redaction => ({ annotationId: redaction.id, + value: redaction.value, comment: dialogResult.comment, removeFromDictionary, removeFromAllDossiers: !!dialogResult.option.extraOption?.checked || !!dialogResult.applyToAllDossiers, @@ -444,7 +454,15 @@ export class AnnotationActionsService { const isHint = redactions.every(r => r.isHint); const { dossierId, fileId } = this._state; this.#processObsAndEmit( - this._manualRedactionService.removeRedaction(body, dossierId, fileId, removeFromDictionary, isHint, includeUnprocessed), + this._manualRedactionService.removeRedaction( + body, + dossierId, + fileId, + removeFromDictionary, + isHint, + includeUnprocessed, + dialogResult.bulkLocal, + ), ).then(); } diff --git a/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts b/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts index dd90f6be4..630592f99 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts @@ -39,6 +39,7 @@ function getMessage(action: ManualRedactionActions, isDictionary = false, error export class ManualRedactionService extends GenericService { protected readonly _defaultModelPath = 'manualRedaction'; readonly #bulkRedaction = `${this._defaultModelPath}/bulk/redaction`; + readonly #bulkLocal = `${this._defaultModelPath}/bulk-local`; constructor( private readonly _toaster: Toaster, @@ -80,14 +81,14 @@ export class ManualRedactionService extends GenericService { requests: List, dossierId: string, fileId: string, - options?: { hint?: boolean; dictionaryLabel?: string }, + options?: { hint?: boolean; dictionaryLabel?: string; bulkLocal?: boolean }, ) { const toast = requests[0].addToDictionary ? this.#showAddToDictionaryToast(requests, options?.dictionaryLabel) : this.#showToast(options?.hint ? 'force-hint' : 'add'); const canAddRedaction = this._iqserPermissionsService.has(Roles.redactions.write); if (canAddRedaction) { - return this.add(requests, dossierId, fileId).pipe(toast); + return this.add(requests, dossierId, fileId, options.bulkLocal).pipe(toast); } return of(undefined); @@ -108,8 +109,9 @@ export class ManualRedactionService extends GenericService { removeFromDictionary = false, isHint = false, includeUnprocessed = false, + bulkLocal = false, ) { - return this.remove(body, dossierId, fileId, includeUnprocessed).pipe( + return this.remove(body, dossierId, fileId, includeUnprocessed, bulkLocal).pipe( this.#showToast(!isHint ? 'remove' : 'remove-hint', removeFromDictionary), ); } @@ -127,8 +129,9 @@ export class ManualRedactionService extends GenericService { } } - add(body: List, dossierId: string, fileId: string) { - return this._post(body, `${this.#bulkRedaction}/add/${dossierId}/${fileId}`).pipe(this.#log('Add', body)); + add(body: List, dossierId: string, fileId: string, bulkLocal = false) { + const bulkPath = bulkLocal ? this.#bulkLocal : this.#bulkRedaction; + return this._post(bulkLocal ? body[0] : body, `${bulkPath}/add/${dossierId}/${fileId}`).pipe(this.#log('Add', body)); } recategorize(body: List, dossierId: string, fileId: string, includeUnprocessed = false) { @@ -142,8 +145,13 @@ export class ManualRedactionService extends GenericService { return super.delete(annotationIds, url).pipe(this.#log('Undo', annotationIds)); } - remove(body: List, dossierId: string, fileId: string, includeUnprocessed = false) { - return this._post(body, `${this.#bulkRedaction}/remove/${dossierId}/${fileId}?includeUnprocessed=${includeUnprocessed}`).pipe( + remove(body: List, dossierId: string, fileId: string, includeUnprocessed = false, bulkLocal = false) { + const bulkPath = bulkLocal ? this.#bulkLocal : this.#bulkRedaction; + const newBody = { + value: body[0].value, + rectangle: false, + }; + return this._post(newBody, `${bulkPath}/remove/${dossierId}/${fileId}?includeUnprocessed=${includeUnprocessed}`).pipe( this.#log('Remove', body), ); } diff --git a/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts b/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts index 976be8626..607d21538 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts @@ -224,6 +224,7 @@ export class PdfProxyService { const selectedQuads: Record = this._pdf.documentViewer.getSelectedTextQuads(); const text = this._documentViewer.selectedText; const manualRedactionEntry = this.#getManualRedaction(selectedQuads, text, true); + console.log('manualRedactionEntry: ', manualRedactionEntry); this.redactTextRequested$.next({ manualRedactionEntry, type }); } diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts index 7aff7bccd..217c4e891 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts @@ -7,6 +7,7 @@ import { removeAnnotationTranslations } from '@translations/remove-annotation-tr import { removeRedactionTranslations } from '@translations/remove-redaction-translations'; import { resizeRedactionTranslations } from '@translations/resize-redaction-translations'; import { + ForceAnnotationOption, RedactOrHintOption, RedactOrHintOptions, RemoveRedactionData, @@ -17,6 +18,7 @@ import { } from './dialog-types'; const PIN_ICON = 'red:push-pin'; +const DOCUMENT_ICON = 'iqser:document'; const FOLDER_ICON = 'red:folder'; const REMOVE_FROM_DICT_ICON = 'red:remove-from-dict'; @@ -77,6 +79,15 @@ export const getRedactOrHintOptions = ( return options; } + if (!isHint) { + options.push({ + label: redactTextTranslations.inDocument.label, + description: redactTextTranslations.inDocument.description, + icon: DOCUMENT_ICON, + value: ResizeOptions.IN_DOCUMENT, + }); + } + options.push({ label: translations.inDossier.label, description: translations.inDossier.description, @@ -140,6 +151,7 @@ export const getRemoveRedactionOptions = ( applyToAllDossiers: boolean, isDocumine: boolean = false, ): DetailsRadioOption[] => { + console.log('TEST'); const translations = isDocumine ? removeAnnotationTranslations : removeRedactionTranslations; const { permissions, redactions, isApprover, falsePositiveContext } = data; const isBulk = redactions.length > 1; @@ -156,6 +168,13 @@ export const getRemoveRedactionOptions = ( icon: PIN_ICON, value: RemoveRedactionOptions.ONLY_HERE, }); + + options.push({ + label: removeRedactionTranslations.IN_DOCUMENT.label, + description: removeRedactionTranslations.IN_DOCUMENT.description, + icon: DOCUMENT_ICON, + value: RemoveRedactionOptions.IN_DOCUMENT, + }); } if (permissions.canRemoveFromDictionary) { options.push({ @@ -217,3 +236,24 @@ export const getRemoveRedactionOptions = ( } return options; }; + +export const getForceAnnotationOptions = (isDocumine: boolean, isHint: boolean): DetailsRadioOption[] => { + if (isDocumine || isHint) { + return []; + } + + return [ + { + label: redactTextTranslations.onlyHere.label, + description: redactTextTranslations.onlyHere.description, + icon: PIN_ICON, + value: ResizeOptions.ONLY_HERE, + }, + { + label: redactTextTranslations.inDocument.label, + description: redactTextTranslations.inDocument.description, + icon: DOCUMENT_ICON, + value: ResizeOptions.IN_DOCUMENT, + }, + ]; +}; diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts index 8fcac6603..d7efb27eb 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts @@ -5,16 +5,25 @@ import { Dictionary, Dossier, File, IAddRedactionRequest, IManualRedactionEntry export const RedactOrHintOptions = { ONLY_HERE: 'ONLY_HERE', + IN_DOCUMENT: 'IN_DOCUMENT', IN_DOSSIER: 'IN_DOSSIER', } as const; export type RedactOrHintOption = keyof typeof RedactOrHintOptions; +export const ForceAnnotationOptions = { + ONLY_HERE: 'ONLY_HERE', + IN_DOCUMENT: 'IN_DOCUMENT', +} as const; + +export type ForceAnnotationOption = keyof typeof ForceAnnotationOptions; + export const ResizeOptions = RedactOrHintOptions; export type ResizeRedactionOption = RedactOrHintOption; export const RemoveRedactionOptions = { ONLY_HERE: 'ONLY_HERE', + IN_DOCUMENT: 'IN_DOCUMENT', IN_DOSSIER: 'IN_DOSSIER', FALSE_POSITIVE: 'FALSE_POSITIVE', DO_NOT_RECOMMEND: 'DO_NOT_RECOMMEND', @@ -46,6 +55,7 @@ export type AddHintData = RedactTextData; export interface RedactTextResult { redaction: IManualRedactionEntry; dictionary: Dictionary; + bulkLocal?: boolean; } export type RedactRecommendationData = EditRedactionData; @@ -53,6 +63,7 @@ export type RedactRecommendationData = EditRedactionData; export interface RedactRecommendationResult { redaction: IAddRedactionRequest; isMulti: boolean; + bulkLocal: boolean; } export interface EditRedactResult { @@ -112,6 +123,7 @@ export interface RemoveRedactionResult { comment: string; option: DetailsRadioOption; applyToAllDossiers?: boolean; + bulkLocal?: boolean; } export type RemoveAnnotationResult = RemoveRedactionResult; diff --git a/apps/red-ui/src/app/translations/redact-text-translations.ts b/apps/red-ui/src/app/translations/redact-text-translations.ts index 76bfadb81..a5166ca86 100644 --- a/apps/red-ui/src/app/translations/redact-text-translations.ts +++ b/apps/red-ui/src/app/translations/redact-text-translations.ts @@ -9,11 +9,15 @@ export interface DialogOption { extraOptionDescription?: string; } -export const redactTextTranslations: Record<'onlyHere' | 'inDossier', DialogOption> = { +export const redactTextTranslations: Record<'onlyHere' | 'inDocument' | 'inDossier', DialogOption> = { onlyHere: { label: _('redact-text.dialog.content.options.only-here.label'), description: _('redact-text.dialog.content.options.only-here.description'), }, + inDocument: { + label: _('redact-text.dialog.content.options.in-document.label'), + description: _('redact-text.dialog.content.options.in-document.description'), + }, inDossier: { label: _('redact-text.dialog.content.options.in-dossier.label'), description: _('redact-text.dialog.content.options.in-dossier.description'), diff --git a/apps/red-ui/src/app/translations/remove-annotation-translations.ts b/apps/red-ui/src/app/translations/remove-annotation-translations.ts index 478c9de8d..e6cd09f1a 100644 --- a/apps/red-ui/src/app/translations/remove-annotation-translations.ts +++ b/apps/red-ui/src/app/translations/remove-annotation-translations.ts @@ -8,6 +8,10 @@ export const removeAnnotationTranslations: { [key in RemoveAnnotationOption]: Di description: _('remove-annotation.dialog.content.options.only-here.description'), descriptionBulk: _('remove-annotation.dialog.content.options.only-here.description-bulk'), }, + IN_DOCUMENT: { + label: _('remove-annotation.dialog.content.options.in-document.label'), + description: _('remove-annotation.dialog.content.options.in-document.description'), + }, IN_DOSSIER: { label: _('remove-annotation.dialog.content.options.in-dossier.label'), labelBulk: _('remove-annotation.dialog.content.options.in-dossier.label-bulk'), diff --git a/apps/red-ui/src/app/translations/remove-redaction-translations.ts b/apps/red-ui/src/app/translations/remove-redaction-translations.ts index 41d5f8b86..910415bca 100644 --- a/apps/red-ui/src/app/translations/remove-redaction-translations.ts +++ b/apps/red-ui/src/app/translations/remove-redaction-translations.ts @@ -8,6 +8,10 @@ export const removeRedactionTranslations: { [key in RemoveRedactionOption]: Dial description: _('remove-redaction.dialog.content.options.only-here.description'), descriptionBulk: _('remove-redaction.dialog.content.options.only-here.description-bulk'), }, + IN_DOCUMENT: { + label: _('remove-redaction.dialog.content.options.in-document.label'), + description: _('remove-redaction.dialog.content.options.in-document.description'), + }, IN_DOSSIER: { label: _('remove-redaction.dialog.content.options.in-dossier.label'), labelBulk: _('remove-redaction.dialog.content.options.in-dossier.label-bulk'), diff --git a/apps/red-ui/src/assets/config/config.json b/apps/red-ui/src/assets/config/config.json index 5f6c0ce6e..deb14e6da 100644 --- a/apps/red-ui/src/assets/config/config.json +++ b/apps/red-ui/src/assets/config/config.json @@ -1,7 +1,7 @@ { "ADMIN_CONTACT_NAME": null, "ADMIN_CONTACT_URL": null, - "API_URL": "https://dan2.iqser.cloud", + "API_URL": "https://dan1.iqser.cloud", "APP_NAME": "RedactManager", "IS_DOCUMINE": false, "RULE_EDITOR_DEV_ONLY": false, @@ -13,7 +13,7 @@ "MAX_RETRIES_ON_SERVER_ERROR": 3, "OAUTH_CLIENT_ID": "redaction", "OAUTH_IDP_HINT": null, - "OAUTH_URL": "https://dan2.iqser.cloud/auth", + "OAUTH_URL": "https://dan1.iqser.cloud/auth", "RECENT_PERIOD_IN_HOURS": 24, "SELECTION_MODE": "structural", "MANUAL_BASE_URL": "https://docs.redactmanager.com/preview", diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index 09ccabbb5..ea6e33f05 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -242,7 +242,6 @@ "label": "Nur hier hinzufügen" } }, - "selected-text": "Ausgewählter Text:", "type": "Typ", "type-placeholder": "Typ auswählen..." }, @@ -276,9 +275,6 @@ "watermarks": "Wasserzeichen" }, "analysis-disabled": "", - "annotation": { - "pending": "(Analyse steht aus)" - }, "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" @@ -334,14 +330,14 @@ "error": "Rekategorisierung des Bilds fehlgeschlagen: {error}", "success": "Bild wurde einer neuen Kategorie zugeordnet." }, - "remove": { - "error": "Entfernen der Schwärzung fehlgeschlagen: {error}", - "success": "Schwärzung wurde entfernt" - }, "remove-hint": { "error": "Entfernen des Hinweises fehlgeschlagen: {error}", "success": "Hinweis wurde entfernt" }, + "remove": { + "error": "Entfernen der Schwärzung fehlgeschlagen: {error}", + "success": "Schwärzung wurde entfernt" + }, "undo": { "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", "success": "Rücksetzung erfolgreich" @@ -354,15 +350,15 @@ "remove-highlights": { "label": "Ausgewählte Markierungen entfernen" }, - "resize": { - "label": "Größe ändern" - }, "resize-accept": { "label": "Neue Größe speichern" }, "resize-cancel": { "label": "Größenänderung abbrechen" }, + "resize": { + "label": "Größe ändern" + }, "see-references": { "label": "Referenzen anzeigen" }, @@ -396,6 +392,9 @@ "skipped": "Ignorierte Schwärzung", "text-highlight": "Markierung" }, + "annotation": { + "pending": "(Analyse steht aus)" + }, "annotations": "Annotationen", "archived-dossiers-listing": { "no-data": { @@ -639,18 +638,14 @@ "warning": "Warnung: Wiederherstellung des Benutzers nicht möglich." }, "confirmation-dialog": { - "approve-file": { - "question": "Dieses Dokument enthält ungesehene Änderungen, die sich durch die Reanalyse ergeben haben.

Möchten Sie es trotzdem freigeben?", - "title": "Warnung!" - }, "approve-file-without-analysis": { "confirmationText": "Ohne Analyse freigeben", "denyText": "Abbrechen", "question": "Analyse zur Erkennung neuer Schwärzungen erforderlich.", "title": "Warnung!" }, - "approve-multiple-files": { - "question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen, die im Zuge einer Reanalyse hinzugefügt wurden.

Möchen Sie die Dateien wirklich freigeben?", + "approve-file": { + "question": "Dieses Dokument enthält ungesehene Änderungen, die sich durch die Reanalyse ergeben haben.

Möchten Sie es trotzdem freigeben?", "title": "Warnung!" }, "approve-multiple-files-without-analysis": { @@ -659,6 +654,10 @@ "question": "Für mindestens eine Datei ist ein Analyselauf zur Erkennung neuer Schwärzungen erforderlich.", "title": "Warnung" }, + "approve-multiple-files": { + "question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen, die im Zuge einer Reanalyse hinzugefügt wurden.

Möchen Sie die Dateien wirklich freigeben?", + "title": "Warnung!" + }, "assign-file-to-me": { "question": { "multiple": "Dieses Dokument wird gerade von einer anderen Person geprüft.

Möchten Sie sich die Datei dennoch zuweisen?", @@ -1028,13 +1027,13 @@ "recent": "Neu ({hours} h)", "unassigned": "Keinem Bearbeiter zugewiesen" }, - "reanalyse": { - "action": "Datei analysieren" - }, "reanalyse-dossier": { "error": "Einplanung der Dateien für die Reanalyse fehlgeschlagen. Bitte versuchen Sie es noch einmal.", "success": "Dateien für Reanalyse vorgesehen." }, + "reanalyse": { + "action": "Datei analysieren" + }, "report-download": "", "start-auto-analysis": "Auto-Analyse aktivieren", "stop-auto-analysis": "Auto-Analyse anhalten", @@ -1104,14 +1103,6 @@ "total-documents": "Dokumente", "total-people": "{count} {count, plural, one{Benutzer} other {Benutzer}}" }, - "dossier-templates": { - "label": "Dossier-Vorlagen", - "status": { - "active": "Aktiv", - "inactive": "Inaktiv", - "incomplete": "Unvollständig" - } - }, "dossier-templates-listing": { "action": { "clone": "Vorlage klonen", @@ -1146,6 +1137,14 @@ "title": "{length} {length, plural, one{Dossier-Vorlage} other{Dossier-Vorlagen}}" } }, + "dossier-templates": { + "label": "Dossier-Vorlagen", + "status": { + "active": "Aktiv", + "inactive": "Inaktiv", + "incomplete": "Unvollständig" + } + }, "dossier-watermark-selector": { "heading": "Wasserzeichen auf Dokumenten", "no-watermark": "Kein Wasserzeichen in der Dossier-Vorlage verfügbar:
Bitten Sie Ihren Admin, eines zu konfigurieren.", @@ -1341,15 +1340,6 @@ "title": "{length} {length, plural, one{Wörterbuch} other{Wörterbücher}}" } }, - "entity": { - "info": { - "actions": { - "revert": "Zurücksetzen", - "save": "Änderungen speichern" - }, - "heading": "Entität bearbeiten" - } - }, "entity-rules-screen": { "error": { "generic": "Fehler: Aktualisierung der Entitätsregeln fehlgeschlagen." @@ -1363,19 +1353,28 @@ "title": "Entitätsregeln-Editor", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} in Regeln gefunden" }, + "entity": { + "info": { + "actions": { + "revert": "Zurücksetzen", + "save": "Änderungen speichern" + }, + "heading": "Entität bearbeiten" + } + }, "error": { "deleted-entity": { "dossier": { "action": "Zurück zur Übersicht", "label": "Dieses Dossier wurde gelöscht!" }, - "file": { - "action": "Zurück zum Dossier", - "label": "Diese Datei wurde gelöscht!" - }, "file-dossier": { "action": "Zurück zur Übersicht", "label": "Das Dossier dieser Datei wurde gelöscht!" + }, + "file": { + "action": "Zurück zum Dossier", + "label": "Diese Datei wurde gelöscht!" } }, "file-preview": { @@ -1393,12 +1392,6 @@ }, "exact-date": "{day}. {month} {year} um {hour}:{minute} Uhr", "file": "Datei", - "file-attribute": { - "update": { - "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", - "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." - } - }, "file-attribute-encoding-types": { "ascii": "ASCII", "iso": "ISO-8859-1", @@ -1409,6 +1402,12 @@ "number": "Nummer", "text": "Freier Text" }, + "file-attribute": { + "update": { + "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", + "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." + } + }, "file-attributes-configurations": { "cancel": "Abbrechen", "form": { @@ -1626,15 +1625,6 @@ "csv": "Die Datei-Attribute wurden erfolgreich aus der hochgeladenen CSV-Datei importiert." } }, - "filter": { - "analysis": "Analyse erforderlich", - "comment": "Kommentare", - "hint": "Nur Hinweise", - "image": "Bilder", - "none": "Keine Annotationen", - "redaction": "Schwärzungen", - "updated": "Aktualisiert" - }, "filter-menu": { "filter-options": "Filteroptionen", "filter-types": "Filter", @@ -1644,6 +1634,15 @@ "unseen-pages": "Nur Annotationen auf ungesehenen Seiten", "with-comments": "Nur Annotationen mit Kommentaren" }, + "filter": { + "analysis": "Analyse erforderlich", + "comment": "Kommentare", + "hint": "Nur Hinweise", + "image": "Bilder", + "none": "Keine Annotationen", + "redaction": "Schwärzungen", + "updated": "Aktualisiert" + }, "filters": { "assigned-people": "Bearbeiter", "documents-status": "Dokumentenstatus", @@ -1922,13 +1921,6 @@ "user-promoted-to-approver": "{user} wurde im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} zum Genehmiger ernannt!", "user-removed-as-dossier-member": "{user} wurde als Mitglied von: {dossierHref, select, null{{dossierName}} other{{dossierName}}} entfernt!" }, - "notifications": { - "button-text": "Benachrichtigungen", - "deleted-dossier": "Gelöschtes Dossier", - "label": "Benachrichtigungen", - "mark-all-as-read": "Alle als gelesen markieren", - "mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren" - }, "notifications-screen": { "category": { "email-notifications": "E-Mail-Benachrichtigungen", @@ -1942,6 +1934,7 @@ "dossier": "Benachrichtigungen zu Dossiers", "other": "Andere Benachrichtigungen" }, + "options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten", "options": { "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen werde", "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Prüfer zugewiesen werde", @@ -1959,7 +1952,6 @@ "USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde", "USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere" }, - "options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten", "schedule": { "daily": "Tägliche Zusammenfassung", "instant": "Sofort", @@ -1967,6 +1959,13 @@ }, "title": "Benachrichtigungseinstellungen" }, + "notifications": { + "button-text": "Benachrichtigungen", + "deleted-dossier": "Gelöschtes Dossier", + "label": "Benachrichtigungen", + "mark-all-as-read": "Alle als gelesen markieren", + "mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren" + }, "ocr": { "confirmation-dialog": { "cancel": "Abbrechen", @@ -2058,16 +2057,16 @@ "warnings-label": "Dialoge und Meldungen", "warnings-subtitle": "„Nicht mehr anzeigen“-Optionen" }, - "processing": { - "basic": "Verarbeitung läuft", - "ocr": "OCR" - }, "processing-status": { "ocr": "OCR", "pending": "Ausstehend", "processed": "Verarbeitet", "processing": "Verarbeitung läuft" }, + "processing": { + "basic": "Verarbeitung läuft", + "ocr": "OCR" + }, "readonly": "Lesemodus", "readonly-archived": "Lesemodus (archiviert)", "redact-text": { @@ -2082,6 +2081,10 @@ "edit-text": "Text bearbeiten", "legal-basis": "Rechtsgrundlage", "options": { + "in-document": { + "description": "", + "label": "" + }, "in-dossier": { "description": "Fügen Sie die Schwärzung zu jedem Dokument in {dossierName} hinzu.", "extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen", @@ -2121,6 +2124,10 @@ "description-bulk": "", "label": "In diesem Kontext aus dem Dossier entfernen" }, + "in-document": { + "description": "", + "label": "" + }, "in-dossier": { "description": "Annotieren Sie den Begriff in diesem Dossier nicht.", "description-bulk": "", @@ -2161,6 +2168,10 @@ "extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen", "label": "In diesem Kontext aus Dossier entfernen" }, + "in-document": { + "description": "", + "label": "" + }, "in-dossier": { "description": "Der Begriff wird in keinem Dokument dieses Dossiers {type, select, hint{annotiert} other{automatisch geschwärzt}}.", "description-bulk": "Die ausgewählten Begriffe werden in diesem Dossier nicht {type, select, hint{annotiert} other{automatisch geschwärzt}}.", @@ -2303,12 +2314,6 @@ "red-user-admin": "Benutzeradmin", "regular": "regulärer Benutzer" }, - "search": { - "active-dossiers": "Dokumente in aktiven Dossiers", - "all-dossiers": "Alle Dokumente", - "placeholder": "Dokumente durchsuchen...", - "this-dossier": "In diesem Dossier" - }, "search-screen": { "cols": { "assignee": "Bearbeiter", @@ -2332,6 +2337,12 @@ "no-match": "Der Suchbegriff wurde in keinem der Dokumente gefunden.", "table-header": "{length} {length, plural, one{Suchergebnis} other{Suchergebnisse}}" }, + "search": { + "active-dossiers": "Dokumente in aktiven Dossiers", + "all-dossiers": "Alle Dokumente", + "placeholder": "Dokumente durchsuchen...", + "this-dossier": "In diesem Dossier" + }, "seconds": "Sekunden", "size": "Größe", "smtp-auth-config": { @@ -2587,4 +2598,4 @@ } }, "yesterday": "Gestern" -} \ No newline at end of file +} diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index 765ae48f9..1208b8d24 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -242,7 +242,6 @@ "label": "Add hint only here" } }, - "selected-text": "Selected text:", "type": "Type", "type-placeholder": "Select type..." }, @@ -2082,6 +2081,10 @@ "edit-text": "Edit text", "legal-basis": "Legal basis", "options": { + "in-document": { + "description": "Add redaction for each occurrence of the term in this document.", + "label": "Redact in document" + }, "in-dossier": { "description": "Add redaction in every document in {dossierName}.", "extraOptionLabel": "Apply to all active and future dossiers", @@ -2121,6 +2124,10 @@ "description-bulk": "", "label": "Remove from dossier in this context" }, + "in-document": { + "description": "", + "label": "" + }, "in-dossier": { "description": "Do not annotate the term in this dossier.", "description-bulk": "", @@ -2161,6 +2168,10 @@ "extraOptionLabel": "Apply to all active and future dossiers", "label": "Remove from dossier in this context" }, + "in-document": { + "description": "Do not auto-redact the selected term in any pages of this document.", + "label": "Remove from document" + }, "in-dossier": { "description": "Do not {type, select, hint{annotate} other{auto-redact}} the selected term in any document of this dossier.", "description-bulk": "Do not {type, select, hint{annotate} other{auto-redact}} the selected terms in this dossier.", @@ -2587,4 +2598,4 @@ } }, "yesterday": "Yesterday" -} \ No newline at end of file +} diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 3348899e0..ab563171b 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -242,7 +242,6 @@ "label": "Add hint only here" } }, - "selected-text": "Selected text:", "type": "Type", "type-placeholder": "Select type..." }, @@ -276,9 +275,6 @@ "watermarks": "Watermarks" }, "analysis-disabled": "Analysis disabled", - "annotation": { - "pending": "(Pending analysis)" - }, "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" @@ -334,14 +330,14 @@ "error": "Rekategorisierung des Bildes gescheitert: {error}", "success": "Bild wurde einer neuen Kategorie zugeordnet." }, - "remove": { - "error": "Fehler beim Entfernen der Schwärzung: {error}", - "success": "Schwärzung entfernt!" - }, "remove-hint": { "error": "Failed to remove hint: {error}", "success": "Hint removed!" }, + "remove": { + "error": "Fehler beim Entfernen der Schwärzung: {error}", + "success": "Schwärzung entfernt!" + }, "undo": { "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", "success": "erfolgreich Rückgängig gemacht" @@ -354,15 +350,15 @@ "remove-highlights": { "label": "Remove selected earmarks" }, - "resize": { - "label": "Größe ändern" - }, "resize-accept": { "label": "Größe speichern" }, "resize-cancel": { "label": "Größenänderung abbrechen" }, + "resize": { + "label": "Größe ändern" + }, "see-references": { "label": "See references" }, @@ -396,6 +392,9 @@ "skipped": "Übersprungen", "text-highlight": "Earmark" }, + "annotation": { + "pending": "(Pending analysis)" + }, "annotations": "Annotations", "archived-dossiers-listing": { "no-data": { @@ -639,18 +638,14 @@ "warning": "Achtung: Diese Aktion kann nicht rückgängig gemacht werden!" }, "confirmation-dialog": { - "approve-file": { - "question": "Dieses Dokument enthält ungesehene Änderungen. Möchten Sie es trotzdem genehmigen?", - "title": "Warnung!" - }, "approve-file-without-analysis": { "confirmationText": "Approve without analysis", "denyText": "Cancel", "question": "Analysis required to detect new components.", "title": "Warning!" }, - "approve-multiple-files": { - "question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen. Möchten Sie sie trotzdem genehmigen?", + "approve-file": { + "question": "Dieses Dokument enthält ungesehene Änderungen. Möchten Sie es trotzdem genehmigen?", "title": "Warnung!" }, "approve-multiple-files-without-analysis": { @@ -659,6 +654,10 @@ "question": "Analysis required to detect new components for at least one file.", "title": "Warning" }, + "approve-multiple-files": { + "question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen. Möchten Sie sie trotzdem genehmigen?", + "title": "Warnung!" + }, "assign-file-to-me": { "question": { "multiple": "Dieses Dokument wird gerade von einer anderen Person geprüft. Möchten Sie Reviewer werden und sich selbst dem Dokument zuweisen?", @@ -1028,13 +1027,13 @@ "recent": "Neu ({hours} h)", "unassigned": "Niemandem zugewiesen" }, - "reanalyse": { - "action": "Datei analysieren" - }, "reanalyse-dossier": { "error": "Die Dateien konnten nicht für eine Reanalyse eingeplant werden. Bitte versuchen Sie es erneut.", "success": "Dateien für Reanalyse vorgesehen." }, + "reanalyse": { + "action": "Datei analysieren" + }, "report-download": "Report download", "start-auto-analysis": "Enable auto-analysis", "stop-auto-analysis": "Stop auto-analysis", @@ -1104,14 +1103,6 @@ "total-documents": "Anzahl der Dokumente", "total-people": "{count} {count, plural, one{user} other {users}}" }, - "dossier-templates": { - "label": "Dossier-Vorlagen", - "status": { - "active": "Active", - "inactive": "Inactive", - "incomplete": "Incomplete" - } - }, "dossier-templates-listing": { "action": { "clone": "Clone template", @@ -1146,6 +1137,14 @@ "title": "{length} dossier {length, plural, one{template} other{templates}}" } }, + "dossier-templates": { + "label": "Dossier-Vorlagen", + "status": { + "active": "Active", + "inactive": "Inactive", + "incomplete": "Incomplete" + } + }, "dossier-watermark-selector": { "heading": "Watermarks on documents", "no-watermark": "There is no watermark defined for the dossier template.
Contact your app admin to define one.", @@ -1341,15 +1340,6 @@ "title": "{length} {length, plural, one{entity} other{entities}}" } }, - "entity": { - "info": { - "actions": { - "revert": "Revert", - "save": "Save changes" - }, - "heading": "Edit entity" - } - }, "entity-rules-screen": { "error": { "generic": "Something went wrong... Entity rules update failed!" @@ -1363,19 +1353,28 @@ "title": "Entity rule editor", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} found in rules" }, + "entity": { + "info": { + "actions": { + "revert": "Revert", + "save": "Save changes" + }, + "heading": "Edit entity" + } + }, "error": { "deleted-entity": { "dossier": { "action": "Zurück zur Übersicht", "label": "Dieses Dossier wurde gelöscht!" }, - "file": { - "action": "Zurück zum Dossier", - "label": "Diese Datei wurde gelöscht!" - }, "file-dossier": { "action": "Zurück zur Übersicht", "label": "Das Dossier dieser Datei wurde gelöscht!" + }, + "file": { + "action": "Zurück zum Dossier", + "label": "Diese Datei wurde gelöscht!" } }, "file-preview": { @@ -1393,12 +1392,6 @@ }, "exact-date": "{day} {month} {year} um {hour}:{minute} Uhr", "file": "Datei", - "file-attribute": { - "update": { - "error": "Failed to update file attribute value!", - "success": "File attribute value has been updated successfully!" - } - }, "file-attribute-encoding-types": { "ascii": "ASCII", "iso": "ISO-8859-1", @@ -1409,6 +1402,12 @@ "number": "Nummer", "text": "Freier Text" }, + "file-attribute": { + "update": { + "error": "Failed to update file attribute value!", + "success": "File attribute value has been updated successfully!" + } + }, "file-attributes-configurations": { "cancel": "Cancel", "form": { @@ -1626,15 +1625,6 @@ "csv": "File attributes were imported successfully from uploaded CSV file." } }, - "filter": { - "analysis": "Analyse erforderlich", - "comment": "Kommentare", - "hint": "Nut Hinweise", - "image": "Bilder", - "none": "Keine Anmerkungen", - "redaction": "Geschwärzt", - "updated": "Aktualisiert" - }, "filter-menu": { "filter-options": "Filteroptionen", "filter-types": "Filter", @@ -1644,6 +1634,15 @@ "unseen-pages": "Nur Anmerkungen auf unsichtbaren Seiten", "with-comments": "Nur Anmerkungen mit Kommentaren" }, + "filter": { + "analysis": "Analyse erforderlich", + "comment": "Kommentare", + "hint": "Nut Hinweise", + "image": "Bilder", + "none": "Keine Anmerkungen", + "redaction": "Geschwärzt", + "updated": "Aktualisiert" + }, "filters": { "assigned-people": "Beauftragt", "documents-status": "Documents state", @@ -1922,13 +1921,6 @@ "user-promoted-to-approver": "{user} wurde im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} zum Genehmiger ernannt!", "user-removed-as-dossier-member": "{user} wurde als Mitglied von: {dossierHref, select, null{{dossierName}} other{{dossierName}}} entfernt!" }, - "notifications": { - "button-text": "Notifications", - "deleted-dossier": "Deleted dossier", - "label": "Benachrichtigungen", - "mark-all-as-read": "Alle als gelesen markieren", - "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}" - }, "notifications-screen": { "category": { "email-notifications": "E-Mail Benachrichtigungen", @@ -1942,6 +1934,7 @@ "dossier": "Dossierbezogene Benachrichtigungen", "other": "Andere Benachrichtigungen" }, + "options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten", "options": { "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen bin", "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Überprüfer zugewiesen bin", @@ -1959,7 +1952,6 @@ "USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde", "USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere" }, - "options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten", "schedule": { "daily": "Tägliche Zusammenfassung", "instant": "Sofortig", @@ -1967,6 +1959,13 @@ }, "title": "Benachrichtigungseinstellungen" }, + "notifications": { + "button-text": "Notifications", + "deleted-dossier": "Deleted dossier", + "label": "Benachrichtigungen", + "mark-all-as-read": "Alle als gelesen markieren", + "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}" + }, "ocr": { "confirmation-dialog": { "cancel": "Cancel", @@ -2058,16 +2057,16 @@ "warnings-label": "Prompts and dialogs", "warnings-subtitle": "Do not show again options" }, - "processing": { - "basic": "Processing", - "ocr": "OCR" - }, "processing-status": { "ocr": "OCR", "pending": "Pending", "processed": "Processed", "processing": "Processing" }, + "processing": { + "basic": "Processing", + "ocr": "OCR" + }, "readonly": "Lesemodus", "readonly-archived": "Read only (archived)", "redact-text": { @@ -2082,6 +2081,10 @@ "edit-text": "", "legal-basis": "Legal basis", "options": { + "in-document": { + "description": "", + "label": "" + }, "in-dossier": { "description": "Add redaction in every document in {dossierName}.", "extraOptionLabel": "Apply to all dossiers", @@ -2121,6 +2124,10 @@ "description-bulk": "The selected items should not be annotated in their respective contexts.", "label": "False positive" }, + "in-document": { + "description": "", + "label": "" + }, "in-dossier": { "description": "Do not annotate ''{value}'' as ''{type}'' in any dossier.", "description-bulk": "Do not annotate the selected terms as their respective types in any dossier.", @@ -2161,6 +2168,10 @@ "extraOptionLabel": "Apply to all dossiers", "label": "False positive" }, + "in-document": { + "description": "", + "label": "" + }, "in-dossier": { "description": "Do not {type} \"{value}\" in any document of the current dossier.", "description-bulk": "", @@ -2303,12 +2314,6 @@ "red-user-admin": "Benutzer-Admin", "regular": "Regulär" }, - "search": { - "active-dossiers": "ganze Plattform", - "all-dossiers": "all documents", - "placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen", - "this-dossier": "in diesem Dossier" - }, "search-screen": { "cols": { "assignee": "Bevollmächtigter", @@ -2332,6 +2337,12 @@ "no-match": "Keine Dokumente entsprechen Ihren aktuellen Filtern.", "table-header": "{length} search {length, plural, one{result} other{results}}" }, + "search": { + "active-dossiers": "ganze Plattform", + "all-dossiers": "all documents", + "placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen", + "this-dossier": "in diesem Dossier" + }, "seconds": "seconds", "size": "Size", "smtp-auth-config": { @@ -2587,4 +2598,4 @@ } }, "yesterday": "Gestern" -} \ No newline at end of file +} diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index 5934e1f48..89fcbd78c 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -242,7 +242,6 @@ "label": "Add hint only here" } }, - "selected-text": "Selected text:", "type": "Type", "type-placeholder": "Select type..." }, @@ -2082,6 +2081,10 @@ "edit-text": "", "legal-basis": "Legal basis", "options": { + "in-document": { + "description": "Add redaction for each occurrence of the term in this document.", + "label": "Redact in document" + }, "in-dossier": { "description": "Add redaction in every document in {dossierName}.", "extraOptionLabel": "Apply to all dossiers", @@ -2121,6 +2124,10 @@ "description-bulk": "The selected items should not be annotated in their respective contexts.", "label": "False positive" }, + "in-document": { + "description": "", + "label": "" + }, "in-dossier": { "description": "Do not annotate ''{value}'' as ''{type}'' in any dossier.", "description-bulk": "Do not annotate the selected terms as their respective types in any dossier.", @@ -2161,6 +2168,10 @@ "extraOptionLabel": "Apply to all dossiers", "label": "False positive" }, + "in-document": { + "description": "", + "label": "" + }, "in-dossier": { "description": "Do not {type} \"{value}\" in any document of the current dossier.", "description-bulk": "", @@ -2587,4 +2598,4 @@ } }, "yesterday": "Yesterday" -} \ No newline at end of file +} diff --git a/libs/common-ui b/libs/common-ui index 2faecb44a..c644eaeba 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 2faecb44a926f02a6d4186e58751ac615f2bfd47 +Subproject commit c644eaeba2e137607f1ceb42b0ee5ce9a2f68bbe diff --git a/libs/red-domain/src/lib/legal-basis/legal-basis-change.request.ts b/libs/red-domain/src/lib/legal-basis/legal-basis-change.request.ts index e1d95b092..1f27f5418 100644 --- a/libs/red-domain/src/lib/legal-basis/legal-basis-change.request.ts +++ b/libs/red-domain/src/lib/legal-basis/legal-basis-change.request.ts @@ -1,5 +1,8 @@ +import { ForceAnnotationOption } from '../../../../../apps/red-ui/src/app/modules/file-preview/utils/dialog-types'; + export interface ILegalBasisChangeRequest { annotationId?: string; comment?: string; legalBasis?: string; + option?: ForceAnnotationOption; } diff --git a/libs/red-domain/src/lib/redaction-log/remove-redaction.request.ts b/libs/red-domain/src/lib/redaction-log/remove-redaction.request.ts index 40290994a..1967a85cb 100644 --- a/libs/red-domain/src/lib/redaction-log/remove-redaction.request.ts +++ b/libs/red-domain/src/lib/redaction-log/remove-redaction.request.ts @@ -2,4 +2,5 @@ export interface IRemoveRedactionRequest { annotationId?: string; comment?: string; removeFromDictionary?: boolean; + value?: string; } From b23c3e60d7dd4345b6008d10b0a126b95d385eaa Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Tue, 17 Sep 2024 17:38:35 +0300 Subject: [PATCH 019/125] RED-10064: added ids for report documents. --- .../reports/reports-screen/reports-screen.component.html | 3 +++ .../screens/reports/reports-screen/reports-screen.component.ts | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen/reports-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen/reports-screen.component.html index a6e907c1b..e3f5c58a5 100644 --- a/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen/reports-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen/reports-screen.component.html @@ -26,6 +26,7 @@ *allow="roles.reportTemplates.upload; if: currentUser.isAdmin" [tooltip]="'reports-screen.upload-document' | translate" [attr.help-mode-key]="'upload_report'" + [buttonId]="'upload_report'" icon="iqser:upload" >
@@ -46,6 +47,7 @@ Date: Wed, 18 Sep 2024 13:57:54 +0300 Subject: [PATCH 020/125] RED-10050: fixed navigating to doc with filtered annotations issue. --- .../components/file-workload/file-workload.component.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts index a6e0675a4..6ccf8e4c7 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts @@ -36,7 +36,7 @@ import { workloadTranslations } from '@translations/workload-translations'; import { UserPreferenceService } from '@users/user-preference.service'; import { getLocalStorageDataByFileId } from '@utils/local-storage'; import { combineLatest, delay, Observable } from 'rxjs'; -import { map, tap } from 'rxjs/operators'; +import { filter, map, tap } from 'rxjs/operators'; import scrollIntoView from 'scroll-into-view-if-needed'; import { REDAnnotationManager } from '../../../pdf-viewer/services/annotation-manager.service'; import { REDDocumentViewer } from '../../../pdf-viewer/services/document-viewer.service'; @@ -187,6 +187,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On const secondary$ = this.filterService.getFilterModels$('secondaryFilters'); return combineLatest([ + this._documentViewer.loaded$, this.fileDataService.all$, primary$, secondary$, @@ -195,7 +196,8 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On this._pageRotationService.rotations$, ]).pipe( delay(0), - map(([annotations, primary, secondary, componentReferenceIds]) => + filter(([loaded]) => loaded), + map(([, annotations, primary, secondary, componentReferenceIds]) => this.#filterAnnotations(annotations, primary, secondary, componentReferenceIds), ), map(annotations => this.#mapListItemsFromAnnotationWrapperArray(annotations)), From 256305d12fd8602a0a738a722dc3ff1a364e1d8f Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Thu, 19 Sep 2024 15:03:32 +0300 Subject: [PATCH 021/125] RED-9578: implemented the new approval modal layout. --- .../services/bulk-actions.service.ts | 58 +++---- .../selected-annotations-table.component.html | 11 +- .../selected-annotations-table.component.scss | 2 +- .../selected-annotations-table.component.ts | 17 +- .../edit-redaction-dialog.component.ts | 15 +- .../force-annotation-dialog.component.ts | 15 +- .../redact-recommendation-dialog.component.ts | 15 +- .../remove-redaction-dialog.component.ts | 18 +- .../file-actions/file-actions.component.ts | 27 +-- .../approve-warning-details.component.html | 9 + .../approve-warning-details.component.scss | 10 ++ .../approve-warning-details.component.ts | 31 ++++ .../warning-details-panel.component.html | 8 + .../warning-details-panel.component.scss | 4 + .../warning-details-panel.component.ts | 37 ++++ .../src/app/services/files/files.service.ts | 10 +- .../approval-warning-reason-translations.ts | 8 + apps/red-ui/src/assets/i18n/redact/de.json | 164 ++++++++---------- apps/red-ui/src/assets/i18n/redact/en.json | 30 ++-- apps/red-ui/src/assets/i18n/scm/de.json | 164 ++++++++---------- apps/red-ui/src/assets/i18n/scm/en.json | 30 ++-- libs/common-ui | 2 +- .../src/lib/files/approve-file-types.ts | 19 ++ libs/red-domain/src/lib/files/index.ts | 1 + 24 files changed, 386 insertions(+), 319 deletions(-) create mode 100644 apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.html create mode 100644 apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.scss create mode 100644 apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.ts create mode 100644 apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.html create mode 100644 apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.scss create mode 100644 apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.ts create mode 100644 apps/red-ui/src/app/translations/approval-warning-reason-translations.ts create mode 100644 libs/red-domain/src/lib/files/approve-file-types.ts diff --git a/apps/red-ui/src/app/modules/dossier-overview/services/bulk-actions.service.ts b/apps/red-ui/src/app/modules/dossier-overview/services/bulk-actions.service.ts index db0cb5e29..6e78328b2 100644 --- a/apps/red-ui/src/app/modules/dossier-overview/services/bulk-actions.service.ts +++ b/apps/red-ui/src/app/modules/dossier-overview/services/bulk-actions.service.ts @@ -1,7 +1,7 @@ -import { Injectable } from '@angular/core'; +import { Injectable, signal } from '@angular/core'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { IConfirmationDialogData, IqserDialog, LoadingService } from '@iqser/common-ui'; -import { Dossier, File, User, WorkflowFileStatus, WorkflowFileStatuses } from '@red/domain'; +import { ApproveResponse, Dossier, File, User, WorkflowFileStatus, WorkflowFileStatuses } from '@red/domain'; import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service'; import { FileManagementService } from '@services/files/file-management.service'; import { FilesService } from '@services/files/files.service'; @@ -11,6 +11,7 @@ import { AssignReviewerApproverDialogComponent } from '../../shared-dossiers/dia import { DossiersDialogService } from '../../shared-dossiers/services/dossiers-dialog.service'; import { FileAssignService } from '../../shared-dossiers/services/file-assign.service'; import { getCurrentUser } from '@common-ui/users'; +import { ApproveWarningDetailsComponent } from '@shared/components/approve-warning-details/approve-warning-details.component'; @Injectable() export class BulkActionsService { @@ -110,34 +111,33 @@ export class BulkActionsService { } async approve(files: File[]): Promise { - const foundAnalysisRequiredFile = files.find(file => file.analysisRequired); - const foundUpdatedFile = files.find(file => file.hasUpdates); - if (foundAnalysisRequiredFile || foundUpdatedFile) { - this._dialogService.openDialog( - 'confirm', - { - title: foundAnalysisRequiredFile - ? _('confirmation-dialog.approve-multiple-files-without-analysis.title') - : _('confirmation-dialog.approve-multiple-files.title'), - question: foundAnalysisRequiredFile - ? _('confirmation-dialog.approve-multiple-files-without-analysis.question') - : _('confirmation-dialog.approve-multiple-files.question'), - confirmationText: foundAnalysisRequiredFile - ? _('confirmation-dialog.approve-multiple-files-without-analysis.confirmationText') - : null, - denyText: foundAnalysisRequiredFile ? _('confirmation-dialog.approve-multiple-files-without-analysis.denyText') : null, - } as IConfirmationDialogData, - async () => { - this._loadingService.start(); - await this._filesService.setApproved(files); - this._loadingService.stop(); - }, - ); - } else { - this._loadingService.start(); - await this._filesService.setApproved(files); - this._loadingService.stop(); + this._loadingService.start(); + const approvalResponse: ApproveResponse[] = await this._filesService.getApproveWarnings(files); + this._loadingService.stop(); + const hasWarnings = approvalResponse.some(response => response.hasWarnings); + if (!hasWarnings) { + return; } + + const fileWarnings = approvalResponse.map(response => ({ fileId: response.fileId, fileWarnings: response.fileWarnings })); + this._dialogService.openDialog( + 'confirm', + { + title: _('confirmation-dialog.approve-file.title'), + question: _('confirmation-dialog.approve-file.question'), + translateParams: { questionLength: files.length }, + confirmationText: _('confirmation-dialog.approve-file.confirmationText'), + denyText: _('confirmation-dialog.approve-file.denyText'), + component: ApproveWarningDetailsComponent, + componentInputs: { data: signal(fileWarnings), files: signal(files) }, + cancelButtonPrimary: true, + } as IConfirmationDialogData, + async () => { + this._loadingService.start(); + await this._filesService.setApproved(files); + this._loadingService.stop(); + }, + ); } assign(files: File[]): void { diff --git a/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.html b/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.html index f8bbf10d5..a47798615 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.html +++ b/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.html @@ -1,14 +1,17 @@ - - - - + + diff --git a/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.scss b/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.scss index 6812c9358..ebcb45852 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.scss @@ -27,7 +27,7 @@ table { th, td { - &:not(.w-50) { + &:first-child:not(.w-50) { width: 25%; } max-width: 0; diff --git a/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.ts b/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.ts index 3601d4b77..bc8018123 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.ts @@ -1,9 +1,9 @@ -import { Component, Input } from '@angular/core'; +import { Component, computed, input } from '@angular/core'; import { NgClass, NgForOf, NgStyle } from '@angular/common'; export interface ValueColumn { label: string; - show: boolean; + hide?: boolean; bold?: boolean; } @@ -18,11 +18,12 @@ const MAX_ITEMS_DISPLAY = 10; styleUrl: './selected-annotations-table.component.scss', }) export class SelectedAnnotationsTableComponent { - @Input({ required: true }) columns: ValueColumn[]; - @Input({ required: true }) data: ValueColumn[][]; - @Input() staticColumns = false; + readonly columns = input.required(); + readonly data = input.required(); + readonly staticColumns = input(false); - get redactedTextsAreaHeight() { - return this.data.length <= MAX_ITEMS_DISPLAY ? TABLE_ROW_SIZE * this.data.length : TABLE_ROW_SIZE * MAX_ITEMS_DISPLAY; - } + readonly redactedTextsAreaHeight = computed(() => + this.data().length <= MAX_ITEMS_DISPLAY ? TABLE_ROW_SIZE * this.data().length : TABLE_ROW_SIZE * MAX_ITEMS_DISPLAY, + ); + readonly shouldApplyHalfWidth = computed(() => this.columns().filter(column => !column.hide).length === 2); } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts index 4a0e68714..44aa3110c 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts @@ -77,19 +77,10 @@ export class EditRedactionDialogComponent readonly isRedacted = this.annotations.every(annotation => annotation.isRedacted); readonly isImported: boolean = this.annotations.every(annotation => annotation.imported); readonly allRectangles = this.annotations.reduce((acc, a) => acc && a.AREA, true); - readonly tableColumns = [ - { - label: 'Value', - show: true, - }, - { - label: 'Type', - show: true, - }, - ]; + readonly tableColumns: ValueColumn[] = [{ label: 'Value' }, { label: 'Type' }]; readonly tableData: ValueColumn[][] = this.data.annotations.map(redaction => [ - { label: redaction.value, show: true, bold: true }, - { label: redaction.typeLabel, show: true }, + { label: redaction.value, bold: true }, + { label: redaction.typeLabel }, ]); options: DetailsRadioOption[] | undefined; legalOptions: LegalBasisOption[] = []; diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts index 28630826d..667823634 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts @@ -60,19 +60,10 @@ const DOCUMINE_LEGAL_BASIS = 'n-a.'; export class ForceAnnotationDialogComponent extends BaseDialogComponent implements OnInit { readonly isDocumine = getConfig().IS_DOCUMINE; - readonly tableColumns = [ - { - label: 'Value', - show: true, - }, - { - label: 'Type', - show: true, - }, - ]; + readonly tableColumns: ValueColumn[] = [{ label: 'Value' }, { label: 'Type' }]; readonly tableData: ValueColumn[][] = this._data.annotations.map(redaction => [ - { label: redaction.value, show: true, bold: true }, - { label: redaction.typeLabel, show: true }, + { label: redaction.value, bold: true }, + { label: redaction.typeLabel }, ]); legalOptions: LegalBasisOption[] = []; diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts index dc50676e2..b6efec032 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts @@ -69,19 +69,10 @@ export class RedactRecommendationDialogComponent reason: [null], }); - readonly tableColumns = [ - { - label: 'Value', - show: true, - }, - { - label: 'Type', - show: true, - }, - ]; + readonly tableColumns: ValueColumn[] = [{ label: 'Value' }, { label: 'Type' }]; readonly tableData: ValueColumn[][] = this.data.annotations.map(redaction => [ - { label: redaction.value, show: true, bold: true }, - { label: redaction.typeLabel, show: true }, + { label: redaction.value, bold: true }, + { label: redaction.typeLabel }, ]); constructor( diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts index 431d41fbc..720f709f4 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts @@ -105,25 +105,19 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< readonly selectedOption = toSignal(this.form.get('option').valueChanges.pipe(map(value => value.value))); readonly isFalsePositive = computed(() => this.selectedOption() === RemoveRedactionOptions.FALSE_POSITIVE); readonly tableColumns = computed(() => [ - { - label: 'Value', - show: true, - }, - { - label: 'Type', - show: true, - }, + { label: 'Value' }, + { label: 'Type' }, { label: 'Context', - show: this.isFalsePositive(), + hide: !this.isFalsePositive(), }, ]); readonly tableData = computed(() => this.data.redactions.map((redaction, index) => [ - { label: redaction.value, show: true, bold: true }, - { label: redaction.typeLabel, show: true }, - { label: this.data.falsePositiveContext[index], show: this.isFalsePositive() }, + { label: redaction.value, bold: true }, + { label: redaction.typeLabel }, + { label: this.data.falsePositiveContext[index], hide: !this.isFalsePositive() }, ]), ); diff --git a/apps/red-ui/src/app/modules/shared-dossiers/components/file-actions/file-actions.component.ts b/apps/red-ui/src/app/modules/shared-dossiers/components/file-actions/file-actions.component.ts index 19a721f98..760c59c66 100644 --- a/apps/red-ui/src/app/modules/shared-dossiers/components/file-actions/file-actions.component.ts +++ b/apps/red-ui/src/app/modules/shared-dossiers/components/file-actions/file-actions.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectorRef, Component, HostBinding, Injector, Input, OnChanges, Optional, ViewChild } from '@angular/core'; +import { ChangeDetectorRef, Component, HostBinding, Injector, Input, OnChanges, Optional, signal, ViewChild } from '@angular/core'; import { toObservable } from '@angular/core/rxjs-interop'; import { Router } from '@angular/router'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; @@ -13,7 +13,7 @@ import { } from '@iqser/common-ui'; import { getCurrentUser } from '@iqser/common-ui/lib/users'; import { IqserTooltipPositions } from '@iqser/common-ui/lib/utils'; -import { Action, ActionTypes, Dossier, File, ProcessingFileStatuses, User } from '@red/domain'; +import { Action, ActionTypes, ApproveResponse, Dossier, File, ProcessingFileStatuses, User } from '@red/domain'; import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service'; import { FileAttributesService } from '@services/entity-services/file-attributes.service'; import { FileManagementService } from '@services/files/file-management.service'; @@ -36,6 +36,7 @@ import { FileAssignService } from '../../services/file-assign.service'; import { ProcessingIndicatorComponent } from '@shared/components/processing-indicator/processing-indicator.component'; import { StatusBarComponent } from '@common-ui/shared'; import { NgIf, NgTemplateOutlet } from '@angular/common'; +import { ApproveWarningDetailsComponent } from '@shared/components/approve-warning-details/approve-warning-details.component'; @Component({ selector: 'redaction-file-actions', @@ -302,20 +303,22 @@ export class FileActionsComponent implements OnChanges { } async setFileApproved() { - if (!this.file.analysisRequired && !this.file.hasUpdates) { - await this.#setFileApproved(); + this._loadingService.start(); + const approvalResponse: ApproveResponse = (await this._filesService.getApproveWarnings([this.file]))[0]; + this._loadingService.stop(); + if (!approvalResponse.hasWarnings) { return; } const data: IConfirmationDialogData = { - title: this.file.analysisRequired - ? _('confirmation-dialog.approve-file-without-analysis.title') - : _('confirmation-dialog.approve-file.title'), - question: this.file.analysisRequired - ? _('confirmation-dialog.approve-file-without-analysis.question') - : _('confirmation-dialog.approve-file.question'), - confirmationText: this.file.analysisRequired ? _('confirmation-dialog.approve-file-without-analysis.confirmationText') : null, - denyText: this.file.analysisRequired ? _('confirmation-dialog.approve-file-without-analysis.denyText') : null, + title: _('confirmation-dialog.approve-file.title'), + question: _('confirmation-dialog.approve-file.question'), + translateParams: { questionLength: 1 }, + confirmationText: _('confirmation-dialog.approve-file.confirmationText'), + denyText: _('confirmation-dialog.approve-file.denyText'), + component: ApproveWarningDetailsComponent, + componentInputs: { data: signal([approvalResponse]), files: signal([this.file]) }, + cancelButtonPrimary: true, }; this._dialogService.openDialog('confirm', data, () => this.#setFileApproved()); diff --git a/apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.html b/apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.html new file mode 100644 index 000000000..c618edd96 --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.html @@ -0,0 +1,9 @@ +
+ @for (file of data(); track file) { + + } +
diff --git a/apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.scss b/apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.scss new file mode 100644 index 000000000..668a18134 --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.scss @@ -0,0 +1,10 @@ +@use 'common-mixins'; + +.scrollable { + overflow-y: auto; + max-height: calc(5 * 50px); + @include common-mixins.scroll-bar; + + padding-left: 2px; + padding-right: 11px; +} diff --git a/apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.ts b/apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.ts new file mode 100644 index 000000000..91d350058 --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.ts @@ -0,0 +1,31 @@ +import { Component, computed, input } from '@angular/core'; +import { ApproveResponse, File } from '@red/domain'; +import { SelectedAnnotationsTableComponent } from '../../../file-preview/components/selected-annotations-table/selected-annotations-table.component'; +import { MatExpansionPanel, MatExpansionPanelHeader } from '@angular/material/expansion'; +import { KeyValuePipe, NgStyle } from '@angular/common'; +import { WarningDetailsPanelComponent } from '@shared/components/warning-details-panel/warning-details-panel.component'; +import { CdkFixedSizeVirtualScroll, CdkVirtualScrollViewport } from '@angular/cdk/scrolling'; + +@Component({ + selector: 'redaction-approve-warning-details', + standalone: true, + imports: [ + SelectedAnnotationsTableComponent, + MatExpansionPanel, + MatExpansionPanelHeader, + KeyValuePipe, + WarningDetailsPanelComponent, + CdkVirtualScrollViewport, + CdkFixedSizeVirtualScroll, + NgStyle, + ], + templateUrl: './approve-warning-details.component.html', + styleUrl: './approve-warning-details.component.scss', +}) +export class ApproveWarningDetailsComponent { + readonly data = input.required(); + readonly files = input.required(); + + readonly fileNamesByIds = computed(() => this.files().reduce((acc, file) => ({ ...acc, [file.id]: file.filename }), {})); + readonly shouldPanelOpenDefault = computed(() => this.files().length === 1); +} diff --git a/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.html b/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.html new file mode 100644 index 000000000..bae0d9986 --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.html @@ -0,0 +1,8 @@ + + {{ filename() }} + + diff --git a/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.scss b/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.scss new file mode 100644 index 000000000..1be3d10c7 --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.scss @@ -0,0 +1,4 @@ +mat-expansion-panel { + margin-bottom: 8px; + max-width: 100%; +} diff --git a/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.ts b/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.ts new file mode 100644 index 000000000..9726e2900 --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.ts @@ -0,0 +1,37 @@ +import { Component, computed, inject, input } from '@angular/core'; +import { + SelectedAnnotationsTableComponent, + ValueColumn, +} from '../../../file-preview/components/selected-annotations-table/selected-annotations-table.component'; +import { WarningModel } from '@red/domain'; +import { MatExpansionPanel, MatExpansionPanelHeader } from '@angular/material/expansion'; +import { approvalWarningReasonTranslations } from '@translations/approval-warning-reason-translations'; +import { TranslateService } from '@ngx-translate/core'; + +@Component({ + selector: 'redaction-warning-details-panel', + standalone: true, + imports: [MatExpansionPanel, MatExpansionPanelHeader, SelectedAnnotationsTableComponent], + templateUrl: './warning-details-panel.component.html', + styleUrl: './warning-details-panel.component.scss', +}) +export class WarningDetailsPanelComponent { + readonly #translateService = inject(TranslateService); + readonly warnings = input(); + readonly filename = input(); + readonly openByDefault = input(); + readonly tableColumns = computed(() => [ + { label: 'Value' }, + { label: 'Type' }, + { label: 'Page' }, + { label: 'Warning Reason' }, + ]); + readonly tableData = computed(() => + this.warnings().map(warning => [ + { label: warning.value, bold: true }, + { label: warning.type }, + { label: warning.pages.join(',') }, + { label: this.#translateService.instant(approvalWarningReasonTranslations[warning.warningType]) }, + ]), + ); +} diff --git a/apps/red-ui/src/app/services/files/files.service.ts b/apps/red-ui/src/app/services/files/files.service.ts index ae2857d51..59db98b39 100644 --- a/apps/red-ui/src/app/services/files/files.service.ts +++ b/apps/red-ui/src/app/services/files/files.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { EntitiesService, isArray, QueryParam } from '@iqser/common-ui'; import { List, mapEach } from '@iqser/common-ui/lib/utils'; -import { File, IFile } from '@red/domain'; +import { ApproveResponse, File, IFile } from '@red/domain'; import { UserService } from '@users/user.service'; import { NGXLogger } from 'ngx-logger'; import { firstValueFrom } from 'rxjs'; @@ -70,7 +70,13 @@ export class FilesService extends EntitiesService { async setApproved(files: File | List) { const _files = asList(files); - return this.#makePost(_files, `${this._defaultModelPath}/approved/${_files[0].dossierId}/bulk`); + return this.#makePost(_files, `${this._defaultModelPath}/approved/${_files[0].dossierId}/bulk`, [{ key: 'force', value: true }]); + } + + async getApproveWarnings(files: File[]) { + const filesIds = files.map(file => file.id); + const url = `${this._defaultModelPath}/approved/${files[0].dossierId}/bulk`; + return await firstValueFrom(this._post(filesIds, url)); } async setUnderReview(files: File | List) { diff --git a/apps/red-ui/src/app/translations/approval-warning-reason-translations.ts b/apps/red-ui/src/app/translations/approval-warning-reason-translations.ts new file mode 100644 index 000000000..8a7265dcf --- /dev/null +++ b/apps/red-ui/src/app/translations/approval-warning-reason-translations.ts @@ -0,0 +1,8 @@ +import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; +import { WarningType } from '@red/domain'; + +export const approvalWarningReasonTranslations: Record = { + [WarningType.PENDING_CHANGE]: _('confirmation-dialog.approve-file.warning-reason.pending-changes'), + [WarningType.LEGAL_BASIS_MISSING]: _('confirmation-dialog.approve-file.warning-reason.legal-basis-missing'), + [WarningType.UNMAPPED_JUSTIFICATION]: _('confirmation-dialog.approve-file.warning-reason.unmapped-justification'), +}; diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index 09ccabbb5..bbb54f960 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -242,7 +242,6 @@ "label": "Nur hier hinzufügen" } }, - "selected-text": "Ausgewählter Text:", "type": "Typ", "type-placeholder": "Typ auswählen..." }, @@ -276,9 +275,6 @@ "watermarks": "Wasserzeichen" }, "analysis-disabled": "", - "annotation": { - "pending": "(Analyse steht aus)" - }, "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" @@ -334,14 +330,14 @@ "error": "Rekategorisierung des Bilds fehlgeschlagen: {error}", "success": "Bild wurde einer neuen Kategorie zugeordnet." }, - "remove": { - "error": "Entfernen der Schwärzung fehlgeschlagen: {error}", - "success": "Schwärzung wurde entfernt" - }, "remove-hint": { "error": "Entfernen des Hinweises fehlgeschlagen: {error}", "success": "Hinweis wurde entfernt" }, + "remove": { + "error": "Entfernen der Schwärzung fehlgeschlagen: {error}", + "success": "Schwärzung wurde entfernt" + }, "undo": { "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", "success": "Rücksetzung erfolgreich" @@ -354,15 +350,15 @@ "remove-highlights": { "label": "Ausgewählte Markierungen entfernen" }, - "resize": { - "label": "Größe ändern" - }, "resize-accept": { "label": "Neue Größe speichern" }, "resize-cancel": { "label": "Größenänderung abbrechen" }, + "resize": { + "label": "Größe ändern" + }, "see-references": { "label": "Referenzen anzeigen" }, @@ -396,6 +392,9 @@ "skipped": "Ignorierte Schwärzung", "text-highlight": "Markierung" }, + "annotation": { + "pending": "(Analyse steht aus)" + }, "annotations": "Annotationen", "archived-dossiers-listing": { "no-data": { @@ -640,24 +639,15 @@ }, "confirmation-dialog": { "approve-file": { - "question": "Dieses Dokument enthält ungesehene Änderungen, die sich durch die Reanalyse ergeben haben.

Möchten Sie es trotzdem freigeben?", - "title": "Warnung!" - }, - "approve-file-without-analysis": { - "confirmationText": "Ohne Analyse freigeben", - "denyText": "Abbrechen", - "question": "Analyse zur Erkennung neuer Schwärzungen erforderlich.", - "title": "Warnung!" - }, - "approve-multiple-files": { - "question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen, die im Zuge einer Reanalyse hinzugefügt wurden.

Möchen Sie die Dateien wirklich freigeben?", - "title": "Warnung!" - }, - "approve-multiple-files-without-analysis": { - "confirmationText": "Ohne Analyse freigeben", - "denyText": "Abbrechen", - "question": "Für mindestens eine Datei ist ein Analyselauf zur Erkennung neuer Schwärzungen erforderlich.", - "title": "Warnung" + "confirmationText": "Approve anyway", + "denyText": "No, cancel", + "question": "Do you still want to approve the {questionLength, plural, one{document} other{documents}}?", + "title": "Approval warning", + "warning-reason": { + "legal-basis-missing": "Legal basis missing", + "pending-changes": "Pending Changes", + "unmapped-justification": "Unmapped justification" + } }, "assign-file-to-me": { "question": { @@ -1028,13 +1018,13 @@ "recent": "Neu ({hours} h)", "unassigned": "Keinem Bearbeiter zugewiesen" }, - "reanalyse": { - "action": "Datei analysieren" - }, "reanalyse-dossier": { "error": "Einplanung der Dateien für die Reanalyse fehlgeschlagen. Bitte versuchen Sie es noch einmal.", "success": "Dateien für Reanalyse vorgesehen." }, + "reanalyse": { + "action": "Datei analysieren" + }, "report-download": "", "start-auto-analysis": "Auto-Analyse aktivieren", "stop-auto-analysis": "Auto-Analyse anhalten", @@ -1104,14 +1094,6 @@ "total-documents": "Dokumente", "total-people": "{count} {count, plural, one{Benutzer} other {Benutzer}}" }, - "dossier-templates": { - "label": "Dossier-Vorlagen", - "status": { - "active": "Aktiv", - "inactive": "Inaktiv", - "incomplete": "Unvollständig" - } - }, "dossier-templates-listing": { "action": { "clone": "Vorlage klonen", @@ -1146,6 +1128,14 @@ "title": "{length} {length, plural, one{Dossier-Vorlage} other{Dossier-Vorlagen}}" } }, + "dossier-templates": { + "label": "Dossier-Vorlagen", + "status": { + "active": "Aktiv", + "inactive": "Inaktiv", + "incomplete": "Unvollständig" + } + }, "dossier-watermark-selector": { "heading": "Wasserzeichen auf Dokumenten", "no-watermark": "Kein Wasserzeichen in der Dossier-Vorlage verfügbar:
Bitten Sie Ihren Admin, eines zu konfigurieren.", @@ -1341,15 +1331,6 @@ "title": "{length} {length, plural, one{Wörterbuch} other{Wörterbücher}}" } }, - "entity": { - "info": { - "actions": { - "revert": "Zurücksetzen", - "save": "Änderungen speichern" - }, - "heading": "Entität bearbeiten" - } - }, "entity-rules-screen": { "error": { "generic": "Fehler: Aktualisierung der Entitätsregeln fehlgeschlagen." @@ -1363,19 +1344,28 @@ "title": "Entitätsregeln-Editor", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} in Regeln gefunden" }, + "entity": { + "info": { + "actions": { + "revert": "Zurücksetzen", + "save": "Änderungen speichern" + }, + "heading": "Entität bearbeiten" + } + }, "error": { "deleted-entity": { "dossier": { "action": "Zurück zur Übersicht", "label": "Dieses Dossier wurde gelöscht!" }, - "file": { - "action": "Zurück zum Dossier", - "label": "Diese Datei wurde gelöscht!" - }, "file-dossier": { "action": "Zurück zur Übersicht", "label": "Das Dossier dieser Datei wurde gelöscht!" + }, + "file": { + "action": "Zurück zum Dossier", + "label": "Diese Datei wurde gelöscht!" } }, "file-preview": { @@ -1393,12 +1383,6 @@ }, "exact-date": "{day}. {month} {year} um {hour}:{minute} Uhr", "file": "Datei", - "file-attribute": { - "update": { - "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", - "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." - } - }, "file-attribute-encoding-types": { "ascii": "ASCII", "iso": "ISO-8859-1", @@ -1409,6 +1393,12 @@ "number": "Nummer", "text": "Freier Text" }, + "file-attribute": { + "update": { + "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", + "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." + } + }, "file-attributes-configurations": { "cancel": "Abbrechen", "form": { @@ -1626,15 +1616,6 @@ "csv": "Die Datei-Attribute wurden erfolgreich aus der hochgeladenen CSV-Datei importiert." } }, - "filter": { - "analysis": "Analyse erforderlich", - "comment": "Kommentare", - "hint": "Nur Hinweise", - "image": "Bilder", - "none": "Keine Annotationen", - "redaction": "Schwärzungen", - "updated": "Aktualisiert" - }, "filter-menu": { "filter-options": "Filteroptionen", "filter-types": "Filter", @@ -1644,6 +1625,15 @@ "unseen-pages": "Nur Annotationen auf ungesehenen Seiten", "with-comments": "Nur Annotationen mit Kommentaren" }, + "filter": { + "analysis": "Analyse erforderlich", + "comment": "Kommentare", + "hint": "Nur Hinweise", + "image": "Bilder", + "none": "Keine Annotationen", + "redaction": "Schwärzungen", + "updated": "Aktualisiert" + }, "filters": { "assigned-people": "Bearbeiter", "documents-status": "Dokumentenstatus", @@ -1922,13 +1912,6 @@ "user-promoted-to-approver": "{user} wurde im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} zum Genehmiger ernannt!", "user-removed-as-dossier-member": "{user} wurde als Mitglied von: {dossierHref, select, null{{dossierName}} other{{dossierName}}} entfernt!" }, - "notifications": { - "button-text": "Benachrichtigungen", - "deleted-dossier": "Gelöschtes Dossier", - "label": "Benachrichtigungen", - "mark-all-as-read": "Alle als gelesen markieren", - "mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren" - }, "notifications-screen": { "category": { "email-notifications": "E-Mail-Benachrichtigungen", @@ -1942,6 +1925,7 @@ "dossier": "Benachrichtigungen zu Dossiers", "other": "Andere Benachrichtigungen" }, + "options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten", "options": { "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen werde", "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Prüfer zugewiesen werde", @@ -1959,7 +1943,6 @@ "USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde", "USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere" }, - "options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten", "schedule": { "daily": "Tägliche Zusammenfassung", "instant": "Sofort", @@ -1967,6 +1950,13 @@ }, "title": "Benachrichtigungseinstellungen" }, + "notifications": { + "button-text": "Benachrichtigungen", + "deleted-dossier": "Gelöschtes Dossier", + "label": "Benachrichtigungen", + "mark-all-as-read": "Alle als gelesen markieren", + "mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren" + }, "ocr": { "confirmation-dialog": { "cancel": "Abbrechen", @@ -2058,16 +2048,16 @@ "warnings-label": "Dialoge und Meldungen", "warnings-subtitle": "„Nicht mehr anzeigen“-Optionen" }, - "processing": { - "basic": "Verarbeitung läuft", - "ocr": "OCR" - }, "processing-status": { "ocr": "OCR", "pending": "Ausstehend", "processed": "Verarbeitet", "processing": "Verarbeitung läuft" }, + "processing": { + "basic": "Verarbeitung läuft", + "ocr": "OCR" + }, "readonly": "Lesemodus", "readonly-archived": "Lesemodus (archiviert)", "redact-text": { @@ -2303,12 +2293,6 @@ "red-user-admin": "Benutzeradmin", "regular": "regulärer Benutzer" }, - "search": { - "active-dossiers": "Dokumente in aktiven Dossiers", - "all-dossiers": "Alle Dokumente", - "placeholder": "Dokumente durchsuchen...", - "this-dossier": "In diesem Dossier" - }, "search-screen": { "cols": { "assignee": "Bearbeiter", @@ -2332,6 +2316,12 @@ "no-match": "Der Suchbegriff wurde in keinem der Dokumente gefunden.", "table-header": "{length} {length, plural, one{Suchergebnis} other{Suchergebnisse}}" }, + "search": { + "active-dossiers": "Dokumente in aktiven Dossiers", + "all-dossiers": "Alle Dokumente", + "placeholder": "Dokumente durchsuchen...", + "this-dossier": "In diesem Dossier" + }, "seconds": "Sekunden", "size": "Größe", "smtp-auth-config": { @@ -2587,4 +2577,4 @@ } }, "yesterday": "Gestern" -} \ No newline at end of file +} diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index 765ae48f9..d642af27b 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -242,7 +242,6 @@ "label": "Add hint only here" } }, - "selected-text": "Selected text:", "type": "Type", "type-placeholder": "Select type..." }, @@ -639,25 +638,16 @@ "warning": "Warning: This action cannot be undone!" }, "confirmation-dialog": { - "approve-file-without-analysis": { - "confirmationText": "Approve without analysis", - "denyText": "Cancel", - "question": "Analysis required to detect new redactions.", - "title": "Warning!" - }, "approve-file": { - "question": "This document contains unseen changes that have been added during the reanalysis.

Do you still want to approve it?", - "title": "Warning!" - }, - "approve-multiple-files-without-analysis": { - "confirmationText": "Approve without analysis", - "denyText": "Cancel", - "question": "Analysis required to detect new redactions for at least one file.", - "title": "Warning" - }, - "approve-multiple-files": { - "question": "At least one of the selected files contains unseen changes that have been added during the reanalysis.

Do you still want to approve them?", - "title": "Warning!" + "confirmationText": "Approve anyway", + "denyText": "No, cancel", + "question": "Do you still want to approve the {questionLength, plural, one{document} other{documents}}?", + "title": "Approval warning", + "warning-reason": { + "legal-basis-missing": "Legal basis missing", + "pending-changes": "Pending Changes", + "unmapped-justification": "Unmapped justification" + } }, "assign-file-to-me": { "question": { @@ -2587,4 +2577,4 @@ } }, "yesterday": "Yesterday" -} \ No newline at end of file +} diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 3348899e0..324bb1632 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -242,7 +242,6 @@ "label": "Add hint only here" } }, - "selected-text": "Selected text:", "type": "Type", "type-placeholder": "Select type..." }, @@ -276,9 +275,6 @@ "watermarks": "Watermarks" }, "analysis-disabled": "Analysis disabled", - "annotation": { - "pending": "(Pending analysis)" - }, "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" @@ -334,14 +330,14 @@ "error": "Rekategorisierung des Bildes gescheitert: {error}", "success": "Bild wurde einer neuen Kategorie zugeordnet." }, - "remove": { - "error": "Fehler beim Entfernen der Schwärzung: {error}", - "success": "Schwärzung entfernt!" - }, "remove-hint": { "error": "Failed to remove hint: {error}", "success": "Hint removed!" }, + "remove": { + "error": "Fehler beim Entfernen der Schwärzung: {error}", + "success": "Schwärzung entfernt!" + }, "undo": { "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", "success": "erfolgreich Rückgängig gemacht" @@ -354,15 +350,15 @@ "remove-highlights": { "label": "Remove selected earmarks" }, - "resize": { - "label": "Größe ändern" - }, "resize-accept": { "label": "Größe speichern" }, "resize-cancel": { "label": "Größenänderung abbrechen" }, + "resize": { + "label": "Größe ändern" + }, "see-references": { "label": "See references" }, @@ -396,6 +392,9 @@ "skipped": "Übersprungen", "text-highlight": "Earmark" }, + "annotation": { + "pending": "(Pending analysis)" + }, "annotations": "Annotations", "archived-dossiers-listing": { "no-data": { @@ -640,24 +639,15 @@ }, "confirmation-dialog": { "approve-file": { - "question": "Dieses Dokument enthält ungesehene Änderungen. Möchten Sie es trotzdem genehmigen?", - "title": "Warnung!" - }, - "approve-file-without-analysis": { - "confirmationText": "Approve without analysis", - "denyText": "Cancel", - "question": "Analysis required to detect new components.", - "title": "Warning!" - }, - "approve-multiple-files": { - "question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen. Möchten Sie sie trotzdem genehmigen?", - "title": "Warnung!" - }, - "approve-multiple-files-without-analysis": { - "confirmationText": "Approve without analysis", - "denyText": "Cancel", - "question": "Analysis required to detect new components for at least one file.", - "title": "Warning" + "confirmationText": "Approve anyway", + "denyText": "No, cancel", + "question": "Do you still want to approve the {questionLength, plural, one{document} other{documents}}?", + "title": "Approval warning", + "warning-reason": { + "legal-basis-missing": "Legal basis missing", + "pending-changes": "Pending Changes", + "unmapped-justification": "Unmapped justification" + } }, "assign-file-to-me": { "question": { @@ -1028,13 +1018,13 @@ "recent": "Neu ({hours} h)", "unassigned": "Niemandem zugewiesen" }, - "reanalyse": { - "action": "Datei analysieren" - }, "reanalyse-dossier": { "error": "Die Dateien konnten nicht für eine Reanalyse eingeplant werden. Bitte versuchen Sie es erneut.", "success": "Dateien für Reanalyse vorgesehen." }, + "reanalyse": { + "action": "Datei analysieren" + }, "report-download": "Report download", "start-auto-analysis": "Enable auto-analysis", "stop-auto-analysis": "Stop auto-analysis", @@ -1104,14 +1094,6 @@ "total-documents": "Anzahl der Dokumente", "total-people": "{count} {count, plural, one{user} other {users}}" }, - "dossier-templates": { - "label": "Dossier-Vorlagen", - "status": { - "active": "Active", - "inactive": "Inactive", - "incomplete": "Incomplete" - } - }, "dossier-templates-listing": { "action": { "clone": "Clone template", @@ -1146,6 +1128,14 @@ "title": "{length} dossier {length, plural, one{template} other{templates}}" } }, + "dossier-templates": { + "label": "Dossier-Vorlagen", + "status": { + "active": "Active", + "inactive": "Inactive", + "incomplete": "Incomplete" + } + }, "dossier-watermark-selector": { "heading": "Watermarks on documents", "no-watermark": "There is no watermark defined for the dossier template.
Contact your app admin to define one.", @@ -1341,15 +1331,6 @@ "title": "{length} {length, plural, one{entity} other{entities}}" } }, - "entity": { - "info": { - "actions": { - "revert": "Revert", - "save": "Save changes" - }, - "heading": "Edit entity" - } - }, "entity-rules-screen": { "error": { "generic": "Something went wrong... Entity rules update failed!" @@ -1363,19 +1344,28 @@ "title": "Entity rule editor", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} found in rules" }, + "entity": { + "info": { + "actions": { + "revert": "Revert", + "save": "Save changes" + }, + "heading": "Edit entity" + } + }, "error": { "deleted-entity": { "dossier": { "action": "Zurück zur Übersicht", "label": "Dieses Dossier wurde gelöscht!" }, - "file": { - "action": "Zurück zum Dossier", - "label": "Diese Datei wurde gelöscht!" - }, "file-dossier": { "action": "Zurück zur Übersicht", "label": "Das Dossier dieser Datei wurde gelöscht!" + }, + "file": { + "action": "Zurück zum Dossier", + "label": "Diese Datei wurde gelöscht!" } }, "file-preview": { @@ -1393,12 +1383,6 @@ }, "exact-date": "{day} {month} {year} um {hour}:{minute} Uhr", "file": "Datei", - "file-attribute": { - "update": { - "error": "Failed to update file attribute value!", - "success": "File attribute value has been updated successfully!" - } - }, "file-attribute-encoding-types": { "ascii": "ASCII", "iso": "ISO-8859-1", @@ -1409,6 +1393,12 @@ "number": "Nummer", "text": "Freier Text" }, + "file-attribute": { + "update": { + "error": "Failed to update file attribute value!", + "success": "File attribute value has been updated successfully!" + } + }, "file-attributes-configurations": { "cancel": "Cancel", "form": { @@ -1626,15 +1616,6 @@ "csv": "File attributes were imported successfully from uploaded CSV file." } }, - "filter": { - "analysis": "Analyse erforderlich", - "comment": "Kommentare", - "hint": "Nut Hinweise", - "image": "Bilder", - "none": "Keine Anmerkungen", - "redaction": "Geschwärzt", - "updated": "Aktualisiert" - }, "filter-menu": { "filter-options": "Filteroptionen", "filter-types": "Filter", @@ -1644,6 +1625,15 @@ "unseen-pages": "Nur Anmerkungen auf unsichtbaren Seiten", "with-comments": "Nur Anmerkungen mit Kommentaren" }, + "filter": { + "analysis": "Analyse erforderlich", + "comment": "Kommentare", + "hint": "Nut Hinweise", + "image": "Bilder", + "none": "Keine Anmerkungen", + "redaction": "Geschwärzt", + "updated": "Aktualisiert" + }, "filters": { "assigned-people": "Beauftragt", "documents-status": "Documents state", @@ -1922,13 +1912,6 @@ "user-promoted-to-approver": "{user} wurde im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} zum Genehmiger ernannt!", "user-removed-as-dossier-member": "{user} wurde als Mitglied von: {dossierHref, select, null{{dossierName}} other{{dossierName}}} entfernt!" }, - "notifications": { - "button-text": "Notifications", - "deleted-dossier": "Deleted dossier", - "label": "Benachrichtigungen", - "mark-all-as-read": "Alle als gelesen markieren", - "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}" - }, "notifications-screen": { "category": { "email-notifications": "E-Mail Benachrichtigungen", @@ -1942,6 +1925,7 @@ "dossier": "Dossierbezogene Benachrichtigungen", "other": "Andere Benachrichtigungen" }, + "options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten", "options": { "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen bin", "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Überprüfer zugewiesen bin", @@ -1959,7 +1943,6 @@ "USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde", "USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere" }, - "options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten", "schedule": { "daily": "Tägliche Zusammenfassung", "instant": "Sofortig", @@ -1967,6 +1950,13 @@ }, "title": "Benachrichtigungseinstellungen" }, + "notifications": { + "button-text": "Notifications", + "deleted-dossier": "Deleted dossier", + "label": "Benachrichtigungen", + "mark-all-as-read": "Alle als gelesen markieren", + "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}" + }, "ocr": { "confirmation-dialog": { "cancel": "Cancel", @@ -2058,16 +2048,16 @@ "warnings-label": "Prompts and dialogs", "warnings-subtitle": "Do not show again options" }, - "processing": { - "basic": "Processing", - "ocr": "OCR" - }, "processing-status": { "ocr": "OCR", "pending": "Pending", "processed": "Processed", "processing": "Processing" }, + "processing": { + "basic": "Processing", + "ocr": "OCR" + }, "readonly": "Lesemodus", "readonly-archived": "Read only (archived)", "redact-text": { @@ -2303,12 +2293,6 @@ "red-user-admin": "Benutzer-Admin", "regular": "Regulär" }, - "search": { - "active-dossiers": "ganze Plattform", - "all-dossiers": "all documents", - "placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen", - "this-dossier": "in diesem Dossier" - }, "search-screen": { "cols": { "assignee": "Bevollmächtigter", @@ -2332,6 +2316,12 @@ "no-match": "Keine Dokumente entsprechen Ihren aktuellen Filtern.", "table-header": "{length} search {length, plural, one{result} other{results}}" }, + "search": { + "active-dossiers": "ganze Plattform", + "all-dossiers": "all documents", + "placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen", + "this-dossier": "in diesem Dossier" + }, "seconds": "seconds", "size": "Size", "smtp-auth-config": { @@ -2587,4 +2577,4 @@ } }, "yesterday": "Gestern" -} \ No newline at end of file +} diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index 5934e1f48..426738e9c 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -242,7 +242,6 @@ "label": "Add hint only here" } }, - "selected-text": "Selected text:", "type": "Type", "type-placeholder": "Select type..." }, @@ -639,25 +638,16 @@ "warning": "Warning: this cannot be undone!" }, "confirmation-dialog": { - "approve-file-without-analysis": { - "confirmationText": "Approve without analysis", - "denyText": "Cancel", - "question": "Analysis required to detect new components.", - "title": "Warning!" - }, "approve-file": { - "question": "This document has unseen changes, do you wish to approve it anyway?", - "title": "Warning!" - }, - "approve-multiple-files-without-analysis": { - "confirmationText": "Approve without analysis", - "denyText": "Cancel", - "question": "Analysis required to detect new components for at least one file.", - "title": "Warning" - }, - "approve-multiple-files": { - "question": "At least one of the files you selected has unseen changes, do you wish to approve them anyway?", - "title": "Warning!" + "confirmationText": "Approve anyway", + "denyText": "No, cancel", + "question": "Do you still want to approve the {questionLength, plural, one{document} other{documents}}?", + "title": "Approval warning", + "warning-reason": { + "legal-basis-missing": "Legal basis missing", + "pending-changes": "Pending Changes", + "unmapped-justification": "Unmapped justification" + } }, "assign-file-to-me": { "question": { @@ -2587,4 +2577,4 @@ } }, "yesterday": "Yesterday" -} \ No newline at end of file +} diff --git a/libs/common-ui b/libs/common-ui index 2faecb44a..c71a4995a 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 2faecb44a926f02a6d4186e58751ac615f2bfd47 +Subproject commit c71a4995a63e4886bc23a8a8cea7d02d7560c2aa diff --git a/libs/red-domain/src/lib/files/approve-file-types.ts b/libs/red-domain/src/lib/files/approve-file-types.ts new file mode 100644 index 000000000..60da462d6 --- /dev/null +++ b/libs/red-domain/src/lib/files/approve-file-types.ts @@ -0,0 +1,19 @@ +export interface ApproveResponse { + readonly fileId: string; + readonly hasWarnings?: boolean; + readonly fileWarnings: WarningModel[]; +} + +export interface WarningModel { + id: string; + value: string; + pages: number[]; + type: string; + warningType: WarningType; +} + +export enum WarningType { + PENDING_CHANGE = 'PENDING_CHANGE', + LEGAL_BASIS_MISSING = 'LEGAL_BASIS_MISSING', + UNMAPPED_JUSTIFICATION = 'UNMAPPED_JUSTIFICATION', +} diff --git a/libs/red-domain/src/lib/files/index.ts b/libs/red-domain/src/lib/files/index.ts index c238e8dff..a821aefd0 100644 --- a/libs/red-domain/src/lib/files/index.ts +++ b/libs/red-domain/src/lib/files/index.ts @@ -4,3 +4,4 @@ export * from './types'; export * from './file-upload-result'; export * from './overwrite-file-options'; export * from './super-types'; +export * from './approve-file-types'; From 7208126584f2a4ac047064e7428dca3242cc9179 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Thu, 19 Sep 2024 17:36:15 +0300 Subject: [PATCH 022/125] RED-9900: removed help mode helper elements from hidden buttons. --- .../editable-structured-component-value.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/editable-structured-component-value/editable-structured-component-value.component.html b/apps/red-ui/src/app/modules/file-preview/components/editable-structured-component-value/editable-structured-component-value.component.html index b12b528d5..725693fd3 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/editable-structured-component-value/editable-structured-component-value.component.html +++ b/apps/red-ui/src/app/modules/file-preview/components/editable-structured-component-value/editable-structured-component-value.component.html @@ -32,7 +32,7 @@
From b5b465d56f0463c9279e226627d0a9675d4c87d6 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Mon, 23 Sep 2024 11:11:02 +0300 Subject: [PATCH 023/125] RED-7345 - update common ui --- libs/common-ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/common-ui b/libs/common-ui index c644eaeba..c71a4995a 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit c644eaeba2e137607f1ceb42b0ee5ce9a2f68bbe +Subproject commit c71a4995a63e4886bc23a8a8cea7d02d7560c2aa From 43154346e3d55ccc5d30ac0065d6e83bdddb58a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 23 Sep 2024 11:54:00 +0300 Subject: [PATCH 024/125] RED-9830: Don't send additional comment request for annotation edit --- .../services/annotation-actions.service.ts | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts index 7673762e6..bf0907324 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts @@ -1,6 +1,6 @@ -import { inject, Injectable } from '@angular/core'; +import { Injectable } from '@angular/core'; import { IqserDialog } from '@common-ui/dialog/iqser-dialog.service'; -import { getConfig, Toaster } from '@iqser/common-ui'; +import { getConfig } from '@iqser/common-ui'; import { List, log } from '@iqser/common-ui/lib/utils'; import { AnnotationPermissions } from '@models/file/annotation.permissions'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; @@ -13,7 +13,6 @@ import { IRectangle, IResizeRequest, } from '@red/domain'; -import { CommentsApiService } from '@services/comments-api.service'; import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service'; import { PermissionsService } from '@services/permissions.service'; import { firstValueFrom, Observable } from 'rxjs'; @@ -48,7 +47,6 @@ import { SkippedService } from './skipped.service'; @Injectable() export class AnnotationActionsService { readonly #isDocumine = getConfig().IS_DOCUMINE; - readonly #commentsApiService = inject(CommentsApiService); constructor( private readonly _manualRedactionService: ManualRedactionService, @@ -63,7 +61,6 @@ export class AnnotationActionsService { private readonly _skippedService: SkippedService, private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _permissionsService: PermissionsService, - private readonly _toaster: Toaster, ) {} removeHighlights(highlights: AnnotationWrapper[]): void { @@ -107,7 +104,11 @@ export class AnnotationActionsService { } const recategorizeBody: List = annotations.map(annotation => { - const body = { annotationId: annotation.id, type: result.type ?? annotation.type }; + const body: IRecategorizationRequest = { + annotationId: annotation.id, + type: result.type ?? annotation.type, + comment: result.comment, + }; if (!this.#isDocumine) { return { ...body, @@ -130,16 +131,6 @@ export class AnnotationActionsService { ) .pipe(log()), ); - - if (result.comment) { - try { - for (const a of annotations) { - await this.#commentsApiService.add(result.comment, a.id, dossierId, fileId); - } - } catch (error) { - this._toaster.rawError(error.error.message); - } - } } async removeRedaction(redactions: AnnotationWrapper[], permissions: AnnotationPermissions) { From 179abe4f37e0c236bd67a6a6222c242208fc2350 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Mon, 23 Sep 2024 11:58:39 +0300 Subject: [PATCH 025/125] RED-10028: added OPTIMIZED_PREVIEW file type in download selection. --- .../dossier-template-info-screen.component.ts | 2 +- .../edit-dossier-download-package.component.ts | 16 ++++++++++------ .../add-dossier-dialog.component.ts | 16 ++++++++++------ .../download-dialog/download-dialog.component.ts | 2 +- .../translations/download-types-translations.ts | 2 ++ apps/red-ui/src/assets/i18n/redact/de.json | 1 + apps/red-ui/src/assets/i18n/redact/en.json | 1 + apps/red-ui/src/assets/i18n/scm/de.json | 1 + apps/red-ui/src/assets/i18n/scm/en.json | 1 + libs/red-domain/src/lib/shared/types.ts | 1 + 10 files changed, 29 insertions(+), 14 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/screens/info/dossier-template-info-screen/dossier-template-info-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/info/dossier-template-info-screen/dossier-template-info-screen.component.ts index a9b2ffd59..314d5ee3d 100644 --- a/apps/red-ui/src/app/modules/admin/screens/info/dossier-template-info-screen/dossier-template-info-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/info/dossier-template-info-screen/dossier-template-info-screen.component.ts @@ -28,7 +28,7 @@ import { MatIcon } from '@angular/material/icon'; import { SelectComponent } from '@shared/components/select/select.component'; import { MatSuffix } from '@angular/material/form-field'; -const downloadTypes = ['ORIGINAL', 'PREVIEW', 'DELTA_PREVIEW', 'REDACTED'].map(type => ({ +const downloadTypes = ['ORIGINAL', 'PREVIEW', 'OPTIMIZED_PREVIEW', 'DELTA_PREVIEW', 'REDACTED'].map(type => ({ key: type, label: downloadTypesTranslations[type], })); diff --git a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/download-package/edit-dossier-download-package.component.ts b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/download-package/edit-dossier-download-package.component.ts index ce7c1d58c..c41932fba 100644 --- a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/download-package/edit-dossier-download-package.component.ts +++ b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/download-package/edit-dossier-download-package.component.ts @@ -42,12 +42,16 @@ export class EditDossierDownloadPackageComponent { #existsWatermarks$: Observable; form: FormGroup; - downloadTypes: { key: DownloadFileType; label: string }[] = ['ORIGINAL', 'PREVIEW', 'DELTA_PREVIEW', 'REDACTED'].map( - (type: DownloadFileType) => ({ - key: type, - label: downloadTypesTranslations[type], - }), - ); + downloadTypes: { key: DownloadFileType; label: string }[] = [ + 'ORIGINAL', + 'PREVIEW', + 'OPTIMIZED_PREVIEW', + 'DELTA_PREVIEW', + 'REDACTED', + ].map((type: DownloadFileType) => ({ + key: type, + label: downloadTypesTranslations[type], + })); availableReportTypes: IReportTemplate[] = []; readonly roles = Roles; @Input() dossier: Dossier; diff --git a/apps/red-ui/src/app/modules/shared/dialogs/add-dossier-dialog/add-dossier-dialog.component.ts b/apps/red-ui/src/app/modules/shared/dialogs/add-dossier-dialog/add-dossier-dialog.component.ts index b79ea0e3d..23cfa0374 100644 --- a/apps/red-ui/src/app/modules/shared/dialogs/add-dossier-dialog/add-dossier-dialog.component.ts +++ b/apps/red-ui/src/app/modules/shared/dialogs/add-dossier-dialog/add-dossier-dialog.component.ts @@ -71,12 +71,16 @@ export class AddDossierDialogComponent extends BaseDialogComponent implements On readonly roles = Roles; readonly iconButtonTypes = IconButtonTypes; hasDueDate = false; - readonly downloadTypes: { key: DownloadFileType; label: string }[] = ['ORIGINAL', 'PREVIEW', 'DELTA_PREVIEW', 'REDACTED'].map( - (type: DownloadFileType) => ({ - key: type, - label: downloadTypesTranslations[type], - }), - ); + readonly downloadTypes: { key: DownloadFileType; label: string }[] = [ + 'ORIGINAL', + 'PREVIEW', + 'OPTIMIZED_PREVIEW', + 'DELTA_PREVIEW', + 'REDACTED', + ].map((type: DownloadFileType) => ({ + key: type, + label: downloadTypesTranslations[type], + })); dossierTemplates: IDossierTemplate[]; availableReportTypes: IReportTemplate[] = []; dossierTemplateId: string; diff --git a/apps/red-ui/src/app/modules/shared/dialogs/download-dialog/download-dialog.component.ts b/apps/red-ui/src/app/modules/shared/dialogs/download-dialog/download-dialog.component.ts index 169c55d91..27b90a794 100644 --- a/apps/red-ui/src/app/modules/shared/dialogs/download-dialog/download-dialog.component.ts +++ b/apps/red-ui/src/app/modules/shared/dialogs/download-dialog/download-dialog.component.ts @@ -90,7 +90,7 @@ export class DownloadDialogComponent extends IqserDialogComponent ({ key: type, label: downloadTypesForDownloadTranslations[type], diff --git a/apps/red-ui/src/app/translations/download-types-translations.ts b/apps/red-ui/src/app/translations/download-types-translations.ts index e11ea04a9..57ed1c79f 100644 --- a/apps/red-ui/src/app/translations/download-types-translations.ts +++ b/apps/red-ui/src/app/translations/download-types-translations.ts @@ -4,6 +4,7 @@ import { DownloadFileType } from '@red/domain'; export const downloadTypesTranslations: { [key in DownloadFileType]: string } = { ORIGINAL: _('download-type.original'), PREVIEW: _('download-type.preview'), + OPTIMIZED_PREVIEW: _('download-type.optimized-preview'), REDACTED: _('download-type.redacted'), ANNOTATED: _('download-type.annotated'), FLATTEN: _('download-type.flatten'), @@ -13,6 +14,7 @@ export const downloadTypesTranslations: { [key in DownloadFileType]: string } = export const downloadTypesForDownloadTranslations: { [key in DownloadFileType]: string } = { ORIGINAL: _('download-type.original'), PREVIEW: _('download-type.preview'), + OPTIMIZED_PREVIEW: _('download-type.optimized-preview'), REDACTED: _('download-type.redacted-only'), ANNOTATED: _('download-type.annotated'), FLATTEN: _('download-type.flatten'), diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index bbb54f960..d97127b00 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -1167,6 +1167,7 @@ "delta-preview": "Delta-PDF", "flatten": "Verflachte PDF", "label": "{length} Dokumenten{length, plural, one{typ} other{typen}}", + "optimized-preview": "Optimized Preview PDF", "original": "Optimierte PDF", "preview": "Vorschau-PDF", "redacted": "Geschwärzte PDF", diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index d642af27b..b8c85c8c0 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -1167,6 +1167,7 @@ "delta-preview": "Delta PDF", "flatten": "Flatten PDF", "label": "{length} document {length, plural, one{version} other{versions}}", + "optimized-preview": "Optimized Preview PDF", "original": "Optimized PDF", "preview": "Preview PDF", "redacted": "Redacted PDF", diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 324bb1632..dd2b402dc 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -1167,6 +1167,7 @@ "delta-preview": "Delta PDF", "flatten": "PDF verflachen", "label": "{length} document {length, plural, one{version} other{versions}}", + "optimized-preview": "Optimized Preview PDF", "original": "Optimiertes PDF", "preview": "PDF-Vorschau", "redacted": "geschwärztes PDF", diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index 426738e9c..320543548 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -1167,6 +1167,7 @@ "delta-preview": "Delta PDF", "flatten": "Flatten PDF", "label": "{length} document {length, plural, one{version} other{versions}}", + "optimized-preview": "Optimized Preview PDF", "original": "Optimized PDF", "preview": "Preview PDF", "redacted": "Redacted PDF", diff --git a/libs/red-domain/src/lib/shared/types.ts b/libs/red-domain/src/lib/shared/types.ts index 84fdf4d00..5603dbf09 100644 --- a/libs/red-domain/src/lib/shared/types.ts +++ b/libs/red-domain/src/lib/shared/types.ts @@ -3,6 +3,7 @@ export const DownloadFileTypes = { FLATTEN: 'FLATTEN', ORIGINAL: 'ORIGINAL', PREVIEW: 'PREVIEW', + OPTIMIZED_PREVIEW: 'OPTIMIZED_PREVIEW', REDACTED: 'REDACTED', DELTA_PREVIEW: 'DELTA_PREVIEW', } as const; From aa2012bbda06853bfda84c84214beece27af472a Mon Sep 17 00:00:00 2001 From: Christoph Schabert Date: Mon, 23 Sep 2024 11:19:06 +0200 Subject: [PATCH 026/125] Update .gitlab-ci.yml file --- .gitlab-ci.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7ebac71ca..c8c245848 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -21,9 +21,9 @@ localazy update: paths: - .yarn-cache/ script: - - git config user.email "${CI_EMAIL}" - - git config user.name "${CI_USERNAME}" - - git remote add gitlab_origin https://${CI_USERNAME}:${CI_ACCESS_TOKEN}@gitlab.knecon.com/redactmanager/red-ui.git + # - git config user.email "${CI_EMAIL}" + # - git config user.name "${CI_USERNAME}" + # - git remote add gitlab_origin https://${CI_USERNAME}:${CI_ACCESS_TOKEN}@gitlab.knecon.com/redactmanager/red-ui.git - cd tools/localazy - yarn install --cache-folder .yarn-cache - yarn start @@ -35,7 +35,8 @@ localazy update: then git status git commit -m "push back localazy update" - git push gitlab_origin HEAD:${CI_COMMIT_REF_NAME} + # git push gitlab_origin HEAD:${CI_COMMIT_REF_NAME} + git push https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.knecon.com/redactmanager/red-ui.git fi rules: - if: $CI_PIPELINE_SOURCE == "schedule" From 12768b52199a00f1044b9bd7eae4d93ac4140fe8 Mon Sep 17 00:00:00 2001 From: Christoph Schabert Date: Mon, 23 Sep 2024 11:22:16 +0200 Subject: [PATCH 027/125] Update .gitlab-ci.yml file --- .gitlab-ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c8c245848..7f7e48c82 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,6 +24,7 @@ localazy update: # - git config user.email "${CI_EMAIL}" # - git config user.name "${CI_USERNAME}" # - git remote add gitlab_origin https://${CI_USERNAME}:${CI_ACCESS_TOKEN}@gitlab.knecon.com/redactmanager/red-ui.git + - git pull - cd tools/localazy - yarn install --cache-folder .yarn-cache - yarn start @@ -36,7 +37,8 @@ localazy update: git status git commit -m "push back localazy update" # git push gitlab_origin HEAD:${CI_COMMIT_REF_NAME} - git push https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.knecon.com/redactmanager/red-ui.git + # git push https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.knecon.com/redactmanager/red-ui.git + git push fi rules: - if: $CI_PIPELINE_SOURCE == "schedule" From 7f08355311c85e4675d69b3af3e241b7be956eb1 Mon Sep 17 00:00:00 2001 From: Christoph Schabert Date: Mon, 23 Sep 2024 11:25:36 +0200 Subject: [PATCH 028/125] Update .gitlab-ci.yml file --- .gitlab-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7f7e48c82..2a66308db 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,7 +24,6 @@ localazy update: # - git config user.email "${CI_EMAIL}" # - git config user.name "${CI_USERNAME}" # - git remote add gitlab_origin https://${CI_USERNAME}:${CI_ACCESS_TOKEN}@gitlab.knecon.com/redactmanager/red-ui.git - - git pull - cd tools/localazy - yarn install --cache-folder .yarn-cache - yarn start From 63e53cb2ed5cf337facd42fe022db936c4107abc Mon Sep 17 00:00:00 2001 From: Christoph Schabert Date: Mon, 23 Sep 2024 11:31:08 +0200 Subject: [PATCH 029/125] Update .gitlab-ci.yml file --- .gitlab-ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2a66308db..8ace6ab80 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,6 +24,7 @@ localazy update: # - git config user.email "${CI_EMAIL}" # - git config user.name "${CI_USERNAME}" # - git remote add gitlab_origin https://${CI_USERNAME}:${CI_ACCESS_TOKEN}@gitlab.knecon.com/redactmanager/red-ui.git + - git push https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.knecon.com/redactmanager/red-ui.git - cd tools/localazy - yarn install --cache-folder .yarn-cache - yarn start @@ -35,9 +36,9 @@ localazy update: then git status git commit -m "push back localazy update" - # git push gitlab_origin HEAD:${CI_COMMIT_REF_NAME} + git push gitlab_origin HEAD:${CI_COMMIT_REF_NAME} # git push https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.knecon.com/redactmanager/red-ui.git - git push + # git push fi rules: - if: $CI_PIPELINE_SOURCE == "schedule" From b5f1afb81effcc46a85d157e4fc312f7ed406307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominique=20Eifl=C3=A4nder?= Date: Mon, 23 Sep 2024 11:53:26 +0200 Subject: [PATCH 030/125] RED-10084: All members of a dossier are able to reanalyse files in error state, no only the owner or assignee --- apps/red-ui/src/app/services/permissions.service.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/red-ui/src/app/services/permissions.service.ts b/apps/red-ui/src/app/services/permissions.service.ts index f1c283543..382711250 100644 --- a/apps/red-ui/src/app/services/permissions.service.ts +++ b/apps/red-ui/src/app/services/permissions.service.ts @@ -401,11 +401,7 @@ export class PermissionsService { } #canReanalyseFile(file: File, dossier: Dossier): boolean { - return ( - dossier.isActive && - ((this.isAssigneeOrApprover(file, dossier) && file.analysisRequired) || - (file.isError && (this.isOwner(dossier) || this.isFileAssignee(file)))) - ); + return dossier.isActive && ((this.isAssigneeOrApprover(file, dossier) && file.analysisRequired) || file.isError); } #canEnableAutoAnalysis(file: File, dossier: Dossier): boolean { From 5de6b359ee514c24f1be1026807d9b45ca645afe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 23 Sep 2024 13:18:05 +0300 Subject: [PATCH 031/125] Revision of the dossier dictionary presentation --- .../edit-dossier-dictionary.component.html | 64 ++++++++------- .../dictionary-manager.component.html | 31 ++------ .../dictionary-manager.component.ts | 77 +++---------------- .../components/editor/editor.component.ts | 25 +++--- apps/red-ui/src/assets/i18n/redact/de.json | 7 +- apps/red-ui/src/assets/i18n/redact/en.json | 9 ++- apps/red-ui/src/assets/i18n/scm/de.json | 7 +- apps/red-ui/src/assets/i18n/scm/en.json | 7 +- 8 files changed, 87 insertions(+), 140 deletions(-) diff --git a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.html b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.html index 727bec369..7d5b0684e 100644 --- a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.html +++ b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.html @@ -18,12 +18,15 @@
- {{ - dictionary.entries.length + - dictionary.falsePositiveEntries.length + - dictionary.falseRecommendationEntries.length - }} - entries +
@@ -36,12 +39,12 @@
{{ selectedDictionary?.label }}
@@ -68,23 +71,6 @@
-
- - - -
+ > + +
+ + + +
+
+ diff --git a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html index 546c0c2f2..4557166e6 100644 --- a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html +++ b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html @@ -1,29 +1,7 @@
-
- - -
-
- -
- -
- {{ currentMatch + '/' + findMatches.length }} - - - -
-
-
+ + +
diff --git a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts index a842204f7..5145a99bc 100644 --- a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts @@ -8,9 +8,7 @@ import { DossierTemplatesService } from '@services/dossier-templates/dossier-tem import { EditorComponent } from '@shared/components/editor/editor.component'; import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service'; import { saveAs } from 'file-saver'; -import { Debounce, List } from '@iqser/common-ui/lib/utils'; -import IModelDeltaDecoration = monaco.editor.IModelDeltaDecoration; -import FindMatch = monaco.editor.FindMatch; +import { List } from '@iqser/common-ui/lib/utils'; import { firstValueFrom } from 'rxjs'; import { MatIcon } from '@angular/material/icon'; import { NgForOf, NgIf } from '@angular/common'; @@ -23,7 +21,6 @@ import { MatOption, MatSelect } from '@angular/material/select'; import { MatDivider } from '@angular/material/divider'; const COMPARE_ENTRIES_ERROR = 'compare-entries-error'; -const SMOOTH_SCROLL = 0; const HELP_MODE_KEYS = { dictionary: 'dictionary_entity', 'false-positive': 'false_recommendations_entity', @@ -53,8 +50,6 @@ const HELP_MODE_KEYS = { ], }) export class DictionaryManagerComponent implements OnChanges, OnInit { - private _searchDecorations: string[] = []; - readonly #currentTab = window.location.href.split('/').pop(); @Input() type: DictionaryType = 'dictionary'; @Input() entityType?: string; @Input() currentDossierId: string; @@ -73,11 +68,8 @@ export class DictionaryManagerComponent implements OnChanges, OnInit { readonly iconButtonTypes = IconButtonTypes; dossiers: Dossier[]; dossierTemplates: DossierTemplate[] = this.dossierTemplatesService.all; - currentMatch = 0; - findMatches: FindMatch[] = []; diffEditorText = ''; showDiffEditor = false; - searchText = ''; selectDossier = { dossierName: _('dictionary-overview.compare.select-dossier') } as Dossier; selectDictionary = { label: _('dictionary-overview.compare.select-dictionary'), @@ -85,10 +77,11 @@ export class DictionaryManagerComponent implements OnChanges, OnInit { selectDossierTemplate = { name: _('dictionary-overview.compare.select-dossier-template') } as DossierTemplate; compare = false; dictionaries: List = this.#dictionaries; + protected initialDossierTemplateId: string; + readonly #currentTab = window.location.href.split('/').pop(); #dossierTemplate = this.dossierTemplatesService.all[0]; #dossier = this.selectDossier; #dictionary = this.selectDictionary; - protected initialDossierTemplateId: string; constructor( private readonly _dictionaryService: DictionaryService, @@ -99,11 +92,6 @@ export class DictionaryManagerComponent implements OnChanges, OnInit { readonly dossierTemplatesService: DossierTemplatesService, ) {} - ngOnInit() { - this.initialDossierTemplateId = this.currentDossierTemplateId; - this.#updateDropdownsOptions(); - } - get selectedDossierTemplate() { return this.#dossierTemplate; } @@ -150,6 +138,7 @@ export class DictionaryManagerComponent implements OnChanges, OnInit { if (dictionary.type) { this.selectedDictionaryType = dictionary.type; this.#dictionary = dictionary; + console.log(dictionary); this.#onDossierChanged(this.#dossier.dossierTemplateId).then(entries => this.#updateDiffEditorText(entries)); } } @@ -185,6 +174,11 @@ export class DictionaryManagerComponent implements OnChanges, OnInit { ); } + ngOnInit() { + this.initialDossierTemplateId = this.currentDossierTemplateId; + this.#updateDropdownsOptions(); + } + download(): void { const content = this.editor.currentEntries.join('\n'); const blob = new Blob([content], { @@ -195,35 +189,6 @@ export class DictionaryManagerComponent implements OnChanges, OnInit { revert() { this.editor?.revert(); - this.searchText = ''; - this.searchChanged(''); - } - - @Debounce() - searchChanged(text: string) { - this.findMatches = this.#getMatches(text.toLowerCase()); - this.#applySearchDecorations(); - - this.currentMatch = 0; - this.nextSearchMatch(); - } - - nextSearchMatch(): void { - if (this.findMatches.length <= 0) { - return; - } - - this.currentMatch = this.currentMatch < this.findMatches.length ? this.currentMatch + 1 : 1; - this.#scrollToCurrentMatch(); - } - - previousSearchMatch(): void { - if (this.findMatches.length <= 0) { - return; - } - - this.currentMatch = this.currentMatch > 1 ? this.currentMatch - 1 : this.findMatches.length; - this.#scrollToCurrentMatch(); } toggleCompareMode() { @@ -246,30 +211,6 @@ export class DictionaryManagerComponent implements OnChanges, OnInit { } } - #applySearchDecorations() { - this._searchDecorations = this.editor.codeEditor?.deltaDecorations(this._searchDecorations, []) || []; - - const decorations = this.findMatches.map(match => this.#getSearchDecoration(match)); - - this._searchDecorations = this.editor.codeEditor?.deltaDecorations(this._searchDecorations, decorations) || []; - } - - #getMatches(text: string): FindMatch[] { - const model = this.editor.codeEditor?.getModel(); - return model?.findMatches(text, false, false, false, null, false) || []; - } - - #getSearchDecoration(match: FindMatch): IModelDeltaDecoration { - return { range: match.range, options: { inlineClassName: 'search-marker' } }; - } - - #scrollToCurrentMatch(): void { - const range = this.findMatches[this.currentMatch - 1].range; - - this.editor.codeEditor.setSelection(range); - this.editor.codeEditor.revealLineInCenter(range.startLineNumber, SMOOTH_SCROLL); - } - async #onDossierChanged(dossierTemplateId: string, dossierId?: string) { let dictionary: IDictionary; if (dossierId === 'template') { diff --git a/apps/red-ui/src/app/modules/shared/components/editor/editor.component.ts b/apps/red-ui/src/app/modules/shared/components/editor/editor.component.ts index e5fa526f5..45a452d89 100644 --- a/apps/red-ui/src/app/modules/shared/components/editor/editor.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/editor/editor.component.ts @@ -5,15 +5,15 @@ import { Subject } from 'rxjs'; import { debounceTime, filter, tap } from 'rxjs/operators'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { List, OnChange } from '@iqser/common-ui/lib/utils'; -import IStandaloneEditorConstructionOptions = monaco.editor.IStandaloneEditorConstructionOptions; -import ICodeEditor = monaco.editor.ICodeEditor; -import IDiffEditor = monaco.editor.IDiffEditor; -import IModelDeltaDecoration = monaco.editor.IModelDeltaDecoration; -import ILineChange = monaco.editor.ILineChange; -import IEditorMouseEvent = monaco.editor.IEditorMouseEvent; import { MonacoEditorModule, MonacoStandaloneCodeEditor, MonacoStandaloneDiffEditor } from '@materia-ui/ngx-monaco-editor'; import { FormsModule } from '@angular/forms'; import { NgIf } from '@angular/common'; +import IStandaloneEditorConstructionOptions = monaco.editor.IStandaloneEditorConstructionOptions; +import IDiffEditor = monaco.editor.IDiffEditor; +import ICodeEditor = monaco.editor.ICodeEditor; +import IModelDeltaDecoration = monaco.editor.IModelDeltaDecoration; +import ILineChange = monaco.editor.ILineChange; +import IEditorMouseEvent = monaco.editor.IEditorMouseEvent; const MIN_WORD_LENGTH = 2; const lineChangeToDecoration = ({ originalEndLineNumber, originalStartLineNumber }: ILineChange) => @@ -35,10 +35,6 @@ const notZero = (lineChange: ILineChange) => lineChange.originalEndLineNumber != imports: [MonacoEditorModule, FormsModule, NgIf], }) export class EditorComponent implements OnInit, OnChanges { - #initialEntriesSet = new Set(); - private _diffEditor: IDiffEditor; - private _decorations: string[] = []; - protected readonly _editorTextChanged$ = new Subject(); @Input() showDiffEditor = false; @Input() diffEditorText: string; @Input() @OnChange('revert') initialEntries: List; @@ -51,6 +47,10 @@ export class EditorComponent implements OnInit, OnChanges { editorOptions: IStandaloneEditorConstructionOptions = {}; codeEditor: ICodeEditor; value: string; + protected readonly _editorTextChanged$ = new Subject(); + #initialEntriesSet = new Set(); + private _diffEditor: IDiffEditor; + private _decorations: string[] = []; constructor( private readonly _loadingService: LoadingService, @@ -84,6 +84,11 @@ export class EditorComponent implements OnInit, OnChanges { return this.currentEntries.length; } + async openFindPanel(): Promise { + const editor = this.showDiffEditor ? this._diffEditor.getOriginalEditor() : this.codeEditor; + await editor.getAction('actions.find').run(); + } + onPaste(event: ClipboardEvent) { if ((event.target as HTMLTextAreaElement).ariaRoleDescription === 'editor') { this._loadingService.start(); diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index d97127b00..aa1b41c55 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -1234,11 +1234,12 @@ "title": "{label} bearbeiten" }, "entries": "{length} {length, plural, one{Eintrag} other{Einträge}}", + "entries-count": "", "false-positive-entries": "{length} {length, plural, one{Falsch-Positiver} other{Falsch-Positive}}", - "false-positives": "Falsch-Positive", + "false-positives": "Falsch-Positive ({count})", "false-recommendation-entries": "{length} {length, plural, one{falsche Empfehlung} other{falsche Empfehlungen}}", - "false-recommendations": "Falsche Empfehlungen", - "to-redact": "Schwärzungen" + "false-recommendations": "Falsche Empfehlungen ({count})", + "to-redact": "Schwärzungen ({count})" }, "general-info": { "form": { diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index b8c85c8c0..2520c4e6a 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -1234,11 +1234,12 @@ "title": "Edit {label}" }, "entries": "{length} {length, plural, one{entry} other{entries}} to redact", + "entries-count": "{count} {count, plural, one{entry} other{entries}}", "false-positive-entries": "{length} false positive {length, plural, one{entry} other{entries}}", - "false-positives": "False positives", + "false-positives": "False positives ({count})", "false-recommendation-entries": "{length} false recommendation {length, plural, one{entry} other{entries}}", - "false-recommendations": "False recommendations", - "to-redact": "To redact" + "false-recommendations": "False recommendations ({count})", + "to-redact": "Entries ({count})" }, "general-info": { "form": { @@ -1264,7 +1265,7 @@ "choose-download": "Select the documents for your download:", "dictionary": "Dictionaries", "dossier-attributes": "Dossier attributes", - "dossier-dictionary": "Dictionaries", + "dossier-dictionary": "Dossier entries", "dossier-info": "Dossier info", "download-package": "Download package", "general-info": "General information", diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index dd2b402dc..cf1f3bb46 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -1234,11 +1234,12 @@ "title": "" }, "entries": "{length} {length, plural, one{entry} other{entries}} to {hint, select, true{annotate} other{redact}}", + "entries-count": "", "false-positive-entries": "{length} false positive {length, plural, one{entry} other{entries}}", - "false-positives": "False positives", + "false-positives": "False positives ({count})", "false-recommendation-entries": "{length} false recommendation {length, plural, one{entry} other{entries}}", - "false-recommendations": "False recommendations", - "to-redact": "To redact" + "false-recommendations": "False recommendations ({count})", + "to-redact": "To redact ({count})" }, "general-info": { "form": { diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index 320543548..66f48bef9 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -1234,11 +1234,12 @@ "title": "" }, "entries": "{length} {length, plural, one{entry} other{entries}} to {hint, select, true{annotate} other{redact}}", + "entries-count": "{count} {count, plural, one{entry} other{entries}}", "false-positive-entries": "{length} false positive {length, plural, one{entry} other{entries}}", - "false-positives": "False positives", + "false-positives": "False positives ({count})", "false-recommendation-entries": "{length} false recommendation {length, plural, one{entry} other{entries}}", - "false-recommendations": "False recommendations", - "to-redact": "To redact" + "false-recommendations": "False recommendations ({count})", + "to-redact": "To redact ({count})" }, "general-info": { "form": { From bda96f952ea20dbd02a50cc8fc72df538003c81f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 23 Sep 2024 14:12:29 +0300 Subject: [PATCH 032/125] Use new transactional endpoint for updating dictionaries --- .../entity-services/dictionary.service.ts | 43 ++++++------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/apps/red-ui/src/app/services/entity-services/dictionary.service.ts b/apps/red-ui/src/app/services/entity-services/dictionary.service.ts index dee8cf209..aa91e81f0 100644 --- a/apps/red-ui/src/app/services/entity-services/dictionary.service.ts +++ b/apps/red-ui/src/app/services/entity-services/dictionary.service.ts @@ -1,7 +1,7 @@ import { HttpErrorResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; -import { EntitiesService, getConfig, isIqserDevMode, QueryParam, Toaster } from '@iqser/common-ui'; +import { EntitiesService, isIqserDevMode, Toaster } from '@iqser/common-ui'; import { List } from '@iqser/common-ui/lib/utils'; import { Dictionary, DictionaryEntryType, DictionaryEntryTypes, IDictionary, IUpdateDictionary, SuperTypes } from '@red/domain'; import { firstValueFrom, forkJoin, Observable } from 'rxjs'; @@ -112,23 +112,18 @@ export class DictionaryService extends EntitiesService } entriesToAdd.push(entry); } - const deletedEntries: Array = []; + const entriesToDelete: Array = []; const entriesSet = new Set(entries); for (let i = 0; i < initialEntries.length; i++) { const entry = initialEntries.at(i); if (entriesSet.has(entry)) { continue; } - deletedEntries.push(entry); + entriesToDelete.push(entry); } try { - if (deletedEntries.length) { - await this.#deleteEntries(deletedEntries, dossierTemplateId, type, dictionaryEntryType, dossierId); - } - if (entriesToAdd.length) { - await this.#addEntries(entriesToAdd, dossierTemplateId, type, dictionaryEntryType, dossierId); - } + await this.#updateEntries(entriesToAdd, entriesToDelete, dossierTemplateId, type, dictionaryEntryType, dossierId); if (showToast) { this._toaster.success(_('dictionary-overview.success.generic')); @@ -249,30 +244,20 @@ export class DictionaryService extends EntitiesService return forkJoin(requests); } - /** - * Add dictionary entries with entry type. - */ - - #addEntries(entries: List, dossierTemplateId: string, type: string, dictionaryEntryType: DictionaryEntryType, dossierId: string) { - const queryParams: List = [ - { key: 'dossierId', value: dossierId }, - { key: 'dictionaryEntryType', value: dictionaryEntryType }, - ]; - const url = `${this._defaultModelPath}/${type}/${dossierTemplateId}`; - return firstValueFrom(this._post(entries, url, queryParams)); - } - - /** - * Delete dictionary entries with entry type. - */ - - #deleteEntries(entries: List, dossierTemplateId: string, type: string, dictionaryEntryType: DictionaryEntryType, dossierId: string) { + #updateEntries( + entriesToAdd: List, + entriesToDelete: List, + dossierTemplateId: string, + type: string, + dictionaryEntryType: DictionaryEntryType, + dossierId: string, + ) { const queryParams = [ { key: 'dossierId', value: dossierId }, { key: 'dictionaryEntryType', value: dictionaryEntryType }, ]; - const url = `${this._defaultModelPath}/delete/${type}/${dossierTemplateId}`; - return firstValueFrom(this._post(entries, url, queryParams)); + const url = `${this._defaultModelPath}/update/${type}/${dossierTemplateId}`; + return firstValueFrom(this._post({ entriesToAdd, entriesToDelete }, url, queryParams)); } #extractDossierLevelTypes(dossierId: string) { From f52a378280f9d31d5acfca7842f9a404afdabc56 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Mon, 23 Sep 2024 14:45:54 +0300 Subject: [PATCH 033/125] WIP on VM/RED-7345 RED-7345 - adapted "force redaction" and "accept recommendation" dialogs to use new bulk-local api --- .../force-annotation-dialog.component.ts | 1 + .../redact-text-dialog.component.ts | 43 +++++++------------ .../services/annotation-actions.service.ts | 19 ++++++-- .../services/manual-redaction.service.ts | 10 ++++- .../services/pdf-proxy.service.ts | 1 - .../enhance-manual-redaction-request.utils.ts | 40 +++++++++++++++++ .../legal-basis/legal-basis-change.request.ts | 1 + 7 files changed, 81 insertions(+), 34 deletions(-) create mode 100644 apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts index 1f41643c1..df634df2e 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts @@ -145,6 +145,7 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen request.legalBasis = !this.isDocumine ? this.form.get('reason').value.legalBasis : DOCUMINE_LEGAL_BASIS; request.comment = this.form.get('comment').value; + request.reason = this.form.get('reason').value.description; request.option = this.form.get('option').value.value; return request; diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts index df94ab8bb..63332bb0a 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts @@ -23,6 +23,7 @@ import { SystemDefaultOption, SystemDefaults } from '../../../account/utils/dial import { getRedactOrHintOptions } from '../../utils/dialog-options'; import { RedactOrHintOption, RedactOrHintOptions, RedactTextData, RedactTextResult, ResizeOptions } from '../../utils/dialog-types'; import { LegalBasisOption } from '../manual-redaction-dialog/manual-annotation-dialog.component'; +import { enhanceManualRedactionRequest, EnhanceRequestData } from '../../utils/enhance-manual-redaction-request.utils'; const MAXIMUM_TEXT_AREA_WIDTH = 421; @@ -170,8 +171,8 @@ export class RedactTextDialogComponent } save(): void { - this.#enhanceManualRedaction(this.data.manualRedactionEntryWrapper.manualRedactionEntry); const redaction = this.data.manualRedactionEntryWrapper.manualRedactionEntry; + enhanceManualRedactionRequest(redaction, this.#enhanceRequestData); this.close({ redaction, dictionary: this.dictionaries.find(d => d.type === this.form.controls.dictionary.value), @@ -227,33 +228,6 @@ export class RedactTextDialogComponent } } - #enhanceManualRedaction(addRedactionRequest: IAddRedactionRequest) { - addRedactionRequest.type = this.form.controls.dictionary.value; - addRedactionRequest.section = null; - addRedactionRequest.value = this.form.controls.selectedText.value; - - const legalOption: LegalBasisOption = this.form.controls.reason.value; - if (legalOption) { - addRedactionRequest.reason = legalOption.description; - addRedactionRequest.legalBasis = legalOption.legalBasis; - } - - const selectedType = this.dictionaries.find(d => d.type === addRedactionRequest.type); - - if (selectedType) { - addRedactionRequest.addToDictionary = selectedType.hasDictionary; - } else { - addRedactionRequest.addToDictionary = this.dictionaryRequest && addRedactionRequest.type !== 'dossier_redaction'; - } - - if (!addRedactionRequest.reason) { - addRedactionRequest.reason = 'Dictionary Request'; - } - const commentValue = this.form.controls.comment.value; - addRedactionRequest.comment = commentValue ? { text: commentValue } : null; - addRedactionRequest.addToAllDossiers = this.data.isApprover && this.dictionaryRequest && this.#applyToAllDossiers; - } - #resetValues() { this.#applyToAllDossiers = this.applyToAll; this.options[2].extraOption.checked = this.#applyToAllDossiers; @@ -268,4 +242,17 @@ export class RedactTextDialogComponent #getOption(option: RedactOrHintOption): DetailsRadioOption { return this.options.find(o => o.value === option); } + + get #enhanceRequestData(): EnhanceRequestData { + return { + type: this.form.controls.dictionary.value, + selectedText: this.form.controls.selectedText.value, + reason: this.form.controls.reason.value, + dictionaries: this.dictionaries, + dictionaryRequest: this.dictionaryRequest, + comment: this.form.controls.comment.value, + isApprover: this.data.isApprover, + applyToAllDossiers: this.#applyToAllDossiers, + }; + } } diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts index 519cf8c7a..366b809f6 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts @@ -90,8 +90,15 @@ export class AnnotationActionsService { annotations[0].isIgnoredHint, ); } else { - console.log('annotation: ', annotations[0]); - obs$ = this._manualRedactionService.addAnnotation(annotations, dossierId, fileId, { + const addAnnotationRequest = annotations.map(a => ({ + comment: { text: request.comment }, + legalBasis: request.legalBasis, + reason: request.reason, + positions: a.positions, + type: a.type, + value: a.value, + })); + obs$ = this._manualRedactionService.addAnnotation(addAnnotationRequest, dossierId, fileId, { hint, bulkLocal: true, }); @@ -210,7 +217,13 @@ export class AnnotationActionsService { this.cancelResize(recommendations[0]).then(); } - const request$ = this._manualRedactionService.addRecommendation(recommendations, result.redaction, dossierId, fileId); + const request$ = this._manualRedactionService.addRecommendation( + recommendations, + result.redaction, + dossierId, + fileId, + result.bulkLocal, + ); return this.#processObsAndEmit(request$); } diff --git a/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts b/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts index 630592f99..6186a2b12 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts @@ -49,7 +49,13 @@ export class ManualRedactionService extends GenericService { super(); } - addRecommendation(annotations: AnnotationWrapper[], redaction: IAddRedactionRequest, dossierId: string, fileId: string) { + addRecommendation( + annotations: AnnotationWrapper[], + redaction: IAddRedactionRequest, + dossierId: string, + fileId: string, + bulkLocal: boolean = false, + ) { const recommendations: List = annotations.map(annotation => ({ addToDictionary: redaction.addToDictionary, addToAllDossiers: redaction.addToAllDossiers, @@ -60,7 +66,7 @@ export class ManualRedactionService extends GenericService { type: redaction.type ?? annotation.type, comment: redaction.comment, })); - return this.addAnnotation(recommendations, dossierId, fileId); + return this.addAnnotation(recommendations, dossierId, fileId, { bulkLocal }); } recategorizeRedactions( diff --git a/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts b/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts index 607d21538..976be8626 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts @@ -224,7 +224,6 @@ export class PdfProxyService { const selectedQuads: Record = this._pdf.documentViewer.getSelectedTextQuads(); const text = this._documentViewer.selectedText; const manualRedactionEntry = this.#getManualRedaction(selectedQuads, text, true); - console.log('manualRedactionEntry: ', manualRedactionEntry); this.redactTextRequested$.next({ manualRedactionEntry, type }); } diff --git a/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts b/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts new file mode 100644 index 000000000..25291fd22 --- /dev/null +++ b/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts @@ -0,0 +1,40 @@ +import { Dictionary, IAddRedactionRequest, SuperType } from '@red/domain'; +import { LegalBasisOption } from '../dialogs/manual-redaction-dialog/manual-annotation-dialog.component'; + +export interface EnhanceRequestData { + readonly type: SuperType | null; + readonly selectedText: string; + readonly reason: LegalBasisOption; + readonly dictionaries: Dictionary[]; + readonly dictionaryRequest: boolean; + readonly comment: string; + readonly isApprover: boolean; + readonly applyToAllDossiers: boolean; +} + +export const enhanceManualRedactionRequest = (addRedactionRequest: IAddRedactionRequest, data: EnhanceRequestData) => { + addRedactionRequest.type = data.type; + addRedactionRequest.section = null; + addRedactionRequest.value = data.selectedText; + + const legalOption: LegalBasisOption = data.reason; + if (legalOption) { + addRedactionRequest.reason = legalOption.description; + addRedactionRequest.legalBasis = legalOption.legalBasis; + } + + const selectedType = data.dictionaries.find(d => d.type === addRedactionRequest.type); + + if (selectedType) { + addRedactionRequest.addToDictionary = selectedType.hasDictionary; + } else { + addRedactionRequest.addToDictionary = data.dictionaryRequest && addRedactionRequest.type !== 'dossier_redaction'; + } + + if (!addRedactionRequest.reason) { + addRedactionRequest.reason = 'Dictionary Request'; + } + const commentValue = data.comment; + addRedactionRequest.comment = commentValue ? { text: commentValue } : null; + addRedactionRequest.addToAllDossiers = data.isApprover && data.dictionaryRequest && data.applyToAllDossiers; +}; diff --git a/libs/red-domain/src/lib/legal-basis/legal-basis-change.request.ts b/libs/red-domain/src/lib/legal-basis/legal-basis-change.request.ts index 1f27f5418..de3e9f2e1 100644 --- a/libs/red-domain/src/lib/legal-basis/legal-basis-change.request.ts +++ b/libs/red-domain/src/lib/legal-basis/legal-basis-change.request.ts @@ -4,5 +4,6 @@ export interface ILegalBasisChangeRequest { annotationId?: string; comment?: string; legalBasis?: string; + reason?: string; option?: ForceAnnotationOption; } From b92d9c9e04e97e0d28b9be13fce906c862d958b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 23 Sep 2024 15:52:20 +0300 Subject: [PATCH 034/125] RED-9840: Allow to open global search results in a new browser tab --- .../search-item-template.component.html | 112 +++++++++--------- .../search-item-template.component.scss | 5 + 2 files changed, 62 insertions(+), 55 deletions(-) diff --git a/apps/red-ui/src/app/modules/search/search-item-template/search-item-template.component.html b/apps/red-ui/src/app/modules/search/search-item-template/search-item-template.component.html index a3683d8b2..ce87e4531 100644 --- a/apps/red-ui/src/app/modules/search/search-item-template/search-item-template.component.html +++ b/apps/red-ui/src/app/modules/search/search-item-template/search-item-template.component.html @@ -1,62 +1,64 @@ -
-
- - {{ item.filename }} -
- - -
- + +
+
+ + {{ item.filename }}
-
- + + +
+ +
+
+ +
+
+ +
+ + {{ 'search-screen.missing' | translate }}: {{ term }}. {{ 'search-screen.must-contain' | translate }}: +  {{ term }} +
- - -
- - {{ 'search-screen.missing' | translate }}: {{ term }}. {{ 'search-screen.must-contain' | translate }}: -  {{ term }} -
-
-
- -
- -
- -
- -
- -
-
- - {{ item.numberOfPages }} +
+
-
+ + + +
+
+ + {{ item.numberOfPages }} +
+
+ diff --git a/apps/red-ui/src/app/modules/search/search-item-template/search-item-template.component.scss b/apps/red-ui/src/app/modules/search/search-item-template/search-item-template.component.scss index 7bf631ad2..d9b2dd141 100644 --- a/apps/red-ui/src/app/modules/search/search-item-template/search-item-template.component.scss +++ b/apps/red-ui/src/app/modules/search/search-item-template/search-item-template.component.scss @@ -7,3 +7,8 @@ background-color: var(--iqser-highlight-color); } } + +a.item-link { + display: contents; + @include common-mixins.clear-a; +} From c6595c64817a8aa372e2889c70a8548f082a9eab Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Mon, 23 Sep 2024 15:56:31 +0300 Subject: [PATCH 035/125] RED-9993: fixed license labels. --- .../license-analysis-capacity-usage.component.ts | 4 ++-- .../license-page-usage/license-page-usage.component.ts | 4 ++-- .../app/modules/admin/screens/license/utils/functions.ts | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/screens/license/components/license-analysis-capacity-usage/license-analysis-capacity-usage.component.ts b/apps/red-ui/src/app/modules/admin/screens/license/components/license-analysis-capacity-usage/license-analysis-capacity-usage.component.ts index 7995cd9bb..e99ef2cbf 100644 --- a/apps/red-ui/src/app/modules/admin/screens/license/components/license-analysis-capacity-usage/license-analysis-capacity-usage.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/license/components/license-analysis-capacity-usage/license-analysis-capacity-usage.component.ts @@ -3,7 +3,7 @@ import { LicenseService } from '@services/license.service'; import { map } from 'rxjs/operators'; import { ChartDataset } from 'chart.js'; import { ChartBlue, ChartGreen, ChartRed } from '../../utils/constants'; -import { getDataUntilCurrentMonth, getLabelsFromLicense, getLineConfig, isCurrentMonthAndYear } from '../../utils/functions'; +import { getDataUntilCurrentMonth, getLabelsFromLicense, getLineConfig, isCurrentMonth } from '../../utils/functions'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { size } from '@iqser/common-ui/lib/utils'; @@ -43,7 +43,7 @@ export class LicenseAnalysisCapacityUsageComponent { #getCapacityDatasets(): ChartDataset[] { const monthlyData = [...this.licenseService.selectedLicenseReport.monthlyData]; const dataUntilCurrentMonth = getDataUntilCurrentMonth(monthlyData); - if (monthlyData.length === 1 || isCurrentMonthAndYear(monthlyData[0].startDate)) { + if (monthlyData.length === 1 || isCurrentMonth(monthlyData[0].startDate)) { const empty = { analysedFilesBytes: null } as ILicenseData; dataUntilCurrentMonth.splice(0, 0, empty); monthlyData.splice(0, 0, empty); diff --git a/apps/red-ui/src/app/modules/admin/screens/license/components/license-page-usage/license-page-usage.component.ts b/apps/red-ui/src/app/modules/admin/screens/license/components/license-page-usage/license-page-usage.component.ts index 7a3c1d3ab..88ebfde38 100644 --- a/apps/red-ui/src/app/modules/admin/screens/license/components/license-page-usage/license-page-usage.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/license/components/license-page-usage/license-page-usage.component.ts @@ -3,7 +3,7 @@ import { LicenseService } from '@services/license.service'; import { map } from 'rxjs/operators'; import { ChartDataset } from 'chart.js'; import { ChartBlue, ChartGreen, ChartRed } from '../../utils/constants'; -import { getDataUntilCurrentMonth, getLabelsFromLicense, getLineConfig, isCurrentMonthAndYear } from '../../utils/functions'; +import { getDataUntilCurrentMonth, getLabelsFromLicense, getLineConfig, isCurrentMonth } from '../../utils/functions'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { ILicenseData } from '@red/domain'; @@ -40,7 +40,7 @@ export class LicensePageUsageComponent { #getPagesDatasets(): ChartDataset[] { const monthlyData = [...this.licenseService.selectedLicenseReport.monthlyData]; const dataUntilCurrentMonth = getDataUntilCurrentMonth(monthlyData); - if (monthlyData.length === 1 || isCurrentMonthAndYear(monthlyData[0].startDate)) { + if (monthlyData.length === 1 || isCurrentMonth(monthlyData[0].startDate)) { const empty = { numberOfAnalyzedPages: null } as ILicenseData; dataUntilCurrentMonth.splice(0, 0, empty); monthlyData.splice(0, 0, empty); diff --git a/apps/red-ui/src/app/modules/admin/screens/license/utils/functions.ts b/apps/red-ui/src/app/modules/admin/screens/license/utils/functions.ts index 2c3a9ce3e..a06f15c17 100644 --- a/apps/red-ui/src/app/modules/admin/screens/license/utils/functions.ts +++ b/apps/red-ui/src/app/modules/admin/screens/license/utils/functions.ts @@ -44,7 +44,7 @@ export const getLabelsFromLicense = (license: ILicenseReport) => { monthIterator = monthIterator.add(1, 'month'); } - if (startMonth.month() === endMonth.month() || startMonth.month() === currentMonth) { + if (startMonth.isSame(endMonth, 'month') || isCurrentMonth(startMonth.toDate())) { result.splice(0, 0, ''); } @@ -55,6 +55,6 @@ export const getDataUntilCurrentMonth = (monthlyData: ILicenseData[]) => { return monthlyData.filter(data => dayjs(data.startDate).isSameOrBefore(dayjs(Date.now()), 'month')); }; -export const isCurrentMonthAndYear = (date: Date | string) => { - return dayjs(date).isSame(dayjs(Date.now()), 'month') && dayjs(date).isSame(dayjs(Date.now()), 'year'); +export const isCurrentMonth = (date: Date | string) => { + return dayjs(date).isSame(dayjs(Date.now()), 'month'); }; From 664410821cde64b972c1daa41b9cb5b9115bd24a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 23 Sep 2024 16:04:53 +0300 Subject: [PATCH 036/125] RED-9822: DocuMine translations --- apps/red-ui/src/assets/i18n/scm/de.json | 2 +- apps/red-ui/src/assets/i18n/scm/en.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index cf1f3bb46..9c5487add 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -1653,7 +1653,7 @@ }, "app-name": { "label": "Name der Applikation", - "placeholder": "RedactManager" + "placeholder": "DocuMine" }, "form": { "auth": "Authentifizierung aktivieren", diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index 66f48bef9..b5c317bd4 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -1653,7 +1653,7 @@ }, "app-name": { "label": "Display name", - "placeholder": "RedactManager" + "placeholder": "DocuMine" }, "form": { "auth": "Enable authentication", From 0be67a85891987823d1f1ce8109da24ec7644edd Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Mon, 23 Sep 2024 17:23:15 +0300 Subject: [PATCH 037/125] RED-7345 - added bulk local remove logic for "remove redaction" dialog --- .../manual-annotation-dialog.component.ts | 4 +- .../remove-redaction-dialog.component.ts | 13 ------ .../services/annotation-actions.service.ts | 42 +++++++++++++++---- .../services/manual-redaction.service.ts | 17 ++++---- .../file-preview/utils/dialog-options.ts | 1 - .../redaction-log/remove-redaction.request.ts | 13 ++++++ 6 files changed, 61 insertions(+), 29 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts index 970bd01d9..c4630f766 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts @@ -32,6 +32,8 @@ export interface LegalBasisOption { description?: string; } +export const NON_READABLE_CONTENT = 'non-readable content'; + @Component({ templateUrl: './manual-annotation-dialog.component.html', styleUrls: ['./manual-annotation-dialog.component.scss'], @@ -196,7 +198,7 @@ export class ManualAnnotationDialogComponent extends BaseDialogComponent impleme ? [this.isFalsePositiveRequest ? 'false_positive' : null, Validators.required] : [this.manualRedactionTypeExists ? SuperTypes.ManualRedaction : null, Validators.required], comment: [null], - classification: ['non-readable content'], + classification: [NON_READABLE_CONTENT], multiplePages: '', }); } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts index 547c4f9ca..8b6812666 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts @@ -134,19 +134,6 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< super(); } - get helpButtonKey() { - if (this.hint) { - return DialogHelpModeKeys.HINT_REMOVE; - } - if (this.recommendation) { - return DialogHelpModeKeys.RECOMMENDATION_REMOVE; - } - if (this.skipped) { - return DialogHelpModeKeys.SKIPPED_REMOVE; - } - return DialogHelpModeKeys.REDACTION_REMOVE; - } - get hasFalsePositiveOption() { return !!this.options.find(option => option.value === RemoveRedactionOptions.FALSE_POSITIVE); } diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts index 366b809f6..4fd55bba0 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts @@ -8,9 +8,11 @@ import { Core } from '@pdftron/webviewer'; import { DictionaryEntryTypes, EarmarkOperation, + type IBulkLocalRemoveRequest, ILegalBasisChangeRequest, IRecategorizationRequest, IRectangle, + type IRemoveRedactionRequest, IResizeRequest, } from '@red/domain'; import { CommentsApiService } from '@services/comments-api.service'; @@ -45,6 +47,7 @@ import { FilePreviewDialogService } from './file-preview-dialog.service'; import { FilePreviewStateService } from './file-preview-state.service'; import { ManualRedactionService } from './manual-redaction.service'; import { SkippedService } from './skipped.service'; +import { NON_READABLE_CONTENT } from '../dialogs/manual-redaction-dialog/manual-annotation-dialog.component'; @Injectable() export class AnnotationActionsService { @@ -456,13 +459,7 @@ export class AnnotationActionsService { #removeRedaction(redactions: AnnotationWrapper[], dialogResult: RemoveRedactionResult) { const removeFromDictionary = dialogResult.option.value === RemoveRedactionOptions.IN_DOSSIER; const includeUnprocessed = redactions.every(redaction => this.#includeUnprocessed(redaction, true)); - const body = redactions.map(redaction => ({ - annotationId: redaction.id, - value: redaction.value, - comment: dialogResult.comment, - removeFromDictionary, - removeFromAllDossiers: !!dialogResult.option.extraOption?.checked || !!dialogResult.applyToAllDossiers, - })); + const body = this.#getRemoveRedactionBody(redactions, dialogResult); // todo: might not be correct, probably shouldn't get to this point if they are not all the same const isHint = redactions.every(r => r.isHint); const { dossierId, fileId } = this._state; @@ -545,4 +542,35 @@ export class AnnotationActionsService { } return false; } + + #getRemoveRedactionBody( + redactions: AnnotationWrapper[], + dialogResult: RemoveRedactionResult, + ): List | IBulkLocalRemoveRequest { + if (dialogResult.bulkLocal) { + const redaction = redactions[0]; + if (redaction.value === NON_READABLE_CONTENT) { + return { + value: redaction.value, + rectangle: true, + position: redaction.entry.positions[0], + originTypes: [redaction.entry.type], + pageNumbers: [redaction.pageNumber], + }; + } + + return { + value: redaction.value, + rectangle: false, + }; + } + + return redactions.map(redaction => ({ + annotationId: redaction.id, + value: redaction.value, + comment: dialogResult.comment, + removeFromDictionary: dialogResult.option.value === RemoveRedactionOptions.IN_DOSSIER, + removeFromAllDossiers: !!dialogResult.option.extraOption?.checked || !!dialogResult.applyToAllDossiers, + })); + } } diff --git a/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts b/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts index 6186a2b12..36504f8db 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts @@ -8,6 +8,7 @@ import { type ManualRedactionEntryType } from '@models/file/manual-redaction-ent import type { DictionaryActions, IAddRedactionRequest, + IBulkLocalRemoveRequest, ILegalBasisChangeRequest, IManualAddResponse, IRecategorizationRequest, @@ -109,7 +110,7 @@ export class ManualRedactionService extends GenericService { } removeRedaction( - body: List, + body: List | IBulkLocalRemoveRequest, dossierId: string, fileId: string, removeFromDictionary = false, @@ -151,13 +152,15 @@ export class ManualRedactionService extends GenericService { return super.delete(annotationIds, url).pipe(this.#log('Undo', annotationIds)); } - remove(body: List, dossierId: string, fileId: string, includeUnprocessed = false, bulkLocal = false) { + remove( + body: List | IBulkLocalRemoveRequest, + dossierId: string, + fileId: string, + includeUnprocessed = false, + bulkLocal = false, + ) { const bulkPath = bulkLocal ? this.#bulkLocal : this.#bulkRedaction; - const newBody = { - value: body[0].value, - rectangle: false, - }; - return this._post(newBody, `${bulkPath}/remove/${dossierId}/${fileId}?includeUnprocessed=${includeUnprocessed}`).pipe( + return this._post(body, `${bulkPath}/remove/${dossierId}/${fileId}?includeUnprocessed=${includeUnprocessed}`).pipe( this.#log('Remove', body), ); } diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts index 217c4e891..35dd23be6 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts @@ -151,7 +151,6 @@ export const getRemoveRedactionOptions = ( applyToAllDossiers: boolean, isDocumine: boolean = false, ): DetailsRadioOption[] => { - console.log('TEST'); const translations = isDocumine ? removeAnnotationTranslations : removeRedactionTranslations; const { permissions, redactions, isApprover, falsePositiveContext } = data; const isBulk = redactions.length > 1; diff --git a/libs/red-domain/src/lib/redaction-log/remove-redaction.request.ts b/libs/red-domain/src/lib/redaction-log/remove-redaction.request.ts index 1967a85cb..364198733 100644 --- a/libs/red-domain/src/lib/redaction-log/remove-redaction.request.ts +++ b/libs/red-domain/src/lib/redaction-log/remove-redaction.request.ts @@ -1,6 +1,19 @@ +import { IEntityLogEntryPosition } from './entity-log-entry'; + export interface IRemoveRedactionRequest { annotationId?: string; comment?: string; removeFromDictionary?: boolean; + removeFromAllDossiers?: boolean; value?: string; } + +export interface IBulkLocalRemoveRequest { + rectangle: boolean; + value: string; + caseSensitive?: boolean; + position?: IEntityLogEntryPosition; + originTypes?: string[]; + originLegalBases?: string[]; + pageNumbers?: number[]; +} From b91893366532c659d62cfcba1b57ec16f0154bd8 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Tue, 24 Sep 2024 09:47:07 +0300 Subject: [PATCH 038/125] RED-7345 - Add/Remove bulk-local text redaction option in dialogs --- .../redact-text-dialog/redact-text-dialog.component.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.scss b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.scss index 64afce14d..0fc65b1a1 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.scss @@ -1,5 +1,5 @@ .dialog-content { - height: 530px; + height: 540px; overflow-y: auto; } From 004025636cc1c6b6b547c29217a92819e47378dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominique=20Eifl=C3=A4nder?= Date: Tue, 24 Sep 2024 10:51:59 +0200 Subject: [PATCH 039/125] RED-10011: Show stmp configuration only if license feature configurableSMTPServer is set to true --- .../general-config-screen.component.html | 11 ++++++++--- .../general-config/general-config-screen.component.ts | 6 ++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/screens/general-config/general-config-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/general-config/general-config-screen.component.html index d7d1b7230..09565c8ee 100644 --- a/apps/red-ui/src/app/modules/admin/screens/general-config/general-config-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/general-config/general-config-screen.component.html @@ -11,7 +11,12 @@
-
- -
+ + @if (smtpLicenseFeatureEnabled) { +
+ +
+ } @else { + + }
diff --git a/apps/red-ui/src/app/modules/admin/screens/general-config/general-config-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/general-config/general-config-screen.component.ts index 6d0470579..e12195ba4 100644 --- a/apps/red-ui/src/app/modules/admin/screens/general-config/general-config-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/general-config/general-config-screen.component.ts @@ -6,6 +6,8 @@ import { BaseFormComponent, IqserListingModule } from '@iqser/common-ui'; import { SystemPreferencesFormComponent } from './system-preferences-form/system-preferences-form.component'; import { RouterHistoryService } from '@services/router-history.service'; import { TranslateModule } from '@ngx-translate/core'; +import { LicenseService } from '@services/license.service'; +import { ILicenseFeature } from '@red/domain'; @Component({ selector: 'redaction-general-config-screen', @@ -17,11 +19,13 @@ import { TranslateModule } from '@ngx-translate/core'; export class GeneralConfigScreenComponent extends BaseFormComponent implements AfterViewInit { readonly currentUser = inject(UserService).currentUser; readonly routerHistoryService = inject(RouterHistoryService); + readonly licenseService = inject(LicenseService); @ViewChild(GeneralConfigFormComponent) generalConfigFormComponent: GeneralConfigFormComponent; @ViewChild(SystemPreferencesFormComponent) systemPreferencesFormComponent: SystemPreferencesFormComponent; @ViewChild(SmtpFormComponent) smtpFormComponent: SmtpFormComponent; children: BaseFormComponent[]; + smtpLicenseFeatureEnabled: boolean; get changed(): boolean { for (const child of this.children) { @@ -43,6 +47,8 @@ export class GeneralConfigScreenComponent extends BaseFormComponent implements A ngAfterViewInit() { this.children = [this.generalConfigFormComponent, this.systemPreferencesFormComponent, this.smtpFormComponent]; + let licenseFeature: ILicenseFeature = this.licenseService.getFeature('configurableSMTPServer'); + this.smtpLicenseFeatureEnabled = licenseFeature != null && licenseFeature.value === true; } async save(): Promise { From 81669177cdae87d58300c007a43677ea375eb4aa Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Wed, 25 Sep 2024 13:54:26 +0300 Subject: [PATCH 040/125] RED-9578: fixed issues and rewrote the annotations table component. --- .../selected-annotations-table.component.html | 29 +++---- .../selected-annotations-table.component.scss | 75 +++++-------------- .../selected-annotations-table.component.ts | 36 +++++++-- .../edit-redaction-dialog.component.html | 2 +- .../force-annotation-dialog.component.html | 2 +- ...edact-recommendation-dialog.component.html | 2 +- .../remove-redaction-dialog.component.html | 2 +- .../remove-redaction-dialog.component.ts | 5 +- .../approve-warning-details.component.scss | 7 +- .../warning-details-panel.component.html | 6 +- .../warning-details-panel.component.ts | 11 ++- libs/common-ui | 2 +- 12 files changed, 83 insertions(+), 96 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.html b/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.html index a47798615..86c807318 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.html +++ b/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.html @@ -1,19 +1,12 @@ -
+
+
{{ cell.label }}
- - - - - - - - - - -
- -
+
+ @for (column of _columns(); track column.label) { +
{{ column.label }}
+ } + @for (row of _data(); track $index) { + @for (cell of row; track cell.label) { +
{{ cell.label }} -
+
+ } + } +
diff --git a/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.scss b/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.scss index ebcb45852..e3e006557 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.scss @@ -1,74 +1,39 @@ @use 'common-mixins'; -table { +.table { padding: 0 13px; - max-width: 100%; - min-width: 100%; - border-spacing: 0; + display: grid; + overflow-x: hidden; + overflow-y: auto; + @include common-mixins.scroll-bar; - tbody { - padding-top: 2px; - overflow-y: auto; - display: block; - @include common-mixins.scroll-bar; + .col { + position: sticky; + top: 0; + z-index: 1; + background: white; } - tr { - max-width: 100%; - min-width: 100%; - display: table; + .cell { + text-align: start; + white-space: nowrap; + text-overflow: ellipsis; + list-style-position: inside; + overflow: hidden; - th { - label { - opacity: 0.7; - font-weight: normal; - } - } - - th, - td { - &:first-child:not(.w-50) { - width: 25%; - } - max-width: 0; - text-align: start; - - white-space: nowrap; - text-overflow: ellipsis; - list-style-position: inside; - overflow: hidden; - - padding-right: 8px; - } - - th:last-child, - td:last-child { - max-width: 0; - width: 50%; - padding-right: 0; - } + padding-right: 8px; + line-height: 1.5; } } -tbody tr:nth-child(odd) { - td { - background-color: var(--iqser-alt-background); - } +.background { + background-color: var(--iqser-alt-background); } .hide { visibility: hidden; } -.w-50 { - max-width: 0; - min-width: 50%; - - &.hide { - display: none; - } -} - .bold { font-weight: bold; } diff --git a/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.ts b/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.ts index bc8018123..dd2f567b3 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.ts @@ -5,9 +5,10 @@ export interface ValueColumn { label: string; hide?: boolean; bold?: boolean; + width?: string; } -const TABLE_ROW_SIZE = 18; +const TABLE_ROW_SIZE = 20; const MAX_ITEMS_DISPLAY = 10; @Component({ @@ -18,12 +19,33 @@ const MAX_ITEMS_DISPLAY = 10; styleUrl: './selected-annotations-table.component.scss', }) export class SelectedAnnotationsTableComponent { - readonly columns = input.required(); - readonly data = input.required(); - readonly staticColumns = input(false); + readonly defaultColumnWidth = input(false); - readonly redactedTextsAreaHeight = computed(() => - this.data().length <= MAX_ITEMS_DISPLAY ? TABLE_ROW_SIZE * this.data().length : TABLE_ROW_SIZE * MAX_ITEMS_DISPLAY, + readonly columns = input.required(); + readonly _columns = computed(() => this.columns().filter(item => !this.defaultColumnWidth() || !item.hide)); + + readonly data = input.required(); + readonly _data = computed(() => this.data().map(item => item.filter(cell => !this.defaultColumnWidth() || !cell.hide))); + + readonly redactedTextsAreaHeight = computed( + () => + (this._data().length <= MAX_ITEMS_DISPLAY ? TABLE_ROW_SIZE * this._data().length : TABLE_ROW_SIZE * MAX_ITEMS_DISPLAY) + + TABLE_ROW_SIZE, ); - readonly shouldApplyHalfWidth = computed(() => this.columns().filter(column => !column.hide).length === 2); + + readonly gridConfig = computed(() => ({ + height: `${this.redactedTextsAreaHeight()}px`, + 'grid-template-columns': !this.defaultColumnWidth() ? this.#computeCustomColumnWidths() : this.#getDefaultColumnWidth(), + 'grid-template-rows': `repeat(${this._data().length + 1}, ${TABLE_ROW_SIZE}px)`, + })); + + #computeCustomColumnWidths() { + return this._columns() + .map(column => column.width ?? `auto`) + .join(' '); + } + + #getDefaultColumnWidth() { + return `repeat(${this._columns().length}, 1fr)`; + } } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html index 58636d2b0..00afb75cc 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html @@ -11,7 +11,7 @@
diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.html index 9a34be925..cdf6b9936 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.html +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.html @@ -7,7 +7,7 @@ } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.html index 7acc288cc..5c7d34dd2 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.html +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.html @@ -7,7 +7,7 @@
diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.html index 57a5a3655..67b718ed6 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.html +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.html @@ -10,7 +10,7 @@
diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts index 8b6812666..972fd64ba 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts @@ -111,11 +111,12 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< readonly selectedOption = toSignal(this.form.get('option').valueChanges.pipe(map(value => value.value))); readonly isFalsePositive = computed(() => this.selectedOption() === RemoveRedactionOptions.FALSE_POSITIVE); readonly tableColumns = computed(() => [ - { label: 'Value' }, - { label: 'Type' }, + { label: 'Value', width: '25%' }, + { label: 'Type', width: '25%' }, { label: 'Context', hide: !this.isFalsePositive(), + width: '50%', }, ]); diff --git a/apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.scss b/apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.scss index 668a18134..7b5d3cd12 100644 --- a/apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.scss +++ b/apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.scss @@ -1,8 +1,13 @@ @use 'common-mixins'; +:host { + height: 250px; +} + .scrollable { + margin-bottom: 8px; overflow-y: auto; - max-height: calc(5 * 50px); + max-height: 240px; @include common-mixins.scroll-bar; padding-left: 2px; diff --git a/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.html b/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.html index bae0d9986..47b99ddf9 100644 --- a/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.html +++ b/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.html @@ -1,8 +1,4 @@ {{ filename() }} - + diff --git a/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.ts b/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.ts index 9726e2900..42e8e1a68 100644 --- a/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.ts @@ -16,7 +16,6 @@ import { TranslateService } from '@ngx-translate/core'; styleUrl: './warning-details-panel.component.scss', }) export class WarningDetailsPanelComponent { - readonly #translateService = inject(TranslateService); readonly warnings = input(); readonly filename = input(); readonly openByDefault = input(); @@ -24,14 +23,20 @@ export class WarningDetailsPanelComponent { { label: 'Value' }, { label: 'Type' }, { label: 'Page' }, - { label: 'Warning Reason' }, + { + label: 'Warning Reason', + width: '40%', + }, ]); + readonly #translateService = inject(TranslateService); readonly tableData = computed(() => this.warnings().map(warning => [ { label: warning.value, bold: true }, { label: warning.type }, { label: warning.pages.join(',') }, - { label: this.#translateService.instant(approvalWarningReasonTranslations[warning.warningType]) }, + { + label: this.#translateService.instant(approvalWarningReasonTranslations[warning.warningType]), + }, ]), ); } diff --git a/libs/common-ui b/libs/common-ui index c71a4995a..835cb7820 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit c71a4995a63e4886bc23a8a8cea7d02d7560c2aa +Subproject commit 835cb7820e2100ff1125939f4c2766f06e9c09a6 From 750312c59ed9e2df7096e2688803896ac4661c03 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Wed, 25 Sep 2024 14:54:14 +0300 Subject: [PATCH 041/125] RED-9486: fixed naming of images in remove dialog. --- .../file-preview/utils/dialog-options.ts | 12 +++++++++++- apps/red-ui/src/assets/i18n/redact/en.json | 18 +++++++++--------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts index 35dd23be6..00cbf3ce6 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts @@ -163,6 +163,7 @@ export const getRemoveRedactionOptions = ( descriptionParams: { value: redactions[0].value, type: redactions[0].HINT ? 'hint' : redactions[0].typeLabel, + isImage: redactions[0].isImage ? 'image' : redactions[0].typeLabel, }, icon: PIN_ICON, value: RemoveRedactionOptions.ONLY_HERE, @@ -171,6 +172,9 @@ export const getRemoveRedactionOptions = ( options.push({ label: removeRedactionTranslations.IN_DOCUMENT.label, description: removeRedactionTranslations.IN_DOCUMENT.description, + descriptionParams: { + isImage: redactions[0].isImage ? 'image' : redactions[0].typeLabel, + }, icon: DOCUMENT_ICON, value: RemoveRedactionOptions.IN_DOCUMENT, }); @@ -179,7 +183,11 @@ export const getRemoveRedactionOptions = ( options.push({ label: isBulk ? translations.IN_DOSSIER.labelBulk : translations.IN_DOSSIER.label, description: isBulk ? translations.IN_DOSSIER.descriptionBulk : translations.IN_DOSSIER.description, - descriptionParams: { value: redactions[0].value, type: redactions[0].HINT ? 'hint' : redactions[0].typeLabel }, + descriptionParams: { + value: redactions[0].value, + type: redactions[0].HINT ? 'hint' : redactions[0].typeLabel, + isImage: redactions[0].isImage ? 'image' : redactions[0].typeLabel, + }, icon: FOLDER_ICON, value: RemoveRedactionOptions.IN_DOSSIER, extraOption: !isDocumine @@ -200,6 +208,7 @@ export const getRemoveRedactionOptions = ( value: redactions[0].value, type: redactions[0].typeLabel, context: falsePositiveContext[0], + isImage: redactions[0].isImage ? 'image' : redactions[0].typeLabel, }, icon: FOLDER_ICON, value: RemoveRedactionOptions.DO_NOT_RECOMMEND, @@ -219,6 +228,7 @@ export const getRemoveRedactionOptions = ( value: redactions[0].value, type: redactions[0].typeLabel, context: falsePositiveContext[0], + isImage: redactions[0].isImage ? 'image' : redactions[0].typeLabel, }, icon: REMOVE_FROM_DICT_ICON, value: RemoveRedactionOptions.FALSE_POSITIVE, diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index cd5b0a83b..c8c292c19 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -2149,32 +2149,32 @@ "comment-placeholder": "Add remarks or notes...", "options": { "do-not-recommend": { - "description": "Do not recommend the selected term in any document of this dossier.", - "description-bulk": "Do not recommend the selected terms in any document of this dossier.", + "description": "Do not recommend the selected {isImage, select, image{image} other{term}} in any document of this dossier.", + "description-bulk": "Do not recommend the selected {isImage, select, image{images} other{terms}} in any document of this dossier.", "extraOptionLabel": "Apply to all active and future dossiers", "label": "Remove from dossier" }, "false-positive": { - "description": "Mark this redaction as a false-positive. The term will not be redacted in this dossier if it occurs in the same context.", - "description-bulk": "Mark these redactions as false-positives. The terms will not be redacted in this dossier if they occur in the same context.", + "description": "Mark this redaction as a false-positive. The {isImage, select, image{image} other{term}} will not be redacted in this dossier if it occurs in the same context.", + "description-bulk": "Mark these redactions as false-positives. The {isImage, select, image{images} other{terms}} will not be redacted in this dossier if they occur in the same context.", "extraOptionDescription": "Dossier template access is required to reverse this action. As a regular user you can only reverse it for this dossier.", "extraOptionLabel": "Apply to all active and future dossiers", "label": "Remove from dossier in this context" }, "in-document": { - "description": "Do not auto-redact the selected term in any pages of this document.", + "description": "Do not auto-redact the selected {isImage, select, image{image} other{term}} in any pages of this document.", "label": "Remove from document" }, "in-dossier": { - "description": "Do not {type, select, hint{annotate} other{auto-redact}} the selected term in any document of this dossier.", - "description-bulk": "Do not {type, select, hint{annotate} other{auto-redact}} the selected terms in this dossier.", + "description": "Do not {type, select, hint{annotate} other{auto-redact}} the selected {isImage, select, image{image} other{term}} in any document of this dossier.", + "description-bulk": "Do not {type, select, hint{annotate} other{auto-redact}} the selected {isImage, select, image{images} other{terms}} in this dossier.", "extraOptionLabel": "Apply to all active and future dossiers", "label": "Remove from dossier", "label-bulk": "Remove from dossier" }, "only-here": { - "description": "Do not {type, select, hint{annotate} other{redact}} the term at this position in the current document.", - "description-bulk": "Do not {type, select, hint{annotate} other{redact}} the selected terms at this position in the current document.", + "description": "Do not {type, select, hint{annotate} other{redact}} the {isImage, select, image{image} other{term}} at this position in the current document.", + "description-bulk": "Do not {type, select, hint{annotate} other{redact}} the selected {isImage, select, image{images} other{terms}} at this position in the current document.", "label": "Remove here" } } From e30a54297afbe95c91fd24ac8be72789ec17c06e Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Wed, 25 Sep 2024 16:14:00 +0300 Subject: [PATCH 042/125] RED-7345 - added translation for value --- .../dialogs/add-hint-dialog/add-hint-dialog.component.html | 2 +- .../redact-text-dialog/redact-text-dialog.component.html | 4 ++-- apps/red-ui/src/assets/i18n/redact/de.json | 6 ++++-- apps/red-ui/src/assets/i18n/redact/en.json | 6 ++++-- apps/red-ui/src/assets/i18n/scm/de.json | 6 ++++-- apps/red-ui/src/assets/i18n/scm/en.json | 6 ++++-- 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/add-hint-dialog/add-hint-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/add-hint-dialog/add-hint-dialog.component.html index 62cb27b02..1b8ba9d00 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/add-hint-dialog/add-hint-dialog.component.html +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/add-hint-dialog/add-hint-dialog.component.html @@ -9,7 +9,7 @@ [ngClass]="isEditingSelectedText ? 'flex relative' : 'flex-align-items-center'" >
- +
- +
- -
- - {{ 'manual-annotation.dialog.content.apply-on-multiple-pages' | translate }} - - -
- - - {{ 'manual-annotation.dialog.content.apply-on-multiple-pages-hint' | translate }} -
-
diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts index c4630f766..4755981ef 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts @@ -1,4 +1,4 @@ -import { Component, Inject, OnInit } from '@angular/core'; +import { Component, Inject, OnChanges, OnInit, SimpleChanges } from '@angular/core'; import { ReactiveFormsModule, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; @@ -25,6 +25,12 @@ import { MatFormField } from '@angular/material/form-field'; import { MatOption, MatSelect, MatSelectTrigger } from '@angular/material/select'; import { MatTooltip } from '@angular/material/tooltip'; import { MatCheckbox } from '@angular/material/checkbox'; +import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option'; +import { RectangleRedactOption, RectangleRedactOptions, RedactOrHintOption } from '../../utils/dialog-types'; +import { getRectangleRedactOptions } from '../../utils/dialog-options'; +import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component'; +import { SystemDefaults } from '../../../account/utils/dialog-defaults'; +import { validatePageRange } from '../../utils/form-validators'; export interface LegalBasisOption { label?: string; @@ -53,19 +59,21 @@ export const NON_READABLE_CONTENT = 'non-readable content'; IqserDenyDirective, MatCheckbox, IconButtonComponent, + DetailsRadioComponent, ], providers: [ManualRedactionService], }) export class ManualAnnotationDialogComponent extends BaseDialogComponent implements OnInit { readonly #dossier: Dossier; - readonly roles = Roles; - isDictionaryRequest: boolean; - isFalsePositiveRequest: boolean; - isEditingSelectedText = false; - applyOnMultiplePages = false; - manualRedactionTypeExists = true; - possibleDictionaries: Dictionary[] = []; - legalOptions: LegalBasisOption[] = []; + protected readonly roles = Roles; + protected readonly options: DetailsRadioOption[]; + protected isDictionaryRequest: boolean; + protected isFalsePositiveRequest: boolean; + protected isEditingSelectedText = false; + protected applyOnMultiplePages = false; + protected manualRedactionTypeExists = true; + protected possibleDictionaries: Dictionary[] = []; + protected legalOptions: LegalBasisOption[] = []; constructor( readonly iqserPermissionsService: IqserPermissionsService, @@ -85,10 +93,20 @@ export class ManualAnnotationDialogComponent extends BaseDialogComponent impleme this.manualRedactionTypeExists = this._dictionaryService.hasManualType(this.#dossier.dossierTemplateId); + this.options = getRectangleRedactOptions(); + this.form = this.#getForm(); this.initialFormValue = this.form.getRawValue(); } + extraOptionChanged(option: DetailsRadioOption): void { + if (option.value === RectangleRedactOptions.MULTIPLE_PAGES) { + setTimeout(() => { + this.form.get('option')?.updateValueAndValidity(); + }, 0); + } + } + get title() { return this._manualRedactionService.getTitle(this.data.manualRedactionEntryWrapper.type); } @@ -200,6 +218,7 @@ export class ManualAnnotationDialogComponent extends BaseDialogComponent impleme comment: [null], classification: [NON_READABLE_CONTENT], multiplePages: '', + option: [this.#getOption(SystemDefaults.RECTANGLE_REDACT_DEFAULT), validatePageRange()], }); } @@ -229,6 +248,10 @@ export class ManualAnnotationDialogComponent extends BaseDialogComponent impleme : this.form.get('selectedText').value; } + #getOption(option: RectangleRedactOption): DetailsRadioOption { + return this.options.find(o => o.value === option); + } + #selectReason() { if (this.legalOptions.length === 1) { this.form.get('reason').setValue(this.legalOptions[0]); diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts index 85a109583..163b8363c 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts @@ -128,7 +128,7 @@ export class RedactRecommendationDialogComponent } extraOptionChanged(option: DetailsRadioOption): void { - this.#applyToAllDossiers = option.extraOption.checked; + this.#applyToAllDossiers = option.additionalCheck.checked; this.#setDictionaries(); if (this.#applyToAllDossiers && this.form.controls.dictionary.value) { @@ -144,7 +144,7 @@ export class RedactRecommendationDialogComponent if (!this.#applyToAllDossiers) { const selectedDictionaryType = this.form.controls.dictionary.value; const selectedDictionary = this.dictionaries.find(d => d.type === selectedDictionaryType); - this.options[0].extraOption.disabled = selectedDictionary.dossierDictionaryOnly; + this.options[0].additionalCheck.disabled = selectedDictionary.dossierDictionaryOnly; } } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts index 63332bb0a..6a9d46536 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts @@ -150,7 +150,7 @@ export class RedactTextDialogComponent } extraOptionChanged(option: DetailsRadioOption): void { - this.#applyToAllDossiers = option.extraOption.checked; + this.#applyToAllDossiers = option.additionalCheck.checked; this.#setDictionaries(); if (this.#applyToAllDossiers && this.form.controls.dictionary.value) { @@ -166,7 +166,7 @@ export class RedactTextDialogComponent if (!this.#applyToAllDossiers) { const selectedDictionaryType = this.form.controls.dictionary.value; const selectedDictionary = this.dictionaries.find(d => d.type === selectedDictionaryType); - this.options[2].extraOption.disabled = selectedDictionary.dossierDictionaryOnly; + this.options[2].additionalCheck.disabled = selectedDictionary.dossierDictionaryOnly; } } @@ -230,7 +230,7 @@ export class RedactTextDialogComponent #resetValues() { this.#applyToAllDossiers = this.applyToAll; - this.options[2].extraOption.checked = this.#applyToAllDossiers; + this.options[2].additionalCheck.checked = this.#applyToAllDossiers; if (this.dictionaryRequest) { this.form.controls.reason.setValue(null); this.form.controls.dictionary.setValue(null); diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/resize-redaction-dialog/resize-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/resize-redaction-dialog/resize-redaction-dialog.component.ts index c51877fb3..a5b174c13 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/resize-redaction-dialog/resize-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/resize-redaction-dialog/resize-redaction-dialog.component.ts @@ -82,7 +82,7 @@ export class ResizeRedactionDialogComponent extends IqserDialogComponent< super.close({ comment: formValue.comment, updateDictionary, - addToAllDossiers: !!formValue.option?.extraOption?.checked, + addToAllDossiers: !!formValue.option?.additionalCheck?.checked, }); } diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts index 9bdb9b7db..05b6ae67f 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts @@ -435,7 +435,7 @@ export class AnnotationActionsService { type: redaction.type, positions: redaction.positions, addToDictionary: true, - addToAllDossiers: !!dialogResult.option.extraOption?.checked || !!dialogResult.applyToAllDossiers, + addToAllDossiers: !!dialogResult.option.additionalCheck?.checked || !!dialogResult.applyToAllDossiers, reason: 'False Positive', dictionaryEntryType: redaction.isRecommendation ? DictionaryEntryTypes.FALSE_RECOMMENDATION @@ -561,7 +561,7 @@ export class AnnotationActionsService { value: redaction.value, comment: dialogResult.comment, removeFromDictionary: dialogResult.option.value === RemoveRedactionOptions.IN_DOSSIER, - removeFromAllDossiers: !!dialogResult.option.extraOption?.checked || !!dialogResult.applyToAllDossiers, + removeFromAllDossiers: !!dialogResult.option.additionalCheck?.checked || !!dialogResult.applyToAllDossiers, })); } } diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts index 00cbf3ce6..74e0a7720 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts @@ -8,6 +8,8 @@ import { removeRedactionTranslations } from '@translations/remove-redaction-tran import { resizeRedactionTranslations } from '@translations/resize-redaction-translations'; import { ForceAnnotationOption, + RectangleRedactOption, + RectangleRedactOptions, RedactOrHintOption, RedactOrHintOptions, RemoveRedactionData, @@ -16,6 +18,7 @@ import { ResizeOptions, ResizeRedactionOption, } from './dialog-types'; +import { rectangleRedactTranslations } from '@translations/rectangle-redact-translations'; const PIN_ICON = 'red:push-pin'; const DOCUMENT_ICON = 'iqser:document'; @@ -43,7 +46,7 @@ export const getEditRedactionOptions = ( descriptionParams: { dossierName: dossierName }, icon: FOLDER_ICON, value: ResizeOptions.IN_DOSSIER, - extraOption: { + additionalCheck: { label: editRedactionTranslations.inDossier.extraOptionLabel, checked: applyToAllDossiers, hidden: dossierDictionaryOnly, @@ -95,7 +98,7 @@ export const getRedactOrHintOptions = ( icon: FOLDER_ICON, value: ResizeOptions.IN_DOSSIER, disabled: isPageExcluded, - extraOption: { + additionalCheck: { label: translations.inDossier.extraOptionLabel, checked: applyToAllDossiers, hidden: !isApprover, @@ -105,6 +108,29 @@ export const getRedactOrHintOptions = ( return options; }; +export const getRectangleRedactOptions = (): DetailsRadioOption[] => { + return [ + { + label: rectangleRedactTranslations.onlyThisPage.label, + description: rectangleRedactTranslations.onlyThisPage.description, + icon: PIN_ICON, + value: RectangleRedactOptions.ONLY_THIS_PAGE, + }, + { + label: rectangleRedactTranslations.multiplePages.label, + description: rectangleRedactTranslations.multiplePages.description, + icon: DOCUMENT_ICON, + value: RectangleRedactOptions.MULTIPLE_PAGES, + additionalInput: { + label: rectangleRedactTranslations.multiplePages.extraOptionLabel, + description: rectangleRedactTranslations.multiplePages.extraOptionDescription, + placeholder: rectangleRedactTranslations.multiplePages.extraOptionPlaceholder, + value: '', + }, + }, + ]; +}; + export const getResizeRedactionOptions = ( redaction: AnnotationWrapper, dossier: Dossier, @@ -136,7 +162,7 @@ export const getResizeRedactionOptions = ( tooltip: !dictBasedType ? translations.inDossier.tooltip : null, icon: FOLDER_ICON, value: RedactOrHintOptions.IN_DOSSIER, - extraOption: { + additionalCheck: { label: translations.inDossier.extraOptionLabel, checked: applyToAllDossiers, hidden: !isApprover, @@ -190,7 +216,7 @@ export const getRemoveRedactionOptions = ( }, icon: FOLDER_ICON, value: RemoveRedactionOptions.IN_DOSSIER, - extraOption: !isDocumine + additionalCheck: !isDocumine ? { label: translations.IN_DOSSIER.extraOptionLabel, checked: applyToAllDossiers, @@ -212,7 +238,7 @@ export const getRemoveRedactionOptions = ( }, icon: FOLDER_ICON, value: RemoveRedactionOptions.DO_NOT_RECOMMEND, - extraOption: !isDocumine + additionalCheck: !isDocumine ? { label: translations.DO_NOT_RECOMMEND.extraOptionLabel, checked: applyToAllDossiers, @@ -232,7 +258,7 @@ export const getRemoveRedactionOptions = ( }, icon: REMOVE_FROM_DICT_ICON, value: RemoveRedactionOptions.FALSE_POSITIVE, - extraOption: !isDocumine + additionalCheck: !isDocumine ? { label: translations.FALSE_POSITIVE.extraOptionLabel, checked: applyToAllDossiers, diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts index d7efb27eb..284469ae9 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts @@ -11,6 +11,13 @@ export const RedactOrHintOptions = { export type RedactOrHintOption = keyof typeof RedactOrHintOptions; +export const RectangleRedactOptions = { + ONLY_THIS_PAGE: 'ONLY_THIS_PAGE', + MULTIPLE_PAGES: 'MULTIPLE_PAGES', +} as const; + +export type RectangleRedactOption = keyof typeof RectangleRedactOptions; + export const ForceAnnotationOptions = { ONLY_HERE: 'ONLY_HERE', IN_DOCUMENT: 'IN_DOCUMENT', diff --git a/apps/red-ui/src/app/modules/file-preview/utils/form-validators.ts b/apps/red-ui/src/app/modules/file-preview/utils/form-validators.ts new file mode 100644 index 000000000..233aed553 --- /dev/null +++ b/apps/red-ui/src/app/modules/file-preview/utils/form-validators.ts @@ -0,0 +1,12 @@ +import { AbstractControl, ValidatorFn } from '@angular/forms'; + +export const validatePageRange = (): ValidatorFn => { + return (control: AbstractControl): { [key: string]: any } | null => { + const option = control.value; + if (option?.additionalInput) { + const validRange = /^(\d+(-\d+)?)(,\d+(-\d+)?)*$/.test(option.additionalInput.value); + return validRange ? null : { invalidRange: true }; + } + return null; + }; +}; diff --git a/apps/red-ui/src/app/translations/rectangle-redact-translations.ts b/apps/red-ui/src/app/translations/rectangle-redact-translations.ts new file mode 100644 index 000000000..2feb6c67b --- /dev/null +++ b/apps/red-ui/src/app/translations/rectangle-redact-translations.ts @@ -0,0 +1,16 @@ +import { DialogOption } from '@translations/redact-text-translations'; +import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; + +export const rectangleRedactTranslations: Record<'onlyThisPage' | 'multiplePages', DialogOption> = { + onlyThisPage: { + label: _('manual-annotation.dialog.content.options.only-this-page.label'), + description: _('manual-annotation.dialog.content.options.only-this-page.description'), + }, + multiplePages: { + label: _('manual-annotation.dialog.content.options.multiple-pages.label'), + description: _('manual-annotation.dialog.content.options.multiple-pages.description'), + extraOptionLabel: _('manual-annotation.dialog.content.options.multiple-pages.extraOptionLabel'), + extraOptionDescription: _('manual-annotation.dialog.content.options.multiple-pages.extraOptionDescription'), + extraOptionPlaceholder: _('manual-annotation.dialog.content.options.multiple-pages.extraOptionPlaceholder'), + }, +} as const; diff --git a/apps/red-ui/src/app/translations/redact-text-translations.ts b/apps/red-ui/src/app/translations/redact-text-translations.ts index a5166ca86..2b334471b 100644 --- a/apps/red-ui/src/app/translations/redact-text-translations.ts +++ b/apps/red-ui/src/app/translations/redact-text-translations.ts @@ -7,6 +7,7 @@ export interface DialogOption { descriptionBulk?: string; extraOptionLabel?: string; extraOptionDescription?: string; + extraOptionPlaceholder?: string; } export const redactTextTranslations: Record<'onlyHere' | 'inDocument' | 'inDossier', DialogOption> = { diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index bdbaa2f35..eabffcfef 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -1878,6 +1878,19 @@ "dictionary": "Wörterbuch", "edit-selected-text": "Ausgewählten Text bearbeiten", "legalBasis": "Rechtsgrundlage", + "options": { + "multiple-pages": { + "description": "", + "extraOptionDescription": "", + "extraOptionLabel": "", + "extraOptionPlaceholder": "", + "label": "" + }, + "only-this-page": { + "description": "", + "label": "" + } + }, "reason": "Grund", "reason-placeholder": "Grund auswählen...", "rectangle": "Bereichsschwärzung", diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index 6c771c61b..ab30f44eb 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -1878,6 +1878,19 @@ "dictionary": "Dictionary", "edit-selected-text": "Edit selected text", "legalBasis": "Legal basis", + "options": { + "multiple-pages": { + "description": "Edit redaction the range of pages", + "extraOptionDescription": "Minus(-) for range and comma(,) for enumeration", + "extraOptionLabel": "Range", + "extraOptionPlaceholder": "e.g. 1-20,22,32", + "label": "Apply on multiple pages" + }, + "only-this-page": { + "description": "Edit redaction only at this position in this document", + "label": "Apply only on this page" + } + }, "reason": "Reason", "reason-placeholder": "Select a reason...", "rectangle": "Custom rectangle", diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index ef13dcc84..dd2b7ee47 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -1878,6 +1878,19 @@ "dictionary": "Wörterbuch", "edit-selected-text": "Edit selected text", "legalBasis": "Rechtsgrundlage", + "options": { + "multiple-pages": { + "description": "", + "extraOptionDescription": "", + "extraOptionLabel": "", + "extraOptionPlaceholder": "", + "label": "" + }, + "only-this-page": { + "description": "", + "label": "" + } + }, "reason": "Begründung", "reason-placeholder": "Wählen Sie eine Begründung aus ...", "rectangle": "Benutzerdefinierter Bereich", diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index 1f9e9b480..96f6e6184 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -1878,6 +1878,19 @@ "dictionary": "Dictionary", "edit-selected-text": "Edit selected text", "legalBasis": "Legal Basis", + "options": { + "multiple-pages": { + "description": "Edit redaction the range of pages", + "extraOptionDescription": "Minus(-) for range and comma(,) for enumeration", + "extraOptionLabel": "Range", + "extraOptionPlaceholder": "e.g. 1-20,22,32", + "label": "Apply on multiple pages" + }, + "only-this-page": { + "description": "Edit redaction only at this position in this document", + "label": "Apply only on this page" + } + }, "reason": "Reason", "reason-placeholder": "Select a reason ...", "rectangle": "Custom Rectangle", From ccd008666e0e137af6f3e3652970eaee24b9dfaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Fri, 27 Sep 2024 16:38:58 +0300 Subject: [PATCH 054/125] RED-10034: Removed unnecessary draw call? --- .../file-preview/file-preview-screen.component.ts | 10 +++++----- .../pdf-viewer/services/annotation-draw.service.ts | 2 +- .../services/annotation-manager.service.ts | 14 ++++---------- .../src/app/services/files/entity-log.service.ts | 8 ++------ 4 files changed, 12 insertions(+), 22 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts index 7701d687c..2e7fbdfd4 100644 --- a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts @@ -100,13 +100,13 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni readonly roles = Roles; readonly fileId = this.state.fileId; readonly dossierId = this.state.dossierId; + protected readonly isDocumine = getConfig().IS_DOCUMINE; @ViewChild('annotationFilterTemplate', { read: TemplateRef, static: false, }) private readonly _filterTemplate: TemplateRef; #loadAllAnnotationsEnabled = false; - protected readonly isDocumine = getConfig().IS_DOCUMINE; constructor( readonly pdf: PdfViewer, @@ -447,11 +447,11 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this._annotationManager.delete(annotationsToDelete); } - drawChangedAnnotations(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]) { + async drawChangedAnnotations(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]): Promise { const annotationsToDraw = this.#getAnnotationsToDraw(oldAnnotations, newAnnotations); this._logger.info('[ANNOTATIONS] To draw: ', annotationsToDraw); this._annotationManager.delete(annotationsToDraw); - return this.#cleanupAndRedrawAnnotations(annotationsToDraw); + await this.#cleanupAndRedrawAnnotations(annotationsToDraw); } async #openRedactTextDialog(manualRedactionEntryWrapper: ManualRedactionEntryWrapper) { @@ -702,7 +702,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this._errorService.set(error); } - #cleanupAndRedrawAnnotations(newAnnotations: List) { + async #cleanupAndRedrawAnnotations(newAnnotations: List): Promise { if (!newAnnotations.length) { return undefined; } @@ -716,7 +716,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni }, 100); } - return this._annotationDrawService.draw(newAnnotations, this._skippedService.hideSkipped(), this.state.dossierTemplateId); + await this._annotationDrawService.draw(newAnnotations, this._skippedService.hideSkipped(), this.state.dossierTemplateId); } #handleDeltaAnnotationFilters(currentFilters: NestedFilter[]) { diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-draw.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-draw.service.ts index b888686b6..c71ac171b 100644 --- a/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-draw.service.ts +++ b/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-draw.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { List } from '@iqser/common-ui/lib/utils'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { Core } from '@pdftron/webviewer'; -import { IRectangle, ISectionRectangle, IPoint, SuperTypes } from '@red/domain'; +import { IPoint, IRectangle, ISectionRectangle, SuperTypes } from '@red/domain'; import { DefaultColorsService } from '@services/entity-services/default-colors.service'; import { hexToRgb } from '@utils/functions'; import { BoundingBox, Table } from '../../file-preview/services/tables.service'; diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-manager.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-manager.service.ts index a2457e199..201d3560c 100644 --- a/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-manager.service.ts +++ b/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-manager.service.ts @@ -19,14 +19,14 @@ const MOVE_OPTION = 'move'; @Injectable() export class REDAnnotationManager { + resizingAnnotationId?: string = undefined; + annotationHasBeenResized?: boolean = false; readonly #hidden = signal(new Set()); + readonly hidden = this.#hidden.asReadonly(); #manager: AnnotationManager; readonly #logger = inject(NGXLogger); readonly #annotationSelected$ = new Subject<[Annotation[], string]>(); readonly annotationSelected$ = this.#annotationSelected$.asObservable(); - resizingAnnotationId?: string = undefined; - annotationHasBeenResized?: boolean = false; - readonly hidden = this.#hidden.asReadonly(); get selected() { return this.#manager.getSelectedAnnotations(); @@ -128,21 +128,15 @@ export class REDAnnotationManager { annotations.forEach(annotation => this.#manager.redrawAnnotation(annotation)); } - add(annotations: Annotation | Annotation[]) { + async add(annotations: Annotation | Annotation[]): Promise { try { annotations = asList(annotations); this.#manager.addAnnotations(annotations, { imported: true }); - return this.#manager.drawAnnotationsFromList(annotations); } catch (e) { console.log(e); } } - showHidden() { - const hidden = this.#getByIds([...this.hidden().values()]); - this.show(hidden); - } - #listenForAnnotationSelected() { this.#manager.addEventListener('annotationSelected', async (annotations: Annotation[], action: string) => { this.#logger.info('[PDF] Annotation selected: ', annotations, action); diff --git a/apps/red-ui/src/app/services/files/entity-log.service.ts b/apps/red-ui/src/app/services/files/entity-log.service.ts index dbc05ea4e..d7287d40c 100644 --- a/apps/red-ui/src/app/services/files/entity-log.service.ts +++ b/apps/red-ui/src/app/services/files/entity-log.service.ts @@ -1,6 +1,6 @@ import { inject, Injectable } from '@angular/core'; -import { GenericService, isIqserDevMode, Toaster } from '@iqser/common-ui'; -import { EntryStates, IEntityLog, IEntityLogEntry, ISectionGrid } from '@red/domain'; +import { GenericService, Toaster } from '@iqser/common-ui'; +import { EntryStates, IEntityLog, IEntityLogEntry } from '@red/domain'; import { firstValueFrom, of } from 'rxjs'; import { catchError } from 'rxjs/operators'; @@ -20,10 +20,6 @@ export class EntityLogService extends GenericService { return entityLog; } - getSectionGrid(dossierId: string, fileId: string) { - return this._getOne([dossierId, fileId], 'sectionGrid'); - } - #filterInvalidEntries(entityLogEntry: IEntityLogEntry[]) { return entityLogEntry.filter(entry => { entry.positions = entry.positions?.filter(p => !!p.rectangle?.length); From c713b9d2f47ed49b51ce3e84351c3c990b928e81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Sat, 28 Sep 2024 17:06:43 +0300 Subject: [PATCH 055/125] RED-10034: Improved UI components, reduced function calls --- .../annotation-actions.component.html | 300 +++++++++--------- .../annotation-actions.component.ts | 197 +++++------- .../annotation-wrapper.component.html | 59 ++-- .../annotation-wrapper.component.ts | 34 +- .../annotations-list.component.html | 12 +- .../annotations-list.component.ts | 41 +-- .../file-preview-screen.component.ts | 149 +++++---- .../services/annotation-references.service.ts | 2 - .../services/pdf-proxy.service.ts | 14 +- 9 files changed, 403 insertions(+), 405 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotation-actions/annotation-actions.component.html b/apps/red-ui/src/app/modules/file-preview/components/annotation-actions/annotation-actions.component.html index a6a68b376..3a79d9f8e 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/annotation-actions/annotation-actions.component.html +++ b/apps/red-ui/src/app/modules/file-preview/components/annotation-actions/annotation-actions.component.html @@ -1,161 +1,165 @@ -
- - - +@if (canPerformAnnotationActions && annotationPermissions()) { +
+ + + - - + + - - - + + + - + - + - + - + - + - + - + - + - + - + - - -
+ +
+
+} diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotation-actions/annotation-actions.component.ts b/apps/red-ui/src/app/modules/file-preview/components/annotation-actions/annotation-actions.component.ts index 3e2b3f822..ae64768f4 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/annotation-actions/annotation-actions.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/annotation-actions/annotation-actions.component.ts @@ -1,4 +1,4 @@ -import { Component, computed, Input, OnChanges } from '@angular/core'; +import { Component, computed, input, Input, untracked } from '@angular/core'; import { CircleButtonComponent, getConfig, HelpModeService, IqserAllowDirective, IqserPermissionsService } from '@iqser/common-ui'; import { AnnotationPermissions } from '@models/file/annotation.permissions'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; @@ -28,21 +28,77 @@ export type AnnotationButtonType = keyof typeof AnnotationButtonTypes; standalone: true, imports: [CircleButtonComponent, NgIf, TranslateModule, AsyncPipe, IqserAllowDirective], }) -export class AnnotationActionsComponent implements OnChanges { - #annotations: AnnotationWrapper[] = []; - readonly #isDocumine = getConfig().IS_DOCUMINE; - protected _annotationId = ''; +export class AnnotationActionsComponent { @Input() buttonType: AnnotationButtonType = AnnotationButtonTypes.default; @Input() tooltipPosition: 'before' | 'above' = 'before'; @Input() canPerformAnnotationActions: boolean; @Input() alwaysVisible: boolean; @Input() actionsHelpModeKey: string; readonly roles = Roles; - annotationPermissions: AnnotationPermissions; - isImage = true; + readonly annotations = input.required({ + transform: value => value.filter(a => a !== undefined), + }); readonly isVisible = computed(() => { const hidden = this._annotationManager.hidden(); - return this.#annotations.reduce((acc, annotation) => !hidden.has(annotation.id) && acc, true); + return this.annotations().reduce((acc, annotation) => !hidden.has(annotation.id) && acc, true); + }); + readonly somePending = computed(() => { + return this.annotations().some(a => a.pending); + }); + readonly sameType = computed(() => { + const annotations = this.annotations(); + const type = annotations[0].superType; + return annotations.every(a => a.superType === type); + }); + readonly resizing = computed(() => { + return this.annotations().length === 1 && this.annotations()[0].id === this._annotationManager.resizingAnnotationId; + }); + readonly viewerAnnotations = computed(() => { + return this._annotationManager.get(this.annotations()); + }); + readonly annotationPermissions = computed(() => + AnnotationPermissions.forUser( + this._permissionsService.isApprover(this._state.dossier()), + this.annotations(), + this._state.dictionaries, + this._iqserPermissionsService, + this._state.file().excludedFromAutomaticAnalysis, + ), + ); + readonly hideSkipped = computed(() => this.skippedService.hideSkipped() && this.annotations().some(a => a.isSkipped)); + readonly isImageHint = computed(() => this.annotations().every(a => a.IMAGE_HINT)); + readonly isImage = computed(() => this.annotations().reduce((acc, a) => acc && a.isImage, true)); + readonly canRemoveRedaction = computed( + () => this.annotationChangesAllowed() && this.annotationPermissions().canRemoveRedaction && this.sameType(), + ); + readonly canForceRedaction = computed(() => this.annotationChangesAllowed() && this.annotationPermissions().canForceRedaction); + readonly canForceHint = computed(() => this.annotationChangesAllowed() && this.annotationPermissions().canForceHint); + readonly canAcceptRecommendation = computed( + () => this.annotationChangesAllowed() && this.annotationPermissions().canAcceptRecommendation, + ); + readonly #isDocumine = getConfig().IS_DOCUMINE; + readonly annotationChangesAllowed = computed( + () => (!this.#isDocumine || !this._state.file().excludedFromAutomaticAnalysis) && !this.somePending(), + ); + readonly canResize = computed( + () => this.annotationChangesAllowed() && this.annotationPermissions().canResizeAnnotation && this.annotations().length === 1, + ); + readonly canEdit = computed(() => { + const canEditRedactions = + this.annotationPermissions().canChangeLegalBasis || + this.annotationPermissions().canRecategorizeAnnotation || + this.annotationPermissions().canForceHint || + this.annotationPermissions().canForceRedaction; + return ( + this.annotationChangesAllowed() && + (this.annotations().length > 1 + ? this.#isDocumine + ? this.annotationPermissions().canEditAnnotations + : this.annotationPermissions().canEditHints || + this.annotationPermissions().canEditImages || + this.annotationPermissions().canEditAnnotations + : canEditRedactions) + ); }); constructor( @@ -58,137 +114,54 @@ export class AnnotationActionsComponent implements OnChanges { readonly annotationReferencesService: AnnotationReferencesService, ) {} - get annotations(): AnnotationWrapper[] { - return this.#annotations; - } - - get isImageHint(): boolean { - return this.annotations.every(annotation => annotation.IMAGE_HINT); - } - - @Input() - set annotations(annotations: AnnotationWrapper[]) { - this.#annotations = annotations.filter(a => a !== undefined); - this.isImage = this.#annotations?.reduce((accumulator, annotation) => annotation.isImage && accumulator, true); - this._annotationId = this.#annotations[0]?.id; - } - - get canEdit(): boolean { - const canEditRedactions = - this.annotationPermissions.canChangeLegalBasis || - this.annotationPermissions.canRecategorizeAnnotation || - this.annotationPermissions.canForceHint || - this.annotationPermissions.canForceRedaction; - return ( - this.#annotationChangesAllowed && - (this.annotations.length > 1 - ? this.#isDocumine - ? this.annotationPermissions.canEditAnnotations - : this.annotationPermissions.canEditHints || - this.annotationPermissions.canEditImages || - this.annotationPermissions.canEditAnnotations - : canEditRedactions) - ); - } - - get canResize(): boolean { - return this.#annotationChangesAllowed && this.annotationPermissions.canResizeAnnotation && this.annotations.length === 1; - } - - get canRemoveRedaction(): boolean { - return this.#annotationChangesAllowed && this.annotationPermissions.canRemoveRedaction && this.#sameType; - } - - get canForceRedaction() { - return this.#annotationChangesAllowed && this.annotationPermissions.canForceRedaction; - } - - get canForceHint() { - return this.#annotationChangesAllowed && this.annotationPermissions.canForceHint; - } - - get canAcceptRecommendation() { - return this.#annotationChangesAllowed && this.annotationPermissions.canAcceptRecommendation; - } - - get viewerAnnotations() { - return this._annotationManager.get(this.#annotations); - } - - get resizing() { - return this.#annotations?.length === 1 && this.#annotations?.[0].id === this._annotationManager.resizingAnnotationId; - } - - get resized() { + get resized(): boolean { return this._annotationManager.annotationHasBeenResized; } - get hideSkipped() { - return this.skippedService.hideSkipped() && this.annotations.some(a => a.isSkipped); + async removeRedaction(): Promise { + const annotations = untracked(this.annotations); + const permissions = untracked(this.annotationPermissions); + await this.annotationActionsService.removeRedaction(annotations, permissions); } - get #sameType() { - const type = this.annotations[0].superType; - return this.annotations.every(a => a.superType === type); - } - - ngOnChanges(): void { - this.#setPermissions(); - } - - removeRedaction() { - this.annotationActionsService.removeRedaction(this.annotations, this.annotationPermissions); - } - - acceptRecommendation() { - return this.annotationActionsService.convertRecommendationToAnnotation(this.annotations); + async acceptRecommendation(): Promise { + const annotations = untracked(this.annotations); + await this.annotationActionsService.convertRecommendationToAnnotation(annotations); } hideAnnotation() { - this._annotationManager.hide(this.viewerAnnotations); + const viewerAnnotations = untracked(this.viewerAnnotations); + this._annotationManager.hide(viewerAnnotations); this._annotationManager.deselect(); - this._annotationManager.addToHidden(this.viewerAnnotations[0].Id); + this._annotationManager.addToHidden(viewerAnnotations[0].Id); } showAnnotation() { - this._annotationManager.show(this.viewerAnnotations); + const viewerAnnotations = untracked(this.viewerAnnotations); + this._annotationManager.show(viewerAnnotations); this._annotationManager.deselect(); - this._annotationManager.removeFromHidden(this.viewerAnnotations[0].Id); + this._annotationManager.removeFromHidden(viewerAnnotations[0].Id); } resize() { - return this.annotationActionsService.resize(this.#annotations[0]); + const annotations = untracked(this.annotations); + return this.annotationActionsService.resize(annotations[0]); } acceptResize() { if (this.resized) { - return this.annotationActionsService.acceptResize(this.#annotations[0], this.annotationPermissions); + const annotations = untracked(this.annotations); + const permissions = untracked(this.annotationPermissions); + return this.annotationActionsService.acceptResize(annotations[0], permissions); } } cancelResize() { - return this.annotationActionsService.cancelResize(this.#annotations[0]); + const annotations = untracked(this.annotations); + return this.annotationActionsService.cancelResize(annotations[0]); } helpModeKey(action: string) { return this.#isDocumine ? `${action}_annotation` : `${this.actionsHelpModeKey}_${action}`; } - - #setPermissions() { - this.annotationPermissions = AnnotationPermissions.forUser( - this._permissionsService.isApprover(this._state.dossier()), - this.#annotations, - this._state.dictionaries, - this._iqserPermissionsService, - this._state.file().excludedFromAutomaticAnalysis, - ); - } - - get #annotationChangesAllowed() { - return (!this.#isDocumine || !this._state.file().excludedFromAutomaticAnalysis) && !this.#somePending; - } - - get #somePending() { - return this.#annotations.some(a => a.pending); - } } diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotation-wrapper/annotation-wrapper.component.html b/apps/red-ui/src/app/modules/file-preview/components/annotation-wrapper/annotation-wrapper.component.html index 887105917..75eb18d3a 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/annotation-wrapper/annotation-wrapper.component.html +++ b/apps/red-ui/src/app/modules/file-preview/components/annotation-wrapper/annotation-wrapper.component.html @@ -1,37 +1,42 @@
-
+
-
-
- - {{ annotation.item.numberOfComments }} -
+ @if (!annotation().item.isEarmark) { +
+ @if (!annotation().item.pending) { +
+ + {{ annotation().item.numberOfComments }} +
+ } -
- + @if (multiSelectService.inactive()) { +
+ +
+ }
-
+ } - - + @if (showComments) { +
-
+ }
- + diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotation-wrapper/annotation-wrapper.component.ts b/apps/red-ui/src/app/modules/file-preview/components/annotation-wrapper/annotation-wrapper.component.ts index 49ea32325..32c14be6d 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/annotation-wrapper/annotation-wrapper.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/annotation-wrapper/annotation-wrapper.component.ts @@ -1,4 +1,4 @@ -import { Component, HostBinding, inject, Input, OnChanges } from '@angular/core'; +import { Component, computed, effect, HostBinding, inject, input } from '@angular/core'; import { getConfig, StopPropagationDirective } from '@iqser/common-ui'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { ListItem } from '@models/file/list-item'; @@ -6,7 +6,6 @@ import { MultiSelectService } from '../../services/multi-select.service'; import { PdfProxyService } from '../../services/pdf-proxy.service'; import { ActionsHelpModeKeys } from '../../utils/constants'; import { AnnotationCardComponent } from '../annotation-card/annotation-card.component'; -import { NgIf } from '@angular/common'; import { MatTooltip } from '@angular/material/tooltip'; import { TranslateModule } from '@ngx-translate/core'; import { MatIcon } from '@angular/material/icon'; @@ -21,7 +20,6 @@ import { AnnotationDetailsComponent } from '../annotation-details/annotation-det standalone: true, imports: [ AnnotationCardComponent, - NgIf, MatTooltip, TranslateModule, StopPropagationDirective, @@ -31,26 +29,28 @@ import { AnnotationDetailsComponent } from '../annotation-details/annotation-det AnnotationDetailsComponent, ], }) -export class AnnotationWrapperComponent implements OnChanges { - readonly #isDocumine = getConfig().IS_DOCUMINE; +export class AnnotationWrapperComponent { + readonly annotation = input.required>(); + @HostBinding('attr.annotation-id') annotationId: string; + @HostBinding('class.active') active: boolean; + + readonly actionsHelpModeKey = computed(() => this.#getActionsHelpModeKey(this.annotation().item)); + showComments = false; protected readonly pdfProxyService = inject(PdfProxyService); protected readonly multiSelectService = inject(MultiSelectService); - @Input({ required: true }) annotation!: ListItem; - @HostBinding('attr.annotation-id') annotationId: string; - @HostBinding('class.active') active = false; - actionsHelpModeKey: string; - showComments = false; + readonly #isDocumine = getConfig().IS_DOCUMINE; - ngOnChanges() { - this.annotationId = this.annotation.item.id; - this.active = this.annotation.isSelected; - this.actionsHelpModeKey = this.#getActionsHelpModeKey(); + constructor() { + effect(() => { + this.active = this.annotation().isSelected; + this.annotationId = this.annotation().item.id; + }); } - #getActionsHelpModeKey(): string { + #getActionsHelpModeKey(item: AnnotationWrapper): string { if (!this.#isDocumine) { - const superType = this.annotation.item.superTypeLabel?.split('.')[1]; - const type = this.annotation.item.type; + const superType = item.superTypeLabel?.split('.')[1]; + const type = item.type; if (superType === 'hint' && (type === 'ocr' || type === 'formula' || type === 'image')) { return ActionsHelpModeKeys[`${superType}-${type}`]; } diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.html b/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.html index c62243644..97d2ea0c0 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.html +++ b/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.html @@ -1,16 +1,16 @@ - -
+@for (annotation of annotations(); track annotation.item.id) { + @if (displayedHighlightGroups()[$index]; as highlightGroup) { -
+ } -
+} []; - @Output() readonly pagesPanelActive = new EventEmitter(); - readonly #earmarkGroups = computed(() => { - if (this._viewModeService.isEarmarks()) { - return this.#getEarmarksGroups(); + readonly annotations = input.required[]>(); + readonly pagesPanelActive = output(); + readonly displayedHighlightGroups = computed(() => { + const isEarMarks = this._viewModeService.isEarmarks(); + let result: Record = {}; + + if (isEarMarks) { + const annotations = this.annotations(); + const earmarkGroups = this.#getEarmarksGroups(annotations); + for (let idx = 0; idx < annotations.length; ++idx) { + const group = earmarkGroups.find(h => h.startIdx === idx); + if (group) { + result[idx] = group; + } + } } - return [] as EarmarkGroup[]; + + return result; }); protected readonly isDocumine = getConfig().IS_DOCUMINE; @@ -77,26 +88,20 @@ export class AnnotationsListComponent extends HasScrollbarDirective { } } - showHighlightGroup(idx: number): EarmarkGroup { - return this._viewModeService.isEarmarks() && this.#earmarkGroups().find(h => h.startIdx === idx); - } - - protected readonly _trackBy = (index: number, listItem: ListItem) => listItem.item.id; - - #getEarmarksGroups() { + #getEarmarksGroups(annotations: ListItem[]) { const earmarksGroups: EarmarkGroup[] = []; - if (!this.annotations?.length) { + if (!annotations.length) { return earmarksGroups; } let lastGroup: EarmarkGroup; - for (let idx = 0; idx < this.annotations.length; ++idx) { - if (idx === 0 || this.annotations[idx].item.color !== this.annotations[idx - 1].item.color) { + for (let idx = 0; idx < annotations.length; ++idx) { + if (idx === 0 || annotations[idx].item.color !== annotations[idx - 1].item.color) { if (lastGroup) { earmarksGroups.push(lastGroup); } - lastGroup = { startIdx: idx, length: 1, color: this.annotations[idx].item.color }; + lastGroup = { startIdx: idx, length: 1, color: annotations[idx].item.color }; } else { lastGroup.length += 1; } diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts index 2e7fbdfd4..7aab6a810 100644 --- a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts @@ -1,5 +1,5 @@ import { ActivatedRouteSnapshot, NavigationExtras, Router, RouterLink } from '@angular/router'; -import { ChangeDetectorRef, Component, effect, NgZone, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core'; +import { ChangeDetectorRef, Component, effect, NgZone, OnDestroy, OnInit, TemplateRef, untracked, ViewChild } from '@angular/core'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { ComponentCanDeactivate } from '@guards/can-deactivate.guard'; import { @@ -179,7 +179,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni effect(() => { this._viewModeService.viewMode(); - this.updateViewMode().then(); + this.#updateViewMode().then(); }); effect(() => { @@ -207,7 +207,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni const earmarks$ = isEarmarksViewMode$.pipe( tap(() => this._loadingService.start()), switchMap(() => this._fileDataService.loadEarmarks()), - tap(() => this.updateViewMode().then(() => this._loadingService.stop())), + tap(() => this.#updateViewMode().then(() => this._loadingService.stop())), ); const currentPageIfEarmarksView$ = combineLatest([this.pdf.currentPage$, this._viewModeService.viewMode$]).pipe( @@ -233,7 +233,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni return isChangingFromEarmarksViewMode$.pipe( map(() => this._fileDataService.earmarks().get(this.pdf.currentPage()) ?? []), - map(earmarks => this.deleteAnnotations(earmarks, [])), + map(earmarks => this.#deleteAnnotations(earmarks, [])), ); } @@ -242,61 +242,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this._viewerHeaderService.disable(ROTATION_ACTION_BUTTONS); } - async updateViewMode(): Promise { - this._logger.info(`[PDF] Update ${this._viewModeService.viewMode()} view mode`); - - const annotations = this._annotationManager.get(a => bool(a.getCustomData('redact-manager'))); - const redactions = annotations.filter(a => bool(a.getCustomData('redaction'))); - - switch (this._viewModeService.viewMode()) { - case ViewModes.STANDARD: { - const wrappers = this._fileDataService.annotations(); - const ocrAnnotationIds = wrappers.filter(a => a.isOCR).map(a => a.id); - const standardEntries = annotations - .filter(a => !bool(a.getCustomData('changeLogRemoved')) && !this._annotationManager.isHidden(a.Id)) - .filter(a => !ocrAnnotationIds.includes(a.Id)); - const nonStandardEntries = annotations.filter( - a => - bool(a.getCustomData('changeLogRemoved')) || - this._annotationManager.isHidden(a.Id) || - (this._skippedService.hideSkipped() && bool(a.getCustomData('skipped'))), - ); - this._readableRedactionsService.setAnnotationsColor(standardEntries, 'annotationColor'); - this._readableRedactionsService.setAnnotationsOpacity(standardEntries, true); - this._annotationManager.show(standardEntries); - this._annotationManager.hide(nonStandardEntries); - break; - } - case ViewModes.DELTA: { - const changeLogEntries = annotations.filter(a => bool(a.getCustomData('changeLog'))); - const nonChangeLogEntries = annotations.filter(a => !bool(a.getCustomData('changeLog'))); - this._readableRedactionsService.setAnnotationsColor(redactions, 'annotationColor'); - this._readableRedactionsService.setAnnotationsOpacity(changeLogEntries, true); - this._annotationManager.show(changeLogEntries); - this._annotationManager.hide(nonChangeLogEntries); - break; - } - case ViewModes.REDACTED: { - const nonRedactionEntries = annotations.filter( - a => !bool(a.getCustomData('redaction')) || bool(a.getCustomData('changeLogRemoved')), - ); - this._readableRedactionsService.setAnnotationsColor(redactions, 'redactionColor'); - this._readableRedactionsService.setAnnotationsOpacity(redactions); - this._annotationManager.show(redactions); - this._annotationManager.hide(nonRedactionEntries); - - break; - } - case ViewModes.TEXT_HIGHLIGHTS: { - this._annotationManager.hide(annotations); - } - } - - this._logger.info('[PDF] Rebuild filters'); - this.#rebuildFilters(); - this._logger.info('[PDF] Update done'); - } - ngOnDetach() { this._viewerHeaderService.resetCompareButtons(); this._viewerHeaderService.enableLoadAllAnnotations(); // Reset the button state (since the viewer is reused between files) @@ -413,7 +358,9 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni const annotations$ = this._fileDataService.annotations$.pipe( startWith([] as AnnotationWrapper[]), pairwise(), - tap(annotations => this.deleteAnnotations(...annotations)), + tap(annotations => this.#deleteAnnotations(...annotations)), + tap(() => this.#updateFiltersAfterAnnotationsChanged()), + tap(() => this.#updateViewMode()), ); const currentPageIfNotHighlightsView$ = combineLatest([this.pdf.currentPage$, this._viewModeService.viewMode$]).pipe( @@ -432,12 +379,72 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni return combineLatest([currentPageAnnotations$, this._documentViewer.loaded$]).pipe( filter(([, loaded]) => loaded), map(([annotations]) => annotations), - tap(([oldA, newA]) => this.drawChangedAnnotations(oldA, newA)?.then(() => this.updateViewMode())), - tap(([, newAnnotations]) => this.#highlightSelectedAnnotations(newAnnotations)), + switchMap(async ([oldAnnotations, newAnnotations]) => { + await this.#drawChangedAnnotations(oldAnnotations, newAnnotations); + return newAnnotations; + }), + tap(newAnnotations => this.#highlightSelectedAnnotations(newAnnotations)), ); } - deleteAnnotations(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]) { + async #updateViewMode(): Promise { + const viewMode = untracked(this._viewModeService.viewMode); + this._logger.info(`[PDF] Update ${viewMode} view mode`); + + const annotations = this._annotationManager.get(a => bool(a.getCustomData('redact-manager'))); + const redactions = annotations.filter(a => bool(a.getCustomData('redaction'))); + + switch (viewMode) { + case ViewModes.STANDARD: { + const wrappers = this._fileDataService.annotations(); + // TODO: const wrappers = untracked(this._fileDataService.annotations); + const ocrAnnotationIds = wrappers.filter(a => a.isOCR).map(a => a.id); + const standardEntries = annotations + .filter(a => !bool(a.getCustomData('changeLogRemoved')) && !this._annotationManager.isHidden(a.Id)) + .filter(a => !ocrAnnotationIds.includes(a.Id)); + const nonStandardEntries = annotations.filter( + a => + bool(a.getCustomData('changeLogRemoved')) || + this._annotationManager.isHidden(a.Id) || + (untracked(this._skippedService.hideSkipped) && bool(a.getCustomData('skipped'))), + ); + this._readableRedactionsService.setAnnotationsColor(standardEntries, 'annotationColor'); + this._readableRedactionsService.setAnnotationsOpacity(standardEntries, true); + this._annotationManager.show(standardEntries); + this._annotationManager.hide(nonStandardEntries); + break; + } + case ViewModes.DELTA: { + const changeLogEntries = annotations.filter(a => bool(a.getCustomData('changeLog'))); + const nonChangeLogEntries = annotations.filter(a => !bool(a.getCustomData('changeLog'))); + this._readableRedactionsService.setAnnotationsColor(redactions, 'annotationColor'); + this._readableRedactionsService.setAnnotationsOpacity(changeLogEntries, true); + this._annotationManager.show(changeLogEntries); + this._annotationManager.hide(nonChangeLogEntries); + break; + } + case ViewModes.REDACTED: { + const nonRedactionEntries = annotations.filter( + a => !bool(a.getCustomData('redaction')) || bool(a.getCustomData('changeLogRemoved')), + ); + this._readableRedactionsService.setAnnotationsColor(redactions, 'redactionColor'); + this._readableRedactionsService.setAnnotationsOpacity(redactions); + this._annotationManager.show(redactions); + this._annotationManager.hide(nonRedactionEntries); + + break; + } + case ViewModes.TEXT_HIGHLIGHTS: { + this._annotationManager.hide(annotations); + } + } + + this._logger.info('[PDF] Rebuild filters'); + this.#rebuildFilters(); + this._logger.info('[PDF] Update done'); + } + + #deleteAnnotations(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]) { const annotationsToDelete = oldAnnotations.filter(oldAnnotation => { const newAnnotation = newAnnotations.find(byId(oldAnnotation.id)); return newAnnotation ? hasChanges(oldAnnotation, newAnnotation) : true; @@ -447,7 +454,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this._annotationManager.delete(annotationsToDelete); } - async drawChangedAnnotations(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]): Promise { + async #drawChangedAnnotations(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]): Promise { const annotationsToDraw = this.#getAnnotationsToDraw(oldAnnotations, newAnnotations); this._logger.info('[ANNOTATIONS] To draw: ', annotationsToDraw); this._annotationManager.delete(annotationsToDraw); @@ -642,7 +649,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni filter(event => event.type === ViewerEvents.LOAD_ALL_ANNOTATIONS), switchMap(() => { // TODO: this switchMap is ugly, to be refactored - const annotations = this._fileDataService.annotations(); + const annotations = untracked(this._fileDataService.annotations); const showWarning = !this.userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning); const annotationsExceedThreshold = annotations.length >= this.configService.values.ANNOTATIONS_THRESHOLD; @@ -655,7 +662,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni filter(([confirmed]) => confirmed), map(([, annotations]) => { this.#loadAllAnnotationsEnabled = true; - this.drawChangedAnnotations([], annotations).then(() => { + this.#drawChangedAnnotations([], annotations).then(() => { this._toaster.success(_('load-all-annotations-success')); this._viewerHeaderService.disableLoadAllAnnotations(); }); @@ -663,7 +670,9 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni ) .subscribe(); - this.addActiveScreenSubscription = this._readableRedactionsService.active$.pipe(map(() => this.updateViewMode())).subscribe(); + this.addActiveScreenSubscription = this._readableRedactionsService.active$ + .pipe(switchMap(() => this.#updateViewMode())) + .subscribe(); this.addActiveScreenSubscription = combineLatest([this._viewModeService.viewMode$, this.state.file$, this._documentViewer.loaded$]) .pipe( @@ -707,6 +716,10 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni return undefined; } + await this._annotationDrawService.draw(newAnnotations, this._skippedService.hideSkipped(), this.state.dossierTemplateId); + } + + #updateFiltersAfterAnnotationsChanged(): void { const currentFilters = this._filterService.getGroup('primaryFilters')?.filters || []; this.#rebuildFilters(); @@ -715,8 +728,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this.#handleDeltaAnnotationFilters(currentFilters); }, 100); } - - await this._annotationDrawService.draw(newAnnotations, this._skippedService.hideSkipped(), this.state.dossierTemplateId); } #handleDeltaAnnotationFilters(currentFilters: NestedFilter[]) { diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-references.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-references.service.ts index 914376c97..789d38d83 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-references.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-references.service.ts @@ -1,5 +1,4 @@ import { computed, Injectable, Signal, signal } from '@angular/core'; -import { BehaviorSubject } from 'rxjs'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { FileDataService } from './file-data.service'; @@ -7,7 +6,6 @@ import { FileDataService } from './file-data.service'; export class AnnotationReferencesService { readonly references: Signal; readonly annotation: Signal; - private readonly _annotation$ = new BehaviorSubject(undefined); readonly #annotation = signal(undefined); constructor(private readonly _fileDataService: FileDataService) { diff --git a/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts b/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts index 976be8626..7b7560376 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts @@ -1,4 +1,4 @@ -import { computed, effect, inject, Injectable, NgZone } from '@angular/core'; +import { computed, effect, inject, Injectable, NgZone, untracked } from '@angular/core'; import { getConfig, IqserPermissionsService } from '@iqser/common-ui'; import { getCurrentUser } from '@iqser/common-ui/lib/users'; import { isJustOne, shareDistinctLast, UI_ROOT_PATH_FN } from '@iqser/common-ui/lib/utils'; @@ -49,7 +49,7 @@ export class PdfProxyService { readonly redactTextRequested$ = new Subject(); readonly currentUser = getCurrentUser(); readonly pageChanged$ = this._pdf.pageChanged$.pipe( - tap(() => this.#handleExcludedPageActions()), + tap(pageNumber => this.#handleExcludedPageActions(pageNumber)), tap(() => { if (this._multiSelectService.inactive()) { this._annotationManager.deselect(); @@ -98,7 +98,7 @@ export class PdfProxyService { effect( () => { const canPerformActions = this.canPerformActions(); - this._pdf.isCompareMode(); + const isCompareMode = this._pdf.isCompareMode(); this.#configureTextPopup(); @@ -109,7 +109,8 @@ export class PdfProxyService { this.#deactivateMultiSelect(); } - this.#handleExcludedPageActions(); + const currentPage = untracked(this._pdf.currentPage); + this.#handleExcludedPageActions(currentPage); }, { allowSignalWrites: true }, ); @@ -227,8 +228,9 @@ export class PdfProxyService { this.redactTextRequested$.next({ manualRedactionEntry, type }); } - #handleExcludedPageActions() { - const isCurrentPageExcluded = this._state.file().isPageExcluded(this._pdf.currentPage()); + #handleExcludedPageActions(currentPage: number) { + const isCurrentPageExcluded = this._state.file().isPageExcluded(currentPage); + if (!isCurrentPageExcluded) { return; } From c3fbb9100aa2d199bb7f23e4daa480cb83a62eb3 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Mon, 30 Sep 2024 13:29:00 +0300 Subject: [PATCH 056/125] RED-9722: split bulk remove-from-dict request into batches. --- .../services/annotation-actions.service.ts | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts index f44e02c32..341bd7c8b 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts @@ -277,7 +277,6 @@ export class AnnotationActionsService { const text = annotation.AREA ? annotation.value : isImageText; const isApprover = this._permissionsService.isApprover(dossier); const dossierTemplate = this._dossierTemplatesService.find(this._state.dossierTemplateId); - const isUnprocessed = annotation.pending; const data: ResizeRedactionData = { redaction: annotation, @@ -308,7 +307,7 @@ export class AnnotationActionsService { await this.cancelResize(annotation); - const { fileId, dossierId, file } = this._state; + const { fileId, dossierId } = this._state; const request = this._manualRedactionService.resize([resizeRequest], dossierId, fileId, includeUnprocessed); return this.#processObsAndEmit(request); } @@ -471,6 +470,36 @@ export class AnnotationActionsService { // todo: might not be correct, probably shouldn't get to this point if they are not all the same const isHint = redactions.every(r => r.isHint); const { dossierId, fileId } = this._state; + const maximumNumberEntries = 100; + if (removeFromDictionary && (body as List).length > maximumNumberEntries) { + const requests = body as List; + const splitNumber = Math.floor(requests.length / maximumNumberEntries); + const remainder = requests.length % maximumNumberEntries; + const splitRequests = []; + for (let i = 0; i < splitNumber; i++) { + splitRequests.push(requests.slice(i * maximumNumberEntries, (i + 1) * maximumNumberEntries)); + } + splitRequests.push(requests.slice(splitNumber * maximumNumberEntries, splitNumber * maximumNumberEntries + remainder)); + + const promises = []; + for (const split of splitRequests) { + promises.push( + firstValueFrom( + this._manualRedactionService.removeRedaction( + split, + dossierId, + fileId, + removeFromDictionary, + isHint, + includeUnprocessed, + dialogResult.bulkLocal, + ), + ), + ); + } + Promise.all(promises).finally(() => this._fileDataService.annotationsChanged()); + return; + } this.#processObsAndEmit( this._manualRedactionService.removeRedaction( body, From b989da3f05697960e4491cedd23e6f8da89f457e Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Mon, 30 Sep 2024 14:10:10 +0300 Subject: [PATCH 057/125] RED-9578: filter files without warnings. --- .../modules/dossier-overview/services/bulk-actions.service.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/red-ui/src/app/modules/dossier-overview/services/bulk-actions.service.ts b/apps/red-ui/src/app/modules/dossier-overview/services/bulk-actions.service.ts index 6e78328b2..d0517aef4 100644 --- a/apps/red-ui/src/app/modules/dossier-overview/services/bulk-actions.service.ts +++ b/apps/red-ui/src/app/modules/dossier-overview/services/bulk-actions.service.ts @@ -119,7 +119,9 @@ export class BulkActionsService { return; } - const fileWarnings = approvalResponse.map(response => ({ fileId: response.fileId, fileWarnings: response.fileWarnings })); + const fileWarnings = approvalResponse + .filter(response => response.hasWarnings) + .map(response => ({ fileId: response.fileId, fileWarnings: response.fileWarnings })); this._dialogService.openDialog( 'confirm', { From fcf159d091763f451507b2d3b2b0fc7353362591 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Wed, 2 Oct 2024 14:32:57 +0300 Subject: [PATCH 058/125] RED-9578: fixed styles. --- .../selected-annotations-table.component.html | 4 +++- .../selected-annotations-table.component.scss | 5 +++++ .../approve-warning-details.component.scss | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.html b/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.html index 86c807318..a801712b9 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.html +++ b/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.html @@ -1,6 +1,8 @@
@for (column of _columns(); track column.label) { -
{{ column.label }}
+
+ +
} @for (row of _data(); track $index) { @for (cell of row; track cell.label) { diff --git a/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.scss b/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.scss index e3e006557..4c49205c1 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/components/selected-annotations-table/selected-annotations-table.component.scss @@ -12,6 +12,11 @@ top: 0; z-index: 1; background: white; + + label { + opacity: 0.7; + font-weight: normal; + } } .cell { diff --git a/apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.scss b/apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.scss index 7b5d3cd12..edae56a05 100644 --- a/apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.scss +++ b/apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.scss @@ -2,10 +2,10 @@ :host { height: 250px; + margin-bottom: 16px; } .scrollable { - margin-bottom: 8px; overflow-y: auto; max-height: 240px; @include common-mixins.scroll-bar; From 6693933941fc3815f31dba46cdede168fe1fa245 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Thu, 3 Oct 2024 14:33:09 +0300 Subject: [PATCH 059/125] RED-9559: dashboard skeleton, empty state and stats have the same width. --- .../dashboard-skeleton/dashboard-skeleton.component.scss | 2 +- .../dashboard/dashboard-screen/dashboard-screen.component.scss | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/red-ui/src/app/components/skeleton/dashboard-skeleton/dashboard-skeleton.component.scss b/apps/red-ui/src/app/components/skeleton/dashboard-skeleton/dashboard-skeleton.component.scss index 535465137..50bd18553 100644 --- a/apps/red-ui/src/app/components/skeleton/dashboard-skeleton/dashboard-skeleton.component.scss +++ b/apps/red-ui/src/app/components/skeleton/dashboard-skeleton/dashboard-skeleton.component.scss @@ -9,7 +9,7 @@ .container { padding: 32px; - width: 900px; + width: 1000px; max-width: 100%; box-sizing: border-box; } diff --git a/apps/red-ui/src/app/modules/dashboard/dashboard-screen/dashboard-screen.component.scss b/apps/red-ui/src/app/modules/dashboard/dashboard-screen/dashboard-screen.component.scss index e58cf19de..976ac19cd 100644 --- a/apps/red-ui/src/app/modules/dashboard/dashboard-screen/dashboard-screen.component.scss +++ b/apps/red-ui/src/app/modules/dashboard/dashboard-screen/dashboard-screen.component.scss @@ -4,6 +4,7 @@ .container { padding: 32px; + width: 1000px; max-width: 100%; box-sizing: border-box; } From bef117a22cf2fb5e27be29b2078b12ddcf9fc58a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Thu, 3 Oct 2024 14:50:58 +0300 Subject: [PATCH 060/125] RED-3800: Localazy manual sync --- apps/red-ui/src/assets/i18n/redact/de.json | 280 +++-- apps/red-ui/src/assets/i18n/redact/en.json | 38 +- apps/red-ui/src/assets/i18n/scm/de.json | 1122 ++++++++++---------- apps/red-ui/src/assets/i18n/scm/en.json | 132 +-- 4 files changed, 756 insertions(+), 816 deletions(-) diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index 588f1bbfe..142adad86 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -138,7 +138,7 @@ }, "add-edit-entity": { "form": { - "case-sensitive": "Groß-/Kleinschreibung berücksichtigen", + "case-sensitive": "Groß-/Kleinschreibung beachten", "color": "Farbe {type, select, redaction{Schwärzung} hint{Hinweis} recommendation{Empfehlung} skipped{Ingorierte Schwärzung} ignored{Ignorierter Hinweis} other{}}", "color-placeholder": "#", "default-reason": "Standardgrund", @@ -146,7 +146,7 @@ "description": "Beschreibung", "description-placeholder": "Beschreibung eingeben", "dossier-dictionary-only": "Nur Dossier-Wörterbuch", - "has-dictionary": "Mit Wörterbuch", + "has-dictionary": "Hat Wörterbuch", "hint": "Hinweis", "manage-entries-in-dictionary-editor-only": "In Schwärzungs-/Bearbeitungsdialogen verfügbar", "name": "Anzeigename", @@ -207,14 +207,14 @@ "generic": "Speichern des Benutzers fehlgeschlagen." }, "form": { - "account-setup": "User account setup", + "account-setup": "Konfiguration des Benutzerkontos", "email": "E-Mail", "first-name": "Vorname", "last-name": "Nachname", "reset-password": "Passwort zurücksetzen", "role": "Rolle", - "send-email": "Do not send email requesting the user to set a password", - "send-email-explanation": "Select this option if you use SSO. Please note that you will need to inform the user directly." + "send-email": "Benutzer nicht per E-Mail auffordern, ein Passwort festzulegen", + "send-email-explanation": "Wählen Sie diese Option, wenn Sie SSO verwenden. Bitte beachten Sie, dass Sie den Benutzer direkt informieren müssen." }, "title": "{type, select, edit{Benutzer bearbeiten} create{Neuen Benutzer erstellen} other{}}" }, @@ -243,8 +243,7 @@ } }, "type": "Typ", - "type-placeholder": "Typ auswählen...", - "value": "" + "type-placeholder": "Typ auswählen..." }, "title": "Hinweis hinzufügen" } @@ -276,6 +275,9 @@ "watermarks": "Wasserzeichen" }, "analysis-disabled": "", + "annotation": { + "pending": "(Analyse steht aus)" + }, "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" @@ -331,14 +333,14 @@ "error": "Rekategorisierung des Bilds fehlgeschlagen: {error}", "success": "Bild wurde einer neuen Kategorie zugeordnet." }, - "remove-hint": { - "error": "Entfernen des Hinweises fehlgeschlagen: {error}", - "success": "Hinweis wurde entfernt" - }, "remove": { "error": "Entfernen der Schwärzung fehlgeschlagen: {error}", "success": "Schwärzung wurde entfernt" }, + "remove-hint": { + "error": "Entfernen des Hinweises fehlgeschlagen: {error}", + "success": "Hinweis wurde entfernt" + }, "undo": { "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", "success": "Rücksetzung erfolgreich" @@ -351,15 +353,15 @@ "remove-highlights": { "label": "Ausgewählte Markierungen entfernen" }, + "resize": { + "label": "Größe ändern" + }, "resize-accept": { "label": "Neue Größe speichern" }, "resize-cancel": { "label": "Größenänderung abbrechen" }, - "resize": { - "label": "Größe ändern" - }, "see-references": { "label": "Referenzen anzeigen" }, @@ -368,7 +370,7 @@ }, "annotation-changes": { "added-locally": "Lokal hinzugefügt", - "forced-hint": "Hint wurde erzwungen", + "forced-hint": "Hinweis wurde erzwungen", "forced-redaction": "Schwärzung wurde erzwungen", "header": "Lokale manuelle Änderungen:", "legal-basis": "Grund wurde geändert", @@ -376,9 +378,8 @@ "removed-manual": "Schwärzung/Hinweis wurde entfernt", "resized": "Schwärzungsbereich wurde geändert" }, - "annotation-content": "{hasRule, select, true {Regel {matchedRule} trifft zu auf{ruleSymbol}} other {}} {hasReason, select, true {{reason}} other {}} {hasLb, select, true {Rechstgrundlage: {legalBasis}} other {}} {hasOverride, select, true {Entfernt durch manuelles Überschreiben} other {}} {hasSection, select, true {{shouldLower, plural, =0 {I} other {i}}n Abschnitt{sectionSymbol} \"{section}\"} other {}}", "annotation-engines": { - "dictionary": "{isHint, select, true{Hinweis} other{Schwärzung}} basiert auf Wörterbuch", + "dictionary": "Basiert auf Wörterbuch", "dossier-dictionary": "Basiert auf Dossier-Wörterbuch", "imported": "Importiert", "ner": "Basiert auf KI-Modell", @@ -394,9 +395,6 @@ "skipped": "Ignorierte Schwärzung", "text-highlight": "Markierung" }, - "annotation": { - "pending": "(Analyse steht aus)" - }, "annotations": "Annotationen", "archived-dossiers-listing": { "no-data": { @@ -420,7 +418,7 @@ "approver": "Genehmiger", "approvers": "Genehmiger", "make-approver": "Zum Genehmiger machen", - "no-reviewers": "Es wurden noch keine Prüfer zum Team hinzugefügt.", + "no-reviewers": "Es wurden noch keine Mitglieder zum Dossier hinzugefügt, die nur die Prüfer-Berechtigung haben.", "reviewers": "Prüfer", "search": "Suche...", "single-user": "Besitzer" @@ -572,7 +570,7 @@ }, "search": "Nach Name suchen...", "table-col-names": { - "column-labels": "Column labels", + "column-labels": "Spaltenbeschriftungen", "name": "Name", "number-of-lines": "Zeilenzahl", "version": "Version" @@ -641,14 +639,14 @@ }, "confirmation-dialog": { "approve-file": { - "confirmationText": "Approve anyway", - "denyText": "No, cancel", - "question": "Do you still want to approve the {questionLength, plural, one{document} other{documents}}?", - "title": "Approval warning", + "confirmationText": "Trotzdem genehmigen", + "denyText": "Nein, abbrechen", + "question": "Dieses Dokument enthält ungesehene Änderungen, die sich durch die Reanalyse ergeben haben.

Möchten Sie es trotzdem freigeben?", + "title": "Warnung!", "warning-reason": { - "legal-basis-missing": "Legal basis missing", - "pending-changes": "Pending Changes", - "unmapped-justification": "Unmapped justification" + "legal-basis-missing": "Rechtsgrundlage fehlt", + "pending-changes": "Änderungen stehen aus", + "unmapped-justification": "Nicht gemappte Begründung" } }, "assign-file-to-me": { @@ -665,7 +663,7 @@ "delete-dossier": { "confirmation-text": "{dossiersCount, plural, one{Dossier} other{Dossiers}} löschen", "deny-text": "{dossiersCount, plural, one{Dossier} other{Dossiers}} behalten", - "question": "Möchten Sie dieses Dokument wirklich löschen?", + "question": "Möchten Sie {dossiersCount, plural, one{dieses Dossier} other{diese Dossiers}} wirklich löschen?", "title": "{dossiersCount, plural, one{{dossierName}} other{selected dossiers}} löschen" }, "delete-file": { @@ -674,7 +672,7 @@ }, "delete-items": { "question": "Möchten Sie {itemsCount, plural, one{dieses Element} other{diese Elemente}} wirklich löschen?", - "title": "{itemsCount, plural, one{{name}} other{Ausgewählte Elemente}} löschen" + "title": "{itemsCount, plural, one{{name}} other{selected items}} löschen" }, "delete-justification": { "question": "Möchten Sie {count, plural, one{diese Begründung} other{diese Begründungen}} wirklich löschen?", @@ -722,7 +720,7 @@ "key": "Typ" }, "table-header": { - "title": "{length} Standard{length, plural, one{farbe} other{farben}}" + "title": "{length} Standard{length, plural, one{Farbe} other{Farben}}" }, "types": { "analysisColor": "Analyse", @@ -764,7 +762,7 @@ "compare": { "compare": "Vergleichen", "select-dictionary": "Wörterbuch auswählen", - "select-dossier": "Wörterbuch auswählen", + "select-dossier": "Dossier auswählen", "select-dossier-template": "Dossier-Vorlage auswählen" }, "download": "Aktuelle Einträge herunterladen", @@ -854,7 +852,7 @@ "date": "Datum", "image": "Bild", "number": "Nummer", - "text": "Freier Text" + "text": "Text" }, "dossier-attributes-listing": { "action": { @@ -946,7 +944,7 @@ }, "dossier-overview": { "approve": "Freigeben", - "approve-disabled": "Sie können die Datei erst freigeben, wenn Sie anhand der neusten Regeln und Begriffe in den Systemwörterbüchern analysiert wurde.", + "approve-disabled": "Sie können die Datei erst freigeben, wenn sie auf Basis der aktuellen Wörterbücher analysiert wurde.", "assign-approver": "Genehmiger zuweisen", "assign-me": "Mir zuweisen", "assign-reviewer": "Benutzer zuweisen", @@ -989,8 +987,8 @@ } }, "filters": { - "label": "Name des Dokuments", - "search": "Name des Dokuments..." + "label": "Dokumentname", + "search": "Name des Dokuments eingeben..." }, "header-actions": { "download-csv": "CSV-Bericht herunterladen", @@ -1020,13 +1018,13 @@ "recent": "Neu ({hours} h)", "unassigned": "Keinem Bearbeiter zugewiesen" }, + "reanalyse": { + "action": "Datei analysieren" + }, "reanalyse-dossier": { "error": "Einplanung der Dateien für die Reanalyse fehlgeschlagen. Bitte versuchen Sie es noch einmal.", "success": "Dateien für Reanalyse vorgesehen." }, - "reanalyse": { - "action": "Datei analysieren" - }, "report-download": "", "start-auto-analysis": "Auto-Analyse aktivieren", "stop-auto-analysis": "Auto-Analyse anhalten", @@ -1096,6 +1094,14 @@ "total-documents": "Dokumente", "total-people": "{count} {count, plural, one{Benutzer} other {Benutzer}}" }, + "dossier-templates": { + "label": "Dossier-Vorlagen", + "status": { + "active": "Aktiv", + "inactive": "Inaktiv", + "incomplete": "Unvollständig" + } + }, "dossier-templates-listing": { "action": { "clone": "Vorlage klonen", @@ -1130,14 +1136,6 @@ "title": "{length} {length, plural, one{Dossier-Vorlage} other{Dossier-Vorlagen}}" } }, - "dossier-templates": { - "label": "Dossier-Vorlagen", - "status": { - "active": "Aktiv", - "inactive": "Inaktiv", - "incomplete": "Unvollständig" - } - }, "dossier-watermark-selector": { "heading": "Wasserzeichen auf Dokumenten", "no-watermark": "Kein Wasserzeichen in der Dossier-Vorlage verfügbar:
Bitten Sie Ihren Admin, eines zu konfigurieren.", @@ -1169,7 +1167,7 @@ "delta-preview": "Delta-PDF", "flatten": "Verflachte PDF", "label": "{length} Dokumenten{length, plural, one{typ} other{typen}}", - "optimized-preview": "Optimized Preview PDF", + "optimized-preview": "Optimierte Vorschau-PDF", "original": "Optimierte PDF", "preview": "Vorschau-PDF", "redacted": "Geschwärzte PDF", @@ -1235,10 +1233,12 @@ "save": "Speichern", "title": "{label} bearbeiten" }, - "entries-count": "", - "false-positives": "Falsch-Positive ({count})", - "false-recommendations": "Falsche Empfehlungen ({count})", - "to-redact": "Schwärzungen ({count})" + "entries": "{length} {length, plural, one{Eintrag} other{Einträge}}", + "false-positive-entries": "{length} {length, plural, one{Falsch-Positiver} other{Falsch-Positive}}", + "false-positives": "Falsch-Positive", + "false-recommendation-entries": "{length} {length, plural, one{falsche Empfehlung} other{falsche Empfehlungen}}", + "false-recommendations": "Falsche Empfehlungen", + "to-redact": "Schwärzungen" }, "general-info": { "form": { @@ -1264,7 +1264,7 @@ "choose-download": "Stellen Sie Ihr Download-Paket zusammen:", "dictionary": "Wörterbücher", "dossier-attributes": "Dossier-Attribute", - "dossier-dictionary": "Wörterbücher", + "dossier-dictionary": "Dossier-Einträge", "dossier-info": "Dossier-Info", "download-package": "Download-Paket", "general-info": "Allgemeine Informationen", @@ -1282,11 +1282,14 @@ "content": { "comment": "Kommentar", "comment-placeholder": "Bemerkungen oder Notizen hinzufügen...", + "custom-rectangle": "Bereichsschwärzung", + "imported": "Importierte Schwärzung", "legal-basis": "Rechtsgrundlage", "options": { - "in-document": { - "description": "", - "label": "" + "in-dossier": { + "description": "Schwärzung in jedem Dokument in {dossierName} bearbeiten.", + "extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen", + "label": "Typ in Dossier ändern" }, "only-here": { "description": "Bearbeiten Sie die Schwärzung nur an dieser Stelle im Dokument.", @@ -1329,6 +1332,15 @@ "title": "{length} {length, plural, one{Wörterbuch} other{Wörterbücher}}" } }, + "entity": { + "info": { + "actions": { + "revert": "Zurücksetzen", + "save": "Änderungen speichern" + }, + "heading": "Entität bearbeiten" + } + }, "entity-rules-screen": { "error": { "generic": "Fehler: Aktualisierung der Entitätsregeln fehlgeschlagen." @@ -1342,28 +1354,19 @@ "title": "Entitätsregeln-Editor", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} in Regeln gefunden" }, - "entity": { - "info": { - "actions": { - "revert": "Zurücksetzen", - "save": "Änderungen speichern" - }, - "heading": "Entität bearbeiten" - } - }, "error": { "deleted-entity": { "dossier": { "action": "Zurück zur Übersicht", "label": "Dieses Dossier wurde gelöscht!" }, - "file-dossier": { - "action": "Zurück zur Übersicht", - "label": "Das Dossier dieser Datei wurde gelöscht!" - }, "file": { "action": "Zurück zum Dossier", "label": "Diese Datei wurde gelöscht!" + }, + "file-dossier": { + "action": "Zurück zur Übersicht", + "label": "Das Dossier dieser Datei wurde gelöscht!" } }, "file-preview": { @@ -1381,6 +1384,12 @@ }, "exact-date": "{day}. {month} {year} um {hour}:{minute} Uhr", "file": "Datei", + "file-attribute": { + "update": { + "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", + "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." + } + }, "file-attribute-encoding-types": { "ascii": "ASCII", "iso": "ISO-8859-1", @@ -1391,12 +1400,6 @@ "number": "Nummer", "text": "Freier Text" }, - "file-attribute": { - "update": { - "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", - "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." - } - }, "file-attributes-configurations": { "cancel": "Abbrechen", "form": { @@ -1472,7 +1475,7 @@ "delete": "Attribut löschen", "edit": "Attribut bearbeiten" }, - "add-new": "Neue Attribute", + "add-new": "Neues Attribut", "bulk-actions": { "delete": "Ausgewählte Attribute löschen" }, @@ -1491,7 +1494,7 @@ "search": "Nach Attribut-Namen suchen...", "table-col-names": { "csv-column": "CSV-Spalte", - "displayed-in-file-list": "In Dokumentenliste", + "displayed-in-file-list": "In Dokumentenliste anzeigen", "filterable": "Filterbar", "name": "Name", "primary": "Primärattribut", @@ -1522,7 +1525,7 @@ }, "last-assignee": "{status, select, APPROVED{Freigegeben} UNDER_APPROVAL{Geprüft} other{Zuletzt geprüft}} von:", "no-data": { - "title": "An dieser Seite wurden keine Änderungen vorgenommen." + "title": "Auf dieser Seite wurden keine Änderungen vorgenommen." }, "quick-nav": { "jump-first": "Zur ersten Seite springen", @@ -1530,7 +1533,7 @@ }, "reanalyse-notification": "Reanalyse starten", "redacted": "Vorschau", - "redacted-tooltip": "Die Vorschau ist eine Vorschau der finalen geschwärzten Version und zeigt nur Schwärzungen. Sie ist nur verfügbar, wenn keine Änderungen oder Reanalysen ausstehen.", + "redacted-tooltip": "Die Vorschau ist eine Vorschau der finalen geschwärzten Version und zeigt nur Schwärzungen.", "standard": "Standard", "standard-tooltip": "Standard zeigt alle Annotationstypen und ermöglicht die Bearbeitung.", "tabs": { @@ -1541,13 +1544,13 @@ "label": "Liste", "no-annotations": "Es sind keine Annotationen vorhanden.", "page-is": "Diese Seite ist", - "reset": "setzen Sie die Filter", + "reset": "Setzen Sie die Filter zurück", "select": "Auswählen", "select-all": "Alle", "select-none": "Keine", "show-skipped": "Ignorierte im Dokument anzeigen", - "the-filters": "zurück.", - "wrong-filters": "Keine Annotationen für die ausgewählte Filterkombination. Bitte ändern Sie die Auswahl oder" + "the-filters": "Filter", + "wrong-filters": "Keine Annotationen für die ausgewählte Filterkombination. Bitte ändern Sie die Auswahl oder setzen die Filter zurück." }, "document-info": { "close": "Datei-Info schließen", @@ -1614,6 +1617,15 @@ "csv": "Die Datei-Attribute wurden erfolgreich aus der hochgeladenen CSV-Datei importiert." } }, + "filter": { + "analysis": "Analyse erforderlich", + "comment": "Kommentare", + "hint": "Nur Hinweise", + "image": "Bilder", + "none": "Keine Annotationen", + "redaction": "Schwärzung", + "updated": "Aktualisiert" + }, "filter-menu": { "filter-options": "Filteroptionen", "filter-types": "Filter", @@ -1623,15 +1635,6 @@ "unseen-pages": "Nur Annotationen auf ungesehenen Seiten", "with-comments": "Nur Annotationen mit Kommentaren" }, - "filter": { - "analysis": "Analyse erforderlich", - "comment": "Kommentare", - "hint": "Nur Hinweise", - "image": "Bilder", - "none": "Keine Annotationen", - "redaction": "Schwärzungen", - "updated": "Aktualisiert" - }, "filters": { "assigned-people": "Bearbeiter", "documents-status": "Dokumentenstatus", @@ -1640,7 +1643,7 @@ "empty": "Leer", "filter-by": "Filter:", "needs-work": "Annotationen", - "people": "Dossier-Mitglieder" + "people": "Dossier-Mitglied(er)" }, "general-config-screen": { "actions": { @@ -1655,7 +1658,7 @@ "auth": "Authentifizierung aktivieren", "change-credentials": "Anmeldedaten ändern", "envelope-from": "Envelope von", - "envelope-from-hint": "Infotext zum Feld „Ausgangsadresse“.", + "envelope-from-hint": "Infotext zum Feld „Envelope von“.", "envelope-from-placeholder": "Envelope-Absenderadresse", "from": "Von", "from-display-name": "Name für Absender", @@ -1910,6 +1913,13 @@ "user-promoted-to-approver": "{user} wurde im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} zum Genehmiger ernannt!", "user-removed-as-dossier-member": "{user} wurde als Mitglied von: {dossierHref, select, null{{dossierName}} other{{dossierName}}} entfernt!" }, + "notifications": { + "button-text": "Benachrichtigungen", + "deleted-dossier": "Gelöschtes Dossier", + "label": "Benachrichtigungen", + "mark-all-as-read": "Alle als gelesen markieren", + "mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren" + }, "notifications-screen": { "category": { "email-notifications": "E-Mail-Benachrichtigungen", @@ -1923,7 +1933,6 @@ "dossier": "Benachrichtigungen zu Dossiers", "other": "Andere Benachrichtigungen" }, - "options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten", "options": { "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen werde", "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Prüfer zugewiesen werde", @@ -1941,6 +1950,7 @@ "USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde", "USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere" }, + "options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten", "schedule": { "daily": "Tägliche Zusammenfassung", "instant": "Sofort", @@ -1948,13 +1958,6 @@ }, "title": "Benachrichtigungseinstellungen" }, - "notifications": { - "button-text": "Benachrichtigungen", - "deleted-dossier": "Gelöschtes Dossier", - "label": "Benachrichtigungen", - "mark-all-as-read": "Alle als gelesen markieren", - "mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren" - }, "ocr": { "confirmation-dialog": { "cancel": "Abbrechen", @@ -2001,34 +2004,14 @@ "previous": "Vorherige" }, "pdf-viewer": { - "header": { - "all-annotations-loaded": "Alle Annotationen geladen", - "compare-button": "Vergleichen", - "layers-panel-button": "Ebenen", - "left-panel-button": "Panel", - "load-all-annotations": "Alle Annotationen laden", - "no-outlines-text": "Keine Gliederung verfügbar", - "no-signatures-text": "In diesem Dokument gibt es keine Unterschriftenfelder", - "outline-multi-select": "Bearbeiten", - "outlines-panel-button": "Gliederung", - "pan-tool-button": "Verschieben", - "rectangle-tool-button": "Bereichsschwärzung", - "rotate-left-button": "Seite nach links drehen", - "rotate-right-button": "Seite nach rechts drehen", - "select-tool-button": "Auswählen", - "signature-panel-button": "Unterschriften", - "thumbnails-panel-button": "Miniaturansicht", - "toggle-layers": "Layout-Raster {active, select, true{deaktivieren} false{aktivieren} other{}}", - "toggle-readable-redactions": "Schwärzungen {active, select, true{wie im finalen Dokument} false{in Vorschau-Farbe} other{}} anzeigen", - "toggle-tooltips": "Tooltips zu Annotationen {active, select, true{deaktivieren} false{aktivieren} other{}}", - "zoom-in-button": "Vergrößern", - "zoom-out-button": "Verkleinern" - }, "text-popup": { "actions": { "search": "Ausgewählten Text suchen" } - } + }, + "toggle-layers": "Layout-Raster {active, select, true{deaktivieren} false{aktivieren} other{}}", + "toggle-readable-redactions": "Schwärzungen {active, select, true{wie im finalen Dokument} false{in Vorschau-Farbe} other{}} anzeigen", + "toggle-tooltips": "Tooltips zu Annotationen {active, select, true{deaktivieren} false{aktivieren} other{}}" }, "permissions-screen": { "dossier": { @@ -2066,16 +2049,16 @@ "warnings-label": "Dialoge und Meldungen", "warnings-subtitle": "„Nicht mehr anzeigen“-Optionen" }, + "processing": { + "basic": "Verarbeitung läuft", + "ocr": "OCR" + }, "processing-status": { "ocr": "OCR", "pending": "Ausstehend", "processed": "Verarbeitet", "processing": "Verarbeitung läuft" }, - "processing": { - "basic": "Verarbeitung läuft", - "ocr": "OCR" - }, "readonly": "Lesemodus", "readonly-archived": "Lesemodus (archiviert)", "redact-text": { @@ -2090,10 +2073,6 @@ "edit-text": "Text bearbeiten", "legal-basis": "Rechtsgrundlage", "options": { - "in-document": { - "description": "", - "label": "" - }, "in-dossier": { "description": "Fügen Sie die Schwärzung zu jedem Dokument in {dossierName} hinzu.", "extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen", @@ -2109,8 +2088,7 @@ "revert-text": "Zurück zu ursprünglicher Auswahl", "type": "Typ", "type-placeholder": "Typ auswählen...", - "unchanged": "Ungeändert", - "value": "" + "unchanged": "Ungeändert" }, "title": "Text schwärzen" } @@ -2134,10 +2112,6 @@ "description-bulk": "", "label": "In diesem Kontext aus dem Dossier entfernen" }, - "in-document": { - "description": "", - "label": "" - }, "in-dossier": { "description": "Annotieren Sie den Begriff in diesem Dossier nicht.", "description-bulk": "", @@ -2178,10 +2152,6 @@ "extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen", "label": "In diesem Kontext aus Dossier entfernen" }, - "in-document": { - "description": "", - "label": "" - }, "in-dossier": { "description": "Der Begriff wird in keinem Dokument dieses Dossiers {type, select, hint{annotiert} other{automatisch geschwärzt}}.", "description-bulk": "Die ausgewählten Begriffe werden in diesem Dossier nicht {type, select, hint{annotiert} other{automatisch geschwärzt}}.", @@ -2324,6 +2294,12 @@ "red-user-admin": "Benutzeradmin", "regular": "regulärer Benutzer" }, + "search": { + "active-dossiers": "Dokumente in aktiven Dossiers", + "all-dossiers": "Alle Dokumente", + "placeholder": "Dokumente durchsuchen...", + "this-dossier": "In diesem Dossier" + }, "search-screen": { "cols": { "assignee": "Bearbeiter", @@ -2347,12 +2323,6 @@ "no-match": "Der Suchbegriff wurde in keinem der Dokumente gefunden.", "table-header": "{length} {length, plural, one{Suchergebnis} other{Suchergebnisse}}" }, - "search": { - "active-dossiers": "Dokumente in aktiven Dossiers", - "all-dossiers": "Alle Dokumente", - "placeholder": "Dokumente durchsuchen...", - "this-dossier": "In diesem Dossier" - }, "seconds": "Sekunden", "size": "Größe", "smtp-auth-config": { @@ -2426,7 +2396,7 @@ }, "label": "Papierkorb", "no-data": { - "title": "Es gibt noch keine gelöschten Elemente." + "title": "Im Papierkorb befinden sich keine gelöschten Elemente." }, "no-match": { "title": "Die ausgewählten Filter treffen auf kein Element zu." @@ -2543,6 +2513,10 @@ "view-as": "Ansicht:", "workflow": "Workflow-Spalten" }, + "viewer-header": { + "all-annotations-loaded": "Alle Annotationen geladen", + "load-all-annotations": "Alle Annotationen laden" + }, "watermark-screen": { "action": { "change-success": "Wasserzeichen wurde aktualisiert.", @@ -2571,10 +2545,6 @@ "orientation": "Textrichtung", "text-label": "Text für Wasserzeichen", "text-placeholder": "Text eingeben" - }, - "pagination": { - "landscape": "Querformat", - "portrait": "Hoch-" } }, "watermarks-listing": { diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index dbfff7087..76cd7ed59 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -265,7 +265,7 @@ "entities": "Entities", "entity-info": "Info", "entity-rule-editor": "Entity rule editor", - "false-positive": "False positive", + "false-positive": "False positives", "false-recommendations": "False recommendations", "file-attributes": "File attributes", "justifications": "Justifications", @@ -643,8 +643,8 @@ "approve-file": { "confirmationText": "Approve anyway", "denyText": "No, cancel", - "question": "Do you still want to approve the {questionLength, plural, one{document} other{documents}}?", - "title": "Approval warning", + "question": "This document contains unseen changes that have been added during the reanalysis.

Do you still want to approve it?", + "title": "Warning!", "warning-reason": { "legal-basis-missing": "Legal basis missing", "pending-changes": "Pending Changes", @@ -946,7 +946,7 @@ }, "dossier-overview": { "approve": "Approve", - "approve-disabled": "File can only be approved once it has been analyzed with the latest set of business rules and terms stored in the system dictionaries.", + "approve-disabled": "File can only be approved once it has been analysed with the latest dictionaries.", "assign-approver": "Assign approver", "assign-me": "Assign to me", "assign-reviewer": "Assign user", @@ -1236,9 +1236,9 @@ "title": "Edit {label}" }, "entries-count": "{count} {count, plural, one{entry} other{entries}}", - "false-positives": "False positives ({count})", - "false-recommendations": "False recommendations ({count})", - "to-redact": "Entries ({count})" + "false-positives": "False positives", + "false-recommendations": "False recommendations", + "to-redact": "To redact" }, "general-info": { "form": { @@ -1290,7 +1290,7 @@ }, "only-here": { "description": "Edit redaction only at this position in this document.", - "label": "Change only here" + "label": "Change type only here" } }, "reason": "Reason", @@ -1547,7 +1547,7 @@ "select-none": "None", "show-skipped": "Show skipped in document", "the-filters": "the filters", - "wrong-filters": "No annotations for the selected filter combination. Please adjust or" + "wrong-filters": "No annotations for the selected filter combination. Please adjust or or reset the filters" }, "document-info": { "close": "Close document info", @@ -1629,12 +1629,12 @@ "hint": "Hints only", "image": "Images", "none": "No annotations", - "redaction": "Redacted", + "redaction": "Redaction", "updated": "Updated" }, "filters": { "assigned-people": "Assignee(s)", - "documents-status": "Documents state", + "documents-status": "Document state", "dossier-state": "Dossier state", "dossier-templates": "Dossier templates", "empty": "Empty", @@ -2166,14 +2166,14 @@ "comment-placeholder": "Add remarks or notes...", "options": { "do-not-recommend": { - "description": "Do not recommend the selected {isImage, select, image{image} other{term}} in any document of this dossier.", - "description-bulk": "Do not recommend the selected {isImage, select, image{images} other{terms}} in any document of this dossier.", + "description": "Do not recommend the selected term in any document of this dossier.", + "description-bulk": "Do not recommend the selected terms in any document of this dossier.", "extraOptionLabel": "Apply to all active and future dossiers", "label": "Remove from dossier" }, "false-positive": { - "description": "Mark this redaction as a false-positive. The {isImage, select, image{image} other{term}} will not be redacted in this dossier if it occurs in the same context.", - "description-bulk": "Mark these redactions as false-positives. The {isImage, select, image{images} other{terms}} will not be redacted in this dossier if they occur in the same context.", + "description": "Mark this redaction as a false-positive. The term will not be redacted in this dossier if it occurs in the same context.", + "description-bulk": "Mark these redactions as false-positives. The terms will not be redacted in this dossier if they occur in the same context.", "extraOptionDescription": "Dossier template access is required to reverse this action. As a regular user you can only reverse it for this dossier.", "extraOptionLabel": "Apply to all active and future dossiers", "label": "Remove from dossier in this context" @@ -2183,15 +2183,15 @@ "label": "Remove from document" }, "in-dossier": { - "description": "Do not {type, select, hint{annotate} other{auto-redact}} the selected {isImage, select, image{image} other{term}} in any document of this dossier.", - "description-bulk": "Do not {type, select, hint{annotate} other{auto-redact}} the selected {isImage, select, image{images} other{terms}} in this dossier.", + "description": "Do not {type, select, hint{annotate} other{auto-redact}} the selected term in any document of this dossier.", + "description-bulk": "Do not {type, select, hint{annotate} other{auto-redact}} the selected terms in this dossier.", "extraOptionLabel": "Apply to all active and future dossiers", "label": "Remove from dossier", "label-bulk": "Remove from dossier" }, "only-here": { - "description": "Do not {type, select, hint{annotate} other{redact}} the {isImage, select, image{image} other{term}} at this position in the current document.", - "description-bulk": "Do not {type, select, hint{annotate} other{redact}} the selected {isImage, select, image{images} other{terms}} at this position in the current document.", + "description": "Do not {type, select, hint{annotate} other{redact}} the term at this position in the current document.", + "description-bulk": "Do not {type, select, hint{annotate} other{redact}} the selected terms at this position in the current document.", "label": "Remove here" } } diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 97bf00f22..448859eef 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -1,11 +1,11 @@ { "accept-recommendation-dialog": { "header": { - "add-to-dictionary": "Add to dictionary", - "request-add-to-dictionary": "Request add to dictionary" + "add-to-dictionary": "Zum Wörterbuch hinzufügen", + "request-add-to-dictionary": "Wörterbucheintrag vorschlagen" } }, - "account-settings": "Account Einstellungen", + "account-settings": "Kontoeinstellungen", "actions": { "all": "Alle", "none": "Keine" @@ -13,23 +13,23 @@ "add-annotation": { "dialog": { "actions": { - "cancel": "Cancel", - "save": "Save" + "cancel": "Abbrechen", + "save": "Speichern" }, "content": { - "comment": "Comment", - "comment-placeholder": "Add remarks or mentions...", - "selected-text": "Selected text:", - "type": "Type", - "type-placeholder": "Select type..." + "comment": "Kommentar", + "comment-placeholder": "Bemerkungen oder Notizen hinzufügen...", + "selected-text": "Ausgewählter Text:", + "type": "Typ", + "type-placeholder": "Typ auswählen..." }, - "title": "Add annotation" + "title": "Annotation hinzufügen" } }, "add-clone-dossier-template": { - "save": "{type, select, clone{Clone} other{Save}}", - "save-and-edit": "{type, select, clone{Clone} other{Save}} and edit", - "title": "{type, select, clone{Clone {dossierTemplateName}} other{Create dossier template}}" + "save": "{type, select, clone{Klonen} other{Speichern}} und bearbeiten", + "save-and-edit": "{type, select, clone{Klonen} other{Speichern}} und bearbeiten", + "title": "{type, select, clone{Klonen {dossierTemplateName}} other{Dossier-Vorlage erstellen}}" }, "add-dossier-dialog": { "actions": { @@ -37,25 +37,25 @@ "save-and-add-members": "Speichern und Team zusammenstellen" }, "errors": { - "dossier-already-exists": "Dieser Dossier-Name ist bereits vergeben!" + "dossier-already-exists": "Dossier-Name bereits vorhanden.\n
  • Befindet sich das gleichnamige Dossier im Papierkorb, können Sie es endgültig löschen, um den Namen erneut zu verwenden.
  • Ist das gleichnamige Dossier aktiv oder archiviert, verwenden Sie bitte einen anderen Namen.
" }, "form": { "description": { "label": "Beschreibung", - "placeholder": "Bitte geben Sie eine Beschreibung ein." + "placeholder": "Bitte eingeben" }, "due-date": "Termin", "name": { "label": "Dossier-Name", - "placeholder": "Geben Sie einen Namen ein." + "placeholder": "Namen eingeben" }, "template": { "label": "Dossier-Vorlage", - "placeholder": "Choose dossier template" + "placeholder": "Dossier-Vorlage auswählen." } }, "header-new": "Dossier erstellen", - "no-report-types-warning": "No report types available. Please contact your administrator." + "no-report-types-warning": "Keine Berichtstypen verfügbar. Bitte wenden Sie sich an Ihren Administrator." }, "add-edit-clone-dossier-template": { "error": { @@ -63,25 +63,25 @@ }, "form": { "apply-updates-default": { - "description": "Apply dictionary updates to all dossiers by default", - "heading": "Entity configuration" + "description": "Neue Wörterbucheinträge standardmäßig für alle Dossiers übernehmen", + "heading": "Konfiguration für Entitäten" }, "description": "Beschreibung", "description-placeholder": "Beschreibung eingeben", "hidden-text": { - "description": "Hidden text is invisible to human readers but can be detected and read by software and machines. For example, the OCR output of scanned documents is stored as hidden text.", - "heading": "Hidden elements in redacted documents", - "title": "Keep hidden text" + "description": "Versteckter Text ist für menschliche Leser nicht sichtbar, kann jedoch von Software und Maschinen erkannt und gelesen werden. Der OCR-Output von gescannten Dokumenten wird beispielsweise als versteckter Text gespeichert.", + "heading": "Versteckte Elemente in geschwärzten Dokumenten", + "title": "Versteckten Text beibehalten" }, "image-metadata": { - "description": "Images in documents might contain additional information as metadata. This could include the creator, the date or the location of the image.", - "title": "Keep image metadata" + "description": "Zusatzinformationen in Form von Metadaten enthalten. Das können u. a. sein: Ersteller, Datum oder Ort des Bilds.", + "title": "Bildmetadaten beibehalten" }, "name": "Name der Dossier-Vorlage", "name-placeholder": "Namen eingeben", "overlapping-elements": { - "description": "Overlapping elements in the document can potentially contain hidden sensitive information. Removing overlapping elements may result in a bigger file size and an increased processing duration.", - "title": "Keep overlapping elements" + "description": "Überlappende Elemente im Dokument können versteckte sensible Informationen enthalten. Durch das Entfernen dieser Elemente können sich die Dateigröße und die Verarbeitungsdauer erhöhen.", + "title": "Überlappende Elemente beibehalten" }, "upload-settings": { "heading": "", @@ -95,25 +95,25 @@ }, "add-edit-component-mapping": { "actions": { - "save": "Save mapping" + "save": "Mapping speichern" }, "dialog": { - "title": "{type, select, add{Add new} edit{Edit} other{}} component mapping" + "title": "{type, select, add{Neues Komponenten-Mapping erstellen} edit{Komponenten-Mapping bearbeiten} other{}}" }, "disabled-file-options": "Re-upload mapping file to change", "form": { - "delimiter": "CSV delimiter", - "delimiter-placeholder": "CSV delimiter", - "encoding-type": "CSV encoding type", - "file": "Mapping file (.csv)", - "name": "Mapping name", - "name-placeholder": "Mapping name", + "delimiter": "CSV-Trennzeichen", + "delimiter-placeholder": "CSV-Trennzeichen", + "encoding-type": "CSV-Kodierung", + "file": "Mapping-Datei (.csv)", + "name": "Name des Mappings", + "name-placeholder": "Name des Mappings", "version": "Version" } }, "add-edit-dossier-attribute": { "error": { - "generic": "Attribut konnte nicht gespeichert werden!" + "generic": "Speichern des Attributs fehlgeschlagen." }, "form": { "label": "Name des Attributs", @@ -126,41 +126,41 @@ }, "add-edit-dossier-state": { "form": { - "color": "HEX color", + "color": "HEX-Farbcode", "color-placeholder": "#", - "name": "Status name", - "name-placeholder": "Enter name", - "rank": "Rank" + "name": "Name des Status", + "name-placeholder": "Namen eingeben", + "rank": "Rang" }, - "save": "Save state", - "success": "Successfully {type, select, edit{updated} create{created} other{}} the dossier state!", - "title": "{type, select, edit{Edit {name}} create{Create} other{}} dossier state" + "save": "Status speichern", + "success": "Dossier-Status {type, select, edit{wurde aktualisiert} create{wurde erstellt} other{}}.", + "title": "{type, select, edit{Dossier-Status {name} bearbeiten} create{Dossier-Status erstellen} other{}}" }, "add-edit-entity": { "form": { - "case-sensitive": "Case-sensitive", - "color": "{type, select, redaction{Annotation} hint{Hint} recommendation{Recommendation} skipped{Skipped annotation} ignored{Ignored hint} other{}} Color", + "case-sensitive": "Groß-/Kleinschreibung beachten", + "color": "Farbe {type, select, redaction{Annotation} hint{Hinweis} recommendation{Empfehlung} skipped{Übersprungene Annotation} ignored{Ignorierter Hinweis} other{}}", "color-placeholder": "#", - "default-reason": "Default reason", - "default-reason-placeholder": "No default reason", - "description": "Description", - "description-placeholder": "Enter description", + "default-reason": "Standardgrund", + "default-reason-placeholder": "Kein Standardgrund", + "description": "Beschreibung", + "description-placeholder": "Beschreibung eingeben", "dossier-dictionary-only": "", - "has-dictionary": "Has dictionary", - "hint": "Hint", + "has-dictionary": "Hat Wörterbuch", + "hint": "Hinweis", "manage-entries-in-dictionary-editor-only": "", - "name": "Display name", - "name-placeholder": "Enter name", - "rank": "Rank", + "name": "Anzeigename", + "name-placeholder": "Name eingeben", + "rank": "Rang", "rank-placeholder": "1000", "redaction": "Annotation", - "technical-name": "Technical name", - "technical-name-hint": "{type, select, edit{Autogenerated based on the initial display name.} create{Autogenerates based on the display name and cannot be edited after saving.} other{}}", + "technical-name": "Technischer Name", + "technical-name-hint": "{type, select, edit{Wird ausgehend vom ersten Anzeigenamen automatisch generiert.} create{Wird ausgehend vom Anzeigenamen generiert und kann nach dem Speichern nicht bearbeitet werden.} other{}}", "template-and-dossier-dictionaries": "" }, "success": { - "create": "Entity added!", - "edit": "Entity updated. Please note that other users need to refresh the browser to see your changes." + "create": "Erfolg: Entität wurde erstellt.", + "edit": "Erfolg: Entität wurde aktualisiert.

Bitten Sie die Benutzer, ihren Browser zu aktualisieren, um die Änderungen zu sehen." } }, "add-edit-file-attribute": { @@ -178,7 +178,7 @@ "type": "Typ" }, "save": "Attribut speichern", - "title": "{type, select, edit{Edit {name}} create{Add New} other{}} Datei-Attribut" + "title": "{type, select, edit{Datei-Attribut {name} bearbeiten} create{Neues Datei-Attribut erstellen} other{}}" }, "add-edit-justification": { "actions": { @@ -190,10 +190,10 @@ "description-placeholder": "Beschreibung eingeben", "name": "Name", "name-placeholder": "Name eingeben", - "reason": "Rechtliche Grundlage", + "reason": "Rechtsgrundlage", "reason-placeholder": "Rechtsgrundlage eingeben" }, - "title": "{type, select, edit{Edit {name}} create{Add New} other{}} Begründung" + "title": "{type, select, edit{Begründung {name} bearbeiten} create{Neue Begründung erstellen} other{}}" }, "add-edit-user": { "actions": { @@ -203,85 +203,87 @@ "save-changes": "Änderungen speichern" }, "error": { - "email-already-used": "Diese E-Mail-Adresse wird bereits von einem anderen Benutzer verwendet!", - "generic": "Benutzer konnte nicht gespeichert werden!" + "email-already-used": "Diese E-Mail-Adresse ist bereits mit einem anderen Benutzer verknüpft.", + "generic": "Speichern des Benutzers fehlgeschlagen." }, "form": { - "account-setup": "User account setup", + "account-setup": "Konfiguration des Benutzerkontos", "email": "E-Mail", "first-name": "Vorname", "last-name": "Nachname", "reset-password": "Passwort zurücksetzen", "role": "Rolle", - "send-email": "Do not send email requesting the user to set a password", - "send-email-explanation": "Select this option if you use SSO. Please note that you will need to inform the user directly." + "send-email": "Benutzer nicht per E-Mail auffordern, ein Passwort festzulegen", + "send-email-explanation": "Wählen Sie diese Option, wenn Sie SSO verwenden. Bitte beachten Sie, dass Sie den Benutzer direkt informieren müssen." }, "title": "{type, select, edit{Benutzer bearbeiten} create{Neuen Benutzer hinzufügen} other{}}" }, "add-entity": { - "save": "Wörterbuch speichern", - "title": "Wörterbuch erstellen" + "save": "Entität speichern", + "title": "Entität erstellen" }, "add-hint": { "dialog": { "actions": { - "cancel": "Cancel", - "save": "Save" + "cancel": "Abbrechen", + "save": "Speichern" }, "content": { - "comment": "Comment", - "comment-placeholder": "Add remarks or mentions...", + "comment": "Kommentar", + "comment-placeholder": "Bemerkungen oder Notizen hinzufügen...", "options": { "in-dossier": { - "description": "Add hint in every document in {dossierName}.", - "extraOptionLabel": "Apply to all dossiers", - "label": "Add hint in dossier" + "description": "Fügen Sie den Hinweis zu jedem Dokument in {dossierName} hinzu.", + "extraOptionLabel": "In alle Dossiers übernehmen", + "label": "Zu Dossier hinzufügen" }, "only-here": { - "description": "Add hint only at this position in this document.", - "label": "Add hint only here" + "description": "Fügen Sie den Hinweis nur an dieser Stelle in diesem Dokument hinzu.", + "label": "Nur hier hinzufügen" } }, - "type": "Type", - "type-placeholder": "Select type...", - "value": "" + "type": "Typ", + "type-placeholder": "Typ auswählen..." }, - "title": "Add hint" + "title": "Hinweis hinzufügen" } }, "admin-side-nav": { - "audit": "Audit", - "component-mappings": "Component mappings", - "component-rule-editor": "Component rule editor", - "components": "Components", - "configurations": "Configurations", - "default-colors": "Default colors", - "dictionary": "Dictionary", - "digital-signature": "Digital signature", - "dossier-attributes": "Dossier attributes", - "dossier-states": "Dossier states", + "audit": "Benutzeraktivitäten", + "component-mappings": "Komponenten-Mappings", + "component-rule-editor": "Komponentenregeln-Editor", + "components": "Komponenten", + "configurations": "Systemkonfiguration", + "default-colors": "Standardfarben", + "dictionary": "Wörterbuch", + "digital-signature": "Digitale Signatur", + "dossier-attributes": "Dossier-Attribute", + "dossier-states": "Dossier-Status", "dossier-template-info": "Info", - "dossier-templates": "Dossier-Vorlage", - "entities": "Entities", + "dossier-templates": "Dossier-Vorlagen", + "entities": "Entitäten", "entity-info": "Info", - "entity-rule-editor": "Entity rule editor", - "false-positive": "False positive", - "false-recommendations": "False recommendations", - "file-attributes": "File attributes", - "justifications": "Justifications", - "license-information": "License Information", - "reports": "Reports", + "entity-rule-editor": "Entitätsregeln-Editor", + "false-positive": "Falsch-Positive", + "false-recommendations": "Falsche Empfehlungen", + "file-attributes": "Datei-Attribute", + "justifications": "Begründungen", + "license-information": "Lizenzinformationen", + "reports": "Berichte", "settings": "Einstellungen", - "user-management": "User Management", - "watermarks": "Watermarks" + "user-management": "Benutzerverwaltung", + "watermarks": "Wasserzeichen" + }, + "analysis-disabled": "Analyse deaktiviert", + "annotation": { + "pending": "(Analyse steht aus)" }, - "analysis-disabled": "Analysis disabled", "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" }, "convert-highlights": { - "label": "Convert Selected Earmarks" + "label": "Ausgewählte Markierungen konvertieren" }, "edit-redaction": { "label": "Edit" @@ -303,41 +305,41 @@ }, "remove": { "error": "Fehler beim Entfernen des Wörterbucheintrags: {error}", - "success": "Wörterbucheintrag wurde gelöscht!" + "success": "Wörterbucheintrag wurde gelöscht" }, "undo": { - "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", - "success": "Rückgängigmachen erfolgreich" + "error": "Rücksetzen der Aktion fehlgeschlagen: {error}", + "success": "Rücksetzung erfolgreich" } }, "manual-redaction": { "add": { - "error": "Fehler beim Speichern der Schwärzung: {error}", - "success": "Schwärzung hinzugefügt!" + "error": "Speichern der Annotation fehlgeschlagen: {error}", + "success": "Annotation hinzugefügt" }, "force-hint": { - "error": "Failed to save hint: {error}", - "success": "Hint added!" + "error": "Speichern des Hinweises fehlgeschlagen: {error}", + "success": "Hinweis hinzugefügt" }, "force-redaction": { - "error": "Die Schwärzung konnte nicht gespeichert werden!", - "success": "Schwärzung eingefügt!" + "error": "Speichern der Annotation fehlgeschlagen: {error}", + "success": "Annotation hinzugefügt" }, "recategorize-annotation": { "error": "", "success": "" }, "recategorize-image": { - "error": "Rekategorisierung des Bildes gescheitert: {error}", + "error": "Rekategorisierung des Bilds fehlgeschlagen: {error}", "success": "Bild wurde einer neuen Kategorie zugeordnet." }, - "remove-hint": { - "error": "Failed to remove hint: {error}", - "success": "Hint removed!" - }, "remove": { - "error": "Fehler beim Entfernen der Schwärzung: {error}", - "success": "Schwärzung entfernt!" + "error": "Entfernen der Annotation fehlgeschlagen: {error}", + "success": "Annotation wurde entfernt" + }, + "remove-hint": { + "error": "Entfernen des Hinweises fehlgeschlagen: {error}", + "success": "Hinweis wurde entfernt" }, "undo": { "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", @@ -346,20 +348,20 @@ } }, "remove-annotation": { - "remove-redaction": "Remove" + "remove-redaction": "Entfernen" }, "remove-highlights": { - "label": "Remove selected earmarks" - }, - "resize-accept": { - "label": "Größe speichern" - }, - "resize-cancel": { - "label": "Größenänderung abbrechen" + "label": "Ausgewählte Markierungen entfernen" }, "resize": { "label": "Größe ändern" }, + "resize-accept": { + "label": "Neue Größe speichern" + }, + "resize-cancel": { + "label": "Größenänderung abbrechen" + }, "see-references": { "label": "See references" }, @@ -367,61 +369,57 @@ "undo": "Rückgängig" }, "annotation-changes": { - "added-locally": "Added locally", - "forced-hint": "Hint forced", - "forced-redaction": "Annotation forced", + "added-locally": "Lokal hinzugefügt", + "forced-hint": "Hinweis wurde erzwungen", + "forced-redaction": "Annotation wurde erzwungen", "header": "Manuelle Änderungen:", "legal-basis": "Grund geändert", "recategorized": "Bildkategorie geändert", "removed-manual": "Schwärzung/Hinweis entfernt", "resized": "Schwärzungsbereich wurde geändert" }, - "annotation-content": "{hasRule, select, true {Regel {matchedRule} trifft zu auf{ruleSymbol}} other {}} {hasReason, select, true {{reason}} other {}} {hasLb, select, true {Rechstgrundlage: {legalBasis}} other {}} {hasOverride, select, true {Entfernt durch manuelles Überschreiben} other {}} {hasSection, select, true {{shouldLower, plural, =0 {I} other {i}}n Abschnitt{sectionSymbol} \"{section}\"} other {}}", "annotation-engines": { - "dictionary": "{isHint, select, true{Hint} other{Redaction}} basierend auf Wörterbuch", - "dossier-dictionary": "Annotation based on dossier dictionary", - "imported": "Annotation is imported", + "dictionary": "{isHint, select, true{Hinweis} other{Schwärzung}} basiert auf Wörterbuch", + "dossier-dictionary": "Annotation basiert auf Dossier-Wörterbuch", + "imported": "Annotation ist importiert", "ner": "Redaktion basierend auf KI", "rule": "Schwärzung basierend auf Regel {rule}" }, "annotation-type": { "hint": "Hinweis", "ignored-hint": "Ignorierter Hinweis", - "manual-hint": "Manual hint", + "manual-hint": "Manueller Hinweis", "manual-redaction": "Manuelle Schwärzung", "recommendation": "Empfehlung", - "redaction": "Schwärzung", + "redaction": "Annotation", "skipped": "Übersprungen", - "text-highlight": "Earmark" + "text-highlight": "Markierung" }, - "annotation": { - "pending": "(Pending analysis)" - }, - "annotations": "Annotations", + "annotations": "Annotationen", "archived-dossiers-listing": { "no-data": { - "title": "No archived dossiers." + "title": "Keine archivierten Dossiers." }, "no-match": { - "title": "No archived dossiers match your current filters." + "title": "Keines der archivierten Dossiers entspricht den ausgewählten Filtern." }, "table-col-names": { - "dossier-state": "Dossier state", - "last-modified": "Archiving time", + "dossier-state": "Dossier-Status", + "last-modified": "Archiviert am", "name": "Name", - "owner": "Owner" + "owner": "Besitzer" }, "table-header": { - "title": "{length} Archived {length, plural, one{dossier} other{dossiers}}" + "title": "{length} {length, plural, one{archiviertes Dossier} other{archivierte Dossiers}}" } }, "assign-dossier-owner": { "dialog": { - "approver": "Approver", - "approvers": "Genehmiger", + "approver": "Genehmiger", + "approvers": "Dossier-Mitglieder", "make-approver": "Zum Genehmiger ernennen", - "no-reviewers": "Es gibt noch keine Reviewer.\nBitte aus der Liste unten auswählen.", - "reviewers": "Reviewer", + "no-reviewers": "Es wurden noch keine Mitglieder zum Dossier hinzugefügt, die nur die Prüfer-Berechtigung haben.", + "reviewers": "Prüfer", "search": "Suche ...", "single-user": "Besitzer" } @@ -440,7 +438,7 @@ }, "assignment": { "owner": "{ownerName} wurde erfolgreich zum Dossier {dossierName} hinzugefügt.", - "reviewer": "{reviewerName} wurde erfolgreich zum Dokument {filename} hinzugefügt." + "reviewer": "{reviewerName} wurde dem Dokument {filename} erfolgreich zugewiesen." }, "audit": "Aktivitätenprotokoll", "audit-screen": { @@ -449,11 +447,11 @@ }, "all-users": "Alle Benutzer", "audit-info-dialog": { - "title": "Audit info" + "title": "Benutzeraktivitäten" }, "categories": { "all-categories": "Alle Bereiche", - "audit": "Aktivitätenprotokoll", + "audit": "Benutzeraktivitäten", "audit-log": "Aktivitätenprotokoll", "dictionary": "Wörterbuch", "document": "Dokument", @@ -463,28 +461,28 @@ "license": "Lizenz", "project": "Projekt", "project-template": "Projekt-Vorlage", - "settings": "Settings", - "user": "Nutzer" + "settings": "Einstellungen", + "user": "Benutzer" }, "no-data": { - "title": "Keine Protokolle verfügbar." + "title": "Keine Aktivitäten vorhanden." }, "table-col-names": { "category": "Kategorie", "date": "Datum", - "message": "Nachricht", - "user": "Nutzer" + "message": "Aktivität", + "user": "Benutzer" }, "table-header": { - "title": "{length} {length, plural, one{log} other{logs}}" + "title": "{length} {length, plural, one{Aktivität} other{Aktivitäten}}" }, "to": "bis" }, "auth-error": { - "heading": "Ihr Benutzer verfügt nicht über die erforderlichen RED-*-Rollen, um auf diese Applikation zugreifen zu können. Bitte kontaktieren Sie Ihren Admin, um den Zugang anzufordern!", - "heading-with-link": "Ihr Benutzer verfügt nicht über die erforderlichen RED-*-Rollen, um auf diese Applikation zugreifen zu können. Bitte kontaktieren Sie Ihren Admin, um den Zugang anzufordern!", - "heading-with-name": "Ihr Benutzer verfügt nicht über die erforderlichen RED-*-Rollen, um auf diese Applikation zugreifen zu können. Bitte kontaktieren Sie {adminName}, um den Zugang anzufordern!", - "heading-with-name-and-link": "Ihr Benutzer verfügt nicht über die erforderlichen RED-*-Rollen, um auf diese Applikation zugreifen zu können. Bitte kontaktieren Sie {adminName}, um den Zugang anzufordern!", + "heading": "Sie haben sich erfolgreich eingeloggt, können aber nicht auf die Applikation zugreifen, da Ihnen keine Rolle zugewiesen ist. Bitten Sie Ihren Admin, Ihnen eine Rolle zuzuweisen.", + "heading-with-link": "Sie haben sich erfolgreich eingeloggt, aber Ihrem Benutzer ist noch keine Rolle zugewiesen. Bitten Sie Ihren RedactManager-Admin Ihnen eine Rolle zuzuweisen.", + "heading-with-name": "Sie haben sich erfolgreich eingeloggt, aber Ihnen ist noch keine Rolle zugewiesen. Bitten Sie {adminName}, Ihnen eine Rolle zuzuweisen.", + "heading-with-name-and-link": "Sie haben sich erfolgreich eingeloggt, aber Ihnen ist noch keine Rolle zugewiesen. Bitten Sie {adminName}, Ihnen eine Rolle zuzuweisen.", "logout": "Ausloggen" }, "change-legal-basis-dialog": { @@ -496,17 +494,17 @@ "classification": "Wert / Klassifizierung", "comment": "Kommentar", "legalBasis": "Rechtsgrundlage", - "reason": "Begründung für die Schwärzung auswählen", - "reason-placeholder": "Wählen Sie eine Begründung aus ...", - "section": "Absatz / Ort" + "reason": "Schwärzungsgrund auswählen", + "reason-placeholder": "Grund auswählen ...", + "section": "Absatz / Textstelle" }, - "header": "Begründung für die Schwärzung bearbeiten" + "header": "Schwärzungsgrund bearbeiten" }, - "color": "Color", + "color": "Farbe", "comments": { "add-comment": "Kommentar eingeben", - "comments": "{count} {count, plural, one{comment} other{comments}}", - "hide-comments": "Kommentare verbergen" + "comments": "{count} {count, plural, one{Kommentar} other{Kommentare}}", + "hide-comments": "Kommentare ausblenden" }, "common": { "close": "Ansicht schließen", @@ -519,198 +517,198 @@ }, "component-definitions": { "actions": { - "revert": "Revert", - "save": "Save Changes" + "revert": "Zurücksetzen", + "save": "Änderungen speichern" }, - "add-new": "New component", - "add-title": "Add new definition", + "add-new": "Neue Komponente", + "add-title": "Neue Definition hinzufügen", "columns": { - "name": "name", - "position": "pos." + "name": "Name", + "position": "Pos." }, - "edit-title": "Edit {displayName} definition", + "edit-title": "Definition von {displayName} bearbeiten", "form": { - "autogenerated-label": "Autogenerated based on the initial display name", - "description": "Description", - "description-placeholder": "Description", - "display-name": "Display Name", - "display-name-placeholder": "Display Name", - "technical-name-label": "Technical name" + "autogenerated-label": "Wird ausgehend vom ersten Anzeigenamen automatisch generiert.", + "description": "Beschreibung", + "description-placeholder": "Beschreibung", + "display-name": "Anzeigename", + "display-name-placeholder": "Anzeigename", + "technical-name-label": "Technischer Name" }, - "title": "{length} {length, plural, one{component} other{components}}" + "title": "{length} {length, plural, one{Komponente} other{Komponenten}}" }, "component-download": { - "json": "Components as JSON", - "report": "Report", - "xml": "Components as XML" + "json": "Komponente als JSON", + "report": "Bericht", + "xml": "Komponente als XML" }, "component-management": { "actions": { - "add": "Add", - "cancel": "Cancel", - "delete": "Remove value", - "edit": "Edit", - "save": "Save", - "undo": "Undo" + "add": "Hinzufügen", + "cancel": "Abbrechen", + "delete": "Wert entfernen", + "edit": "Bearbeiten", + "save": "Speichern", + "undo": "Zurücksetzen" }, - "components": "Components", + "components": "Komponenten", "table-header": { - "component": "Component", - "value": "Value" + "component": "Komponente", + "value": "Wert" } }, "component-mappings-screen": { "action": { - "delete": "Delete mapping", - "download": "Download mapping", - "edit": "Edit mapping" + "delete": "Mapping löschen", + "download": "Mapping herunterladen", + "edit": "Mapping bearbeiten" }, - "add-new": "New mapping", + "add-new": "Neues Mapping", "no-data": { - "action": "New mapping", - "title": "There are no component mappings." + "action": "Neues Mapping", + "title": "Es gibt noch keine Komponent-Mappings." }, - "search": "Search by name...", + "search": "Nach Name suchen...", "table-col-names": { - "column-labels": "Column labels", - "name": "name", - "number-of-lines": "Number of lines", - "version": "version" + "column-labels": "Spaltenbeschriftungen", + "name": "Name", + "number-of-lines": "Zeilenzahl", + "version": "Version" }, "table-header": { - "title": "Component mapping" + "title": "Komponenten-Mapping" } }, "component-rules-screen": { "error": { - "generic": "Something went wrong... Component rules update failed!" + "generic": "Es ist ein Fehler aufgetreten ... Die Komponentenregeln konnte nicht aktualisiert werden!" }, - "errors-found": "{errors, plural, one{An error} other{{errors} errors}} found in rules", - "revert-changes": "Revert", - "save-changes": "Save changes", + "errors-found": "{errors, plural, one{An error}andere{{errors} Fehler}} in den Regeln gefunden", + "revert-changes": "Zurücksetzen", + "save-changes": "Änderungen speichern", "success": { - "generic": "Component rules updated!" + "generic": "Komponentenregeln aktualisiert!" }, - "title": "Component rule editor" + "title": "Komponentenregeln-Editor" }, "configurations": "Einstellungen", "confirm-archive-dossier": { - "archive": "Archive dossier", - "cancel": "Cancel", + "archive": "Dossier archivieren", + "cancel": "Abbrechen", "checkbox": { - "documents": "All documents will be archived and cannot be put back to active" + "documents": "Alle Dokumente werden archiviert und können nicht in den aktiven Status zurückversetzt werden." }, - "details": "Restoring an archived dossier is not possible anymore, once it got archived.", - "title": "Archive {dossierName}", - "toast-error": "Please confirm that you understand the ramifications of your action!", - "warning": "Are you sure you want to archive the dossier?" + "details": "Beachten Sie, dass die Archivierung irreversibel ist. Sie können archivierte Dokumente nicht bearbeiten.", + "title": "{dossierName} archivieren", + "toast-error": "Bitte bestätigen Sie, dass Sie die Folgen dieser Aktion verstehen.", + "warning": "Möchten Sie das Dossier wirklich archivieren?" }, "confirm-delete-attribute": { - "cancel": "Keep {count, plural, one{attribute} other{attributes}}", - "delete": "Delete {count, plural, one{attribute} other{attributes}}", - "dossier-impacted-documents": "All dossiers based on this template will be affected", - "dossier-lost-details": "All values for this attribute will be lost", - "file-impacted-documents": "All documents {count, plural, one{it is} other{they are}} used on will be impacted", - "file-lost-details": "All inputted details on the documents will be lost", - "impacted-report": "{reportsCount}", - "title": "Delete {count, plural, one{{name}} other{file attributes}}", - "toast-error": "Bitte bestätigen Sie, dass Ihnen die Konsequenzen dieser Aktion bewusst sind!", - "warning": "Achtung: Diese Aktion kann nicht rückgängig gemacht werden!" + "cancel": "{count, plural, one{Attribut} other{Attribute}} beibehalten", + "delete": "{count, plural, one{Attribut} other{Attribute}} löschen", + "dossier-impacted-documents": "Diese Aktion hat Folgen für alle Dossiers, die diese Vorlage verwenden.", + "dossier-lost-details": "Die von Benutzern auf Dokumentebene eingegebenen Attributwerte gehen verloren.", + "file-impacted-documents": "Alle Dokumente, die {count, plural, one{dieses Attribut} other{diese Attribute}} verwenden, sind von der Aktion betroffen.", + "file-lost-details": "Die von Benutzern auf Dokumentebene eingegebenen Informationen gehen verloren.", + "impacted-report": "{reportsCount} Berichte nutzen den Platzhalter dieses Attributs. Bitte aktualisieren Sie diese.", + "title": "{count, plural, one{Attribut} other{Attribute}} löschen", + "toast-error": "Bitte bestätigen Sie, dass die Folgen dieser Aktion verstehen.", + "warning": "Warnung: Wiederherstellung des Attributs nicht möglich." }, "confirm-delete-dossier-state": { - "cancel": "Cancel", - "delete": "Delete", - "delete-replace": "Delete and replace", + "cancel": "Abbrechen", + "delete": "Löschen", + "delete-replace": "Löschen und ersetzen", "form": { - "state": "Replace state", - "state-placeholder": "Choose another state" + "state": "Status ersetzen", + "state-placeholder": "Anderen Status auswählen" }, - "question": "Replace the {count, plural, one{dossier's} other{dossiers'}} state with another state", - "success": "Successfully deleted state!", - "title": "Delete dossier state", - "warning": "The {name} state is assigned to {count} {count, plural, one{dossier} other{dossiers}}." + "question": "Wählen Sie einen Status aus, um den aktuellen {count, plural, one{Dossierstatus} other{Dossierstatus}} zu ersetzen", + "success": "Der Status wurde erfolgreich gelöscht", + "title": "Dossier-Status löschen", + "warning": "Der Status {name} ist {count} {count, plural, one{Dossier} other{Dossiers}} zugewiesen." }, "confirm-delete-users": { - "cancel": "Keep {usersCount, plural, one{user} other{users}}", - "delete": "Delete {usersCount, plural, one{user} other{users}}", - "impacted-documents": "All documents pending review from the {usersCount, plural, one{user} other{users}} will be impacted", - "impacted-dossiers": "{dossiersCount} {dossiersCount, plural, one{dossier} other{dossiers}} will be impacted", - "title": "Delete {usersCount, plural, one{user} other{users}} from workspace", - "toast-error": "Bitte bestätigen Sie, dass Ihnen die Konsequenzen dieser Aktion bewusst sind!", - "warning": "Achtung: Diese Aktion kann nicht rückgängig gemacht werden!" + "cancel": "{usersCount, plural, one{Benutzer} other{Benutzer}} behalten", + "delete": "{usersCount, plural, one{Benutzer} other{Benutzer}} löschen", + "impacted-documents": "Alle Dokumente betroffen, deren Review durch {usersCount, plural, one{den Benutzer} other{die Benutzer}} noch aussteht", + "impacted-dossiers": "{dossiersCount} {dossiersCount, plural, one{Dossier} other{Dossiers}} sind betroffen", + "title": "{usersCount, plural, one{Benutzer} other{Benutzer}} aus Workspace entfernen", + "toast-error": "Bitte bestätigen Sie, dass Sie die Folgen dieser Aktion verstehen.", + "warning": "Warnung: Wiederherstellung des Benutzers nicht möglich." }, "confirmation-dialog": { "approve-file": { - "confirmationText": "Approve anyway", - "denyText": "No, cancel", - "question": "Do you still want to approve the {questionLength, plural, one{document} other{documents}}?", - "title": "Approval warning", + "confirmationText": "Trotzdem genehmigen", + "denyText": "Nein, abbrechen", + "question": "Dieses Dokument enthält ungesehene Änderungen, die sich durch die Reanalyse ergeben haben.

Möchten Sie es trotzdem freigeben?", + "title": "Warnung!", "warning-reason": { - "legal-basis-missing": "Legal basis missing", - "pending-changes": "Pending Changes", - "unmapped-justification": "Unmapped justification" + "legal-basis-missing": "Rechtsgrundlage fehlt", + "pending-changes": "Änderungen stehen aus", + "unmapped-justification": "Nicht gemappte Begründung" } }, "assign-file-to-me": { "question": { "multiple": "Dieses Dokument wird gerade von einer anderen Person geprüft. Möchten Sie Reviewer werden und sich selbst dem Dokument zuweisen?", - "single": "This document is currently assigned to someone else. Are you sure you want to replace it and assign yourself to this document?" + "single": "Dieses Dokument ist aktuell einem anderen Benutzer zugewiesen. Möchten Sie es sich dennoch selbst zuweisen?" }, - "title": "Neuen Reviewer zuweisen" + "title": "Anderen Benutzer zuweisen" }, "compare-file": { - "question": "Achtung!

Seitenzahl stimmt nicht überein, aktuelles Dokument hat {currentDocumentPageCount} Seite(n). Das hochgeladene Dokument hat {compareDocumentPageCount} Seite(n).

Möchten Sie fortfahren?", + "question": "Warnung: Seitenzahl stimmt nicht überein

Aktuelles Dokument: {currentDocumentPageCount} Seite(n).

Hochgeladenes Dokument: {compareDocumentPageCount} Seite(n).

Es scheint sich um ein anderes Dokument zu handeln. Möchten Sie fortfahren?", "title": "Vergleichen mit: {fileName}" }, "delete-dossier": { - "confirmation-text": "Delete {dossiersCount, plural, one{dossier} other{dossiers}}", - "deny-text": "Keep {dossiersCount, plural, one{dossier} other{dossiers}}", - "question": "Are you sure you want to delete {dossiersCount, plural, one{this dossier} other{these dossiers}}?", - "title": "Delete {dossiersCount, plural, one{{dossierName}} other{Selected Dossiers}}" + "confirmation-text": "{dossiersCount, plural, one{Dossier} other{Dossiers}} löschen", + "deny-text": "{dossiersCount, plural, one{Dossier} other{Dossiers}} behalten", + "question": "Möchten Sie {dossiersCount, plural, one{dieses Dossier} other{diese Dossiers}} wirklich löschen?", + "title": "{dossiersCount, plural, one{{dossierName}} other{selected dossiers}} löschen" }, "delete-file": { "question": "Möchten Sie fortfahren?", "title": "Dokument löschen" }, "delete-items": { - "question": "Are you sure you want to delete {itemsCount, plural, one{this item} other{these items}}?", - "title": "Delete {itemsCount, plural, one{{name}} other{Selected Items}}" + "question": "Möchten Sie {itemsCount, plural, one{dieses Element} other{diese Elemente}} wirklich löschen?", + "title": "{itemsCount, plural, one{{name}} other{Selected Items}} löschen" }, "delete-justification": { - "question": "Are you sure you want to delete {count, plural, one{this justification} other{these justifications}}?", - "title": "Delete {count, plural, one{{justificationName}} other{selected justifications}}" + "question": "Möchten Sie {count, plural, one{diese Begründung} other{diese Begründungen}} wirklich löschen?", + "title": "{count, plural, one{{justificationName}} other{selected justifications}} löschen" }, "input-label": "Bitte geben Sie unten Folgendes ein, um fortzufahren", "report-template-same-name": { - "confirmation-text": "Ja. Hochladen fortsetzen", - "deny-text": "Nein. Hochladen abbrechen", - "question": "{fileName}", - "title": "Hochladen von Berichtsvorlagen" + "confirmation-text": "Ja. Upload fortsetzen", + "deny-text": "Nein. Upload abbrechen", + "question": "Es gibt bereits eine Berichtsvorlage mit dem Namen: {fileName}. Möchten Sie dennoch fortfahren?", + "title": "Vorlagen-Upload" }, "unsaved-changes": { - "confirmation-text": "Save and leave", - "details": "If you leave the tab without saving, all the unsaved changes will be lost.", - "discard-changes-text": "DISCARD CHANGES", - "question": "Are you sure you want to leave the tab? You have unsaved changes.", - "title": "You have unsaved changes" + "confirmation-text": "Speichern und schließen", + "details": "Wenn Sie den Tab jetzt verlassen, gehen alle ungespeicherten Änderungen verloren. Bitte speichern Sie Ihre Änderungen. ", + "discard-changes-text": "ÄNDERUNGEN VERWERFEN", + "question": "Möchten Sie den Tab dennoch schließen?", + "title": "Sie haben ungespeicherte Änderungen" }, "upload-report-template": { "alternate-confirmation-text": "Als Bericht für mehrere Dokumente hochladen", "confirmation-text": "Als Bericht für ein Dokument hochladen", "deny-text": "Uploads abbrechen", - "question": "Wählen Sie bitte aus, ob {fileName} eine Berichtsvorlage für eine oder für mehrere Dateien ist", - "title": "Upload der Berichtsvorlage" + "question": "Geben Sie bitte an, ob {fileName} eine Berichtsvorlage für eine oder für mehrere Dateien ist", + "title": "Vorlagen-Upload" } }, - "content": "Begründung", + "content": "Grund", "dashboard": { "empty-template": { - "description": "This template does not contain any dossiers. Start by creating a dossier to use it on.", - "new-dossier": "New dossier" + "description": "Diese Vorlage enthält keine Dossiers. Erstellen Sie ein Dossier, um nach diesen Regeln zu schwärzen.", + "new-dossier": "Neues Dossier" }, "greeting": { - "subtitle": "Here's what's happening in your teams today.", - "title": "Welcome, {name}!" + "subtitle": "Hier findest du deine Dossier-Vorlagen im Überblick.", + "title": "Wilkommen, {name}!" } }, "default-colors-screen": { @@ -722,20 +720,20 @@ "key": "Typ" }, "table-header": { - "title": "{length} default {length, plural, one{color} other{colors}}" + "title": "{length} Standard{length, plural, one{Farbe} other{Farben}}" }, "types": { "analysisColor": "Analyse", - "appliedRedactionColor": "Applied redaction", - "dictionaryRequestColor": "Wörterbuch", - "hintColor": "Hint", + "appliedRedactionColor": "Schwärzung im finalen Dokument", + "dictionaryRequestColor": "Vorschlag für Wörterbuch", + "hintColor": "Hinweis", "ignoredHintColor": "Ignorierter Hinweis", "previewColor": "Vorschau", - "recommendationColor": "Recommendation", - "redactionColor": "Annotation color", - "requestAdd": "Neuen Wörterbucheintrag vorschlagen", - "requestRemove": "Anfrage entfernt", - "skippedColor": "Skipped", + "recommendationColor": "Empfehlung", + "redactionColor": "Anmerkung", + "requestAdd": "Vorschlag für Wörterbucheintrag", + "requestRemove": "Vorschlag für Entfernung", + "skippedColor": "Ignorierte Schwärzung", "updatedColor": "Aktualisiert" } }, @@ -759,7 +757,7 @@ "system-default": "", "title": "" }, - "dictionary": "Wörterbuch", + "dictionary": "Typ", "dictionary-overview": { "compare": { "compare": "Vergleichen", @@ -767,88 +765,88 @@ "select-dossier": "Dossier auswählen", "select-dossier-template": "Dossiervorlage auswählen" }, - "download": "Download current entries", + "download": "Aktuelle Einträge herunterladen", "error": { - "400": "Cannot update dictionary because at least one of the newly added words where recognized as a general term that appear too often in texts.", - "generic": "Es ist ein Fehler aufgetreten ... Das Wörterbuch konnte nicht aktualisiert werden!" + "400": "Die Aktualisierung des Wörterbuchs ist fehlgeschlagen.

Mindestens einer der neu hinzugefügten Begriffe wurde als häufig verwendeter allgemeiner Begriff identifiziert. Bitte entfernen Sie die betreffenden Begriffe, um mit der Aktualisierung fortzufahren.", + "generic": "Fehler: Aktualisierung des Wörterbuchs fehlgeschlagen." }, - "revert-changes": "Rückgängig machen", + "revert-changes": "Zurücksetzen", "save-changes": "Änderungen speichern", "search": "Suche ...", - "select-dictionary": "Wählen Sie oben das Wörterbuch aus, das Sie mit dem aktuellen Wörterbuch vergleichen möchten.", + "select-dictionary": "Wählen Sie oben ein Wörterbuch für den Vergleich aus.", "success": { - "generic": "Wörterbuch aktualisiert!" + "generic": "Wörterbuch wurde aktualisiert" } }, "digital-signature": "Digitale Signatur", "digital-signature-dialog": { "actions": { - "back": "Back", - "cancel": "Cancel", - "certificate-not-valid-error": "Uploaded certificate is not valid!", - "continue": "Continue", - "save": "Save configurations", - "save-error": "Failed to save digital signature!", - "save-success": "Digital signature certificate successfully saved!" + "back": "Zurück", + "cancel": "Abbrechen", + "certificate-not-valid-error": "Das hochgeladene Zertifikat ist ungültig.", + "continue": "Weiter", + "save": "Konfiguration speichern", + "save-error": "Speichern der digitalen Signatur fehlgeschlagen.", + "save-success": "Das Zertifikat für die digitale Signatur wurde erfolgreich gespeichert." }, "forms": { "kms": { - "certificate-content": "Certificate content", - "certificate-name": "Certificate name", - "kms-access-key": "KMS access key", + "certificate-content": "Inhalt des Zertifikats", + "certificate-name": "Name des Zertifikats", + "kms-access-key": "KMS Access Key", "kms-id": "KMS ID", - "kms-region": "KMS region", - "kms-secret-key": "KMS secret key", - "kms-service-endpoint": "KMS service endpoint" + "kms-region": "KMS Region", + "kms-secret-key": "KMS Secret Key", + "kms-service-endpoint": "KMS Service Endpoint" }, "pkcs": { - "certificate-name": "Certificate name", - "contact-information": "Contact information", - "location": "Location", - "password-key": "Password key", - "reason": "Reason" + "certificate-name": "Name des Zertifikats", + "contact-information": "Kontaktinformation", + "location": "Ort", + "password-key": "Passwortschlüssel", + "reason": "Grund" } }, "options": { "kms": { - "description": "Provide a corresponding PEM file containing the certificate, along with Amazon KMS credentials needed for securing the private key.", - "label": "I use an Amazon KMS private key" + "description": "Bitte laden Sie eine PEM-Datei mit dem Zertifikat hoch und geben Sie die Amazon KMS-Anmeldedaten an, um den privaten Schlüssel zu sichern.", + "label": "Ich verwende einen Amazon KMS Private Key" }, "pkcs": { - "description": "A PKCS#12 file is a file that bundles the private key and the X.509 certificate. The password protection is required to secure the private key. Unprotected PKCS#12 files are not supported.", - "label": "I want to upload a PKCS#12 file" + "description": "Eine PKCS#12-Datei kombiniert Ihren privaten Schlüssel mit einem X.509-Zertifikat. Der Passwortschutz ist unerlässlich, um den privaten Schlüssel zu sichern, da ungeschützte PKCS#12-Dateien nicht unterstützt werden.", + "label": "Ich möchte eine PKCS#12-Datei hochladen" } }, "title": { - "before-configuration": "Configure digital signature certificate", - "kms": "Configure a certificate with Amazon KMS", - "pkcs": "Configure a PKCS#12 certificate" + "before-configuration": "Zertifikat für digitale Signatur konfigurieren", + "kms": "Zertifikat mit Amazon KMS konfigurieren", + "pkcs": "PKCS#12-Zertifikat konfigurieren" }, - "upload-warning-message": "To configure the certificate, you first need to upload it." + "upload-warning-message": "Um das Zertifikat zu konfigurieren, müssen Sie es zunächst hochladen." }, "digital-signature-screen": { "action": { - "delete-error": "Die digitale Signatur konnte nicht entfernt werden, bitte versuchen Sie es erneut.", - "delete-success": "Die digitale Signatur wurde gelöscht. Geschwärzte Dateien werden nicht länger mit einer Signatur versehen!", - "remove": "Remove", - "save": "Digitale Signatur speichern", - "save-error": "Failed to save digital signature!", - "save-success": "Digital signature certificate successfully saved!" + "delete-error": "Speichern der digitalen Signatur fehlgeschlagen. Bitte versuchen Sie es noch einmal.", + "delete-success": "Die digitale Signatur wurde gelöscht. Geschwärzte Dateien werden nicht länger mit einer Signatur versehen.", + "remove": "Entfernen", + "save": "Änderungen speichern", + "save-error": "Speichern der digitalen Signatur fehlgeschlagen.", + "save-success": "Das Zertifikat für die digitale Signatur wurde erfolgreich gespeichert." }, "no-data": { - "action": "Zertifikat hochladen", - "title": "Es ist kein Zertifikat für die digitale Signatur konfiguriert. Laden Sie ein PCKS#12-Zertifikat hoch, um Ihre geschwärzten Dokumente zu signieren." + "action": "Zertifikat konfigurieren", + "title": "Es ist kein Zertifikat für die digitale Signatur konfiguriert.
Laden Sie ein Zertifikat hoch, um geschwärzte Dokumente zu signieren." } }, "document-info": { - "save": "Dokumenteninformation speichern", - "title": "Datei-Attribute anlegen" + "save": "Datei-Info speichern", + "title": "Datei-Attribute eingeben" }, "documine-export": { - "document": "Document", - "document-tooltip": "Document", - "export": "Component download", - "export-tooltip": "Component download" + "document": "Dokument", + "document-tooltip": "Dokument", + "export": "Komponenten-Download", + "export-tooltip": "Komponenten-Download" }, "dossier-attribute-types": { "date": "Datum", @@ -874,35 +872,35 @@ }, "search": "Suche ...", "table-col-names": { - "label": "Label", + "label": "Name", "placeholder": "Platzhalter", "type": "Typ" }, "table-header": { - "title": "{length} dossier {length, plural, one{attribute} other{attributes}}" + "title": "{length} {length, plural, one{Dossier-Attribut} other{Dossier-Attribute}}" } }, "dossier-details": { "assign-members": "Mitglieder zuweisen", "collapse": "Details ausblenden", - "document-status": "Document status", + "document-status": "Verarbeitungsstatus der Dokumente", "edit-owner": "Eigentümer bearbeiten", "expand": "Details zeigen", "members": "Mitglieder", - "owner": "Eigentümer", + "owner": "Besitzer", "see-less": "Weniger anzeigen", "title": "Dossier-Details" }, "dossier-listing": { "add-new": "Neues Dossier", "archive": { - "action": "Archive dossier", - "archive-failed": "Failed to archive dossier {dossierName}!", - "archive-succeeded": "Successfully archived dossier {dossierName}." + "action": "Dossier archivieren", + "archive-failed": "Archivierung des Dossiers {dossierName} fehlgeschlagen.", + "archive-succeeded": "Das Dossier {dossierName} wurde erfolgreich archiviert." }, "delete": { "action": "Dossier löschen", - "delete-failed": "Das Dossier {dossierName} konnte nicht gelöscht werden" + "delete-failed": "Löschen des Dossiers {dossierName} fehlgeschlagen." }, "dossier-info": { "action": "Dossier-Info" @@ -911,8 +909,8 @@ "action": "Dossier bearbeiten" }, "filters": { - "label": "Dossiername", - "search": "Dossiername..." + "label": "Dossier-Name", + "search": "Dossier-Namen eingeben..." }, "no-data": { "action": "Neues Dossier", @@ -922,34 +920,34 @@ "title": "Die ausgewählten Filter treffen auf kein Dossier zu." }, "quick-filters": { - "member": "Dossier member", - "owner": "Dossier owner" + "member": "Dossier-Mitglied", + "owner": "Dossier-Besitzer" }, "reanalyse": { - "action": "Gesamtes Dossier analysieren" + "action": "Ganzes Dossier analysieren" }, "stats": { - "analyzed-pages": "{count, plural, one{Page} other{Pages}}", + "analyzed-pages": "{count, plural, one{Seite} other{Seiten}}", "total-people": "Anzahl der Benutzer" }, "table-col-names": { "documents-status": "Documents state", - "dossier-state": "Dossier state", - "last-modified": "Last modified", + "dossier-state": "Dossier-Status", + "last-modified": "Letzte Änderung", "name": "Name", - "needs-work": "Arbeitsvorrat", + "needs-work": "Liste", "owner": "Besitzer" }, "table-header": { - "title": "{length} active {length, plural, one{dossier} other{dossiers}}" + "title": "{length} {length, plural, one{aktives Dossier} other{aktive Dossiers}}" } }, "dossier-overview": { "approve": "Genehmigen", - "approve-disabled": "Das Dokument kann erst genehmigt werden, wenn eine Analyse auf Basis der aktuellen Wörterbücher durchgeführt wurde und die Vorschläge bearbeitet wurden.", + "approve-disabled": "Sie können die Datei erst freigeben, wenn sie auf Basis der aktuellen Wörterbücher analysiert wurde.", "assign-approver": "Genehmiger zuordnen", - "assign-me": "Mir zuteilen", - "assign-reviewer": "Überprüfer zuordnen", + "assign-me": "Mir zuweisen", + "assign-reviewer": "Benutzer zuweisen", "back-to-new": "Move to 'New'", "bulk": { "delete": "Dokumente löschen", @@ -960,7 +958,7 @@ }, "dossier-details": { "attributes": { - "expand": "{count} custom {count, plural, one{attribute} other{attributes}}", + "expand": "{count} {count, plural, one{benutzerdefiniertes Attribut} other{benutzerdefinierte Attribute}}", "image-uploaded": "Bild hochgeladen", "show-less": "weniger anzeigen" }, @@ -990,7 +988,7 @@ }, "filters": { "label": "Dokumentname", - "search": "Dokumentname..." + "search": "Name des Dokuments eingeben..." }, "header-actions": { "download-csv": "CSV-Dateibericht herunterladen", @@ -1020,13 +1018,13 @@ "recent": "Neu ({hours} h)", "unassigned": "Niemandem zugewiesen" }, + "reanalyse": { + "action": "Datei analysieren" + }, "reanalyse-dossier": { "error": "Die Dateien konnten nicht für eine Reanalyse eingeplant werden. Bitte versuchen Sie es erneut.", "success": "Dateien für Reanalyse vorgesehen." }, - "reanalyse": { - "action": "Datei analysieren" - }, "report-download": "Report download", "start-auto-analysis": "Enable auto-analysis", "stop-auto-analysis": "Stop auto-analysis", @@ -1096,6 +1094,14 @@ "total-documents": "Anzahl der Dokumente", "total-people": "{count} {count, plural, one{user} other {users}}" }, + "dossier-templates": { + "label": "Dossier-Vorlagen", + "status": { + "active": "Active", + "inactive": "Inactive", + "incomplete": "Incomplete" + } + }, "dossier-templates-listing": { "action": { "clone": "Clone template", @@ -1130,14 +1136,6 @@ "title": "{length} dossier {length, plural, one{template} other{templates}}" } }, - "dossier-templates": { - "label": "Dossier-Vorlagen", - "status": { - "active": "Active", - "inactive": "Inactive", - "incomplete": "Incomplete" - } - }, "dossier-watermark-selector": { "heading": "Watermarks on documents", "no-watermark": "There is no watermark defined for the dossier template.
Contact your app admin to define one.", @@ -1235,10 +1233,12 @@ "save": "", "title": "" }, - "entries-count": "", - "false-positives": "False positives ({count})", - "false-recommendations": "False recommendations ({count})", - "to-redact": "To redact ({count})" + "entries": "{length} {length, plural, one{entry} other{entries}} to {hint, select, true{annotate} other{redact}}", + "false-positive-entries": "{length} false positive {length, plural, one{entry} other{entries}}", + "false-positives": "False positives", + "false-recommendation-entries": "{length} false recommendation {length, plural, one{entry} other{entries}}", + "false-recommendations": "False recommendations", + "to-redact": "To redact" }, "general-info": { "form": { @@ -1282,10 +1282,13 @@ "content": { "comment": "Comment", "comment-placeholder": "Add remarks or mentions...", + "custom-rectangle": "", + "imported": "", "legal-basis": "", "options": { - "in-document": { + "in-dossier": { "description": "", + "extraOptionLabel": "", "label": "" }, "only-here": { @@ -1329,6 +1332,15 @@ "title": "{length} {length, plural, one{entity} other{entities}}" } }, + "entity": { + "info": { + "actions": { + "revert": "Revert", + "save": "Save changes" + }, + "heading": "Edit entity" + } + }, "entity-rules-screen": { "error": { "generic": "Something went wrong... Entity rules update failed!" @@ -1342,45 +1354,42 @@ "title": "Entity rule editor", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} found in rules" }, - "entity": { - "info": { - "actions": { - "revert": "Revert", - "save": "Save changes" - }, - "heading": "Edit entity" - } - }, "error": { "deleted-entity": { "dossier": { "action": "Zurück zur Übersicht", "label": "Dieses Dossier wurde gelöscht!" }, - "file-dossier": { - "action": "Zurück zur Übersicht", - "label": "Das Dossier dieser Datei wurde gelöscht!" - }, "file": { "action": "Zurück zum Dossier", "label": "Diese Datei wurde gelöscht!" + }, + "file-dossier": { + "action": "Zurück zur Übersicht", + "label": "Das Dossier dieser Datei wurde gelöscht!" } }, "file-preview": { - "action": "Refresh", - "label": "An unknown error occurred. Please refresh the page." + "action": "Aktualisieren", + "label": "Unbekannter Fehler: Bitte aktualisieren Sie die Seite." }, "http": { - "generic": "Aktion mit Code {status} fehlgeschlagen" + "generic": "Aktion fehlgeschlagen. Fehlercode: {status}" }, - "missing-types": "The dossier template has missing types ({missingTypes}). Data might not be displayed correctly.", + "missing-types": "Dossier-Vorlage unvollständig: Fehlende Typen ({missingTypes}) können zu Anzeigefehlern führen.", "offline": "Du bist offline", "online": "Du bist online", "reload": "Neu laden", - "title": "Hoppla! Etwas ist schief gelaufen..." + "title": "Ein Fehler ist aufgetreten." }, "exact-date": "{day} {month} {year} um {hour}:{minute} Uhr", "file": "Datei", + "file-attribute": { + "update": { + "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", + "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." + } + }, "file-attribute-encoding-types": { "ascii": "ASCII", "iso": "ISO-8859-1", @@ -1391,25 +1400,19 @@ "number": "Nummer", "text": "Freier Text" }, - "file-attribute": { - "update": { - "error": "Failed to update file attribute value!", - "success": "File attribute value has been updated successfully!" - } - }, "file-attributes-configurations": { - "cancel": "Cancel", + "cancel": "Abbrechen", "form": { - "delimiter": "Delimiter", - "encoding-type": "Encoding type", - "key-column": "Key column", - "support-csv-mapping": "Support CSV mapping" + "delimiter": "Trennzeichen", + "encoding-type": "Kodierungstyp", + "key-column": "Schlüsselspalte", + "support-csv-mapping": "CSV-Mapping unterstützen" }, - "save": "Save configurations", - "title": "Configurations", + "save": "Konfiguration speichern", + "title": "Konfiguration", "update": { - "error": "Failed to update the configuration!", - "success": "Configuration has been updated successfully!" + "error": "Aktualisierung der Konfiguration fehlgeschlagen.", + "success": "Die Konfiguration wurde erfolgreich aktualisiert." } }, "file-attributes-csv-import": { @@ -1429,9 +1432,9 @@ "key-column": "Schlüsselspalte", "key-column-placeholder": "Spalte auswählen ...", "no-data": { - "title": "Keine Datei-Attribute definiert. Wählen Sie links eine Spalte aus, um Datei-Attribute zu definieren." + "title": "Keine Datei-Attribute definiert. Wählen Sie links eine CSV-Spalte aus, um Datei-Attribute zu definieren." }, - "no-hovered-column": "Fahren Sie mit der Maus über den Eintrag, um eine Vorschau der CSV-Spalte zu sehen.", + "no-hovered-column": "Hovern Sie über den Eintrag, um eine Vorschau der CSV-Spalte anzuzeigen.", "no-sample-data-for": "Keine Beispieldaten für {column}.", "parse-csv": "CSV-Datei mit neuen Optionen parsen", "quick-activation": { @@ -1441,7 +1444,7 @@ "save": { "error": "Fehler beim Erstellen der Datei-Attribute!", "label": "Attribute speichern", - "success": "{count} file {count, plural, one{attribute} other{attributes}} created successfully!" + "success": "{count} Datei-{count, plural, one{Attribut} other{Attribute}} erfolgreich erstellt!" }, "search": { "placeholder": "Nach Spaltennamen suchen ..." @@ -1450,7 +1453,7 @@ "table-col-names": { "name": "Name", "primary": "Primärattribut", - "primary-info-tooltip": "Der Wert des Attributs, das als Primärattribut ausgewählt wurde, wird in der Dokumentenliste unter dem Dateinamen angezeigt.", + "primary-info-tooltip": "Der Wert des Primärattributs steht in der Dokumentenliste unter dem Dateinamen.", "read-only": "Schreibgeschützt", "type": "Typ" }, @@ -1462,9 +1465,9 @@ "remove-selected": "Ausgewählte entfernen", "type": "Typ" }, - "title": "{length} file {length, plural, one{attribute} other{attributes}}" + "title": "{length} Datei-{length, plural, one{Attribut} other{Attribute}}" }, - "title": "CSV-Spalten auswählen, die als Datei-Attribute verwendet werden sollen", + "title": "CSV-Spalten zur Verwendung als Datei-Attriute auswählen", "total-rows": "{rows} Zeilen insgesamt" }, "file-attributes-listing": { @@ -1472,14 +1475,14 @@ "delete": "Attribut löschen", "edit": "Attribute bearbeiten" }, - "add-new": "Neue Attribute", + "add-new": "Neues Attribut", "bulk-actions": { "delete": "Ausgewählte Attribute löschen" }, - "configurations": "Configurations", + "configurations": "Konfiguration", "error": { - "conflict": "Es gibt bereits ein Attribute mit diesem Name!", - "generic": "Attribute konnte nicht erstellt werden!" + "conflict": "Es gibt bereits ein Attribut mit diesem Namen. Bitte versuchen Sie es mit einem anderen Namen.", + "generic": "Erstellung des Datei-Attributs fehlgeschlagen." }, "no-data": { "title": "Es sind noch keine Datei-Attribute vorhanden." @@ -1495,42 +1498,42 @@ "filterable": "Filterbar", "name": "Name", "primary": "Primärattribut", - "primary-info-tooltip": "Der Wert des Attributs, das als Primärattribut ausgewählt wurde, wird in der Dokumentenliste unter dem Dateinamen angezeigt.", + "primary-info-tooltip": "Der Wert des Primärattributs steht in der Dokumentenliste unter dem Dateinamen.", "read-only": "Schreibgeschützt", "type": "Eingabetyp" }, "table-header": { - "title": "{length} file {length, plural, one{attribute} other{attributes}}" + "title": "{length} {length, plural, one{Datei-Attribut} other{Datei-Attribute}}" }, "upload-csv": "Datei-Attribute hochladen" }, "file-preview": { "assign-me": "Mir zuweisen", - "assign-reviewer": "Reviewer zuweisen", - "change-reviewer": "Reviewer wechseln", + "assign-reviewer": "Benutzer zuweisen", + "change-reviewer": "Prüfer ändern", "delta": "Delta", - "delta-tooltip": "Die Delta-Ansicht zeigt nur die Änderungen seit der letzten Reanalyse an. Die Ansicht ist nur verfügbar, wenn es seit der letzten Analyse mindestens 1 Änderung gab", - "document-info": "Dok-Infos: Hier finden Sie die zu Ihrem Dokument hinterlegten Informationen; u. a. die für das Dokument erforderlichen Metadaten.", + "delta-tooltip": "Delta zeigt die Änderungen seit der letzten Reanalyse. Sie ist nur verfügbar, wenn es seitdem min. 1 Änderung gab.", + "document-info": "Datei-Info (Datei-Attribute)", "download-original-file": "Originaldatei herunterladen", "exclude-pages": "Seiten von Schwärzung ausschließen", - "excluded-from-redaction": "Von Schwärzung ausgeschlossen", - "fullscreen": "Vollbildmodus", - "get-tables": "Draw tables", + "excluded-from-redaction": "Seite ausgeschlossen", + "fullscreen": "Vollbildmodus (F-Taste)", + "get-tables": "Tabellen zeichnen", "highlights": { - "convert": "Convert earmarks", - "remove": "Remove earmarks" + "convert": "Markierungen konvertieren", + "remove": "Markierungen entfernen" }, - "last-assignee": "Zuletzt überprüft von:", + "last-assignee": "{status, select, APPROVED{Freigegeben} UNDER_APPROVAL{Geprüft} other{Zuletzt geprüft}} von:", "no-data": { - "title": "Auf dieser Seite gibt es keine Anmerkungen." + "title": "Auf dieser Seite wurden keine Änderungen vorgenommen." }, "quick-nav": { "jump-first": "Zur ersten Seite springen", "jump-last": "Zur letzten Seite springen" }, - "reanalyse-notification": "Start re-analysis", + "reanalyse-notification": "Reanalyse starten", "redacted": "Vorschau", - "redacted-tooltip": "In der Schwärzungsvorschau sehen Sie nur die Schwärzungen. Es handelt sich also um eine Vorschau der endgültigen geschwärzten Version. Diese Ansicht ist nur verfügbar, wenn für die Datei keine Änderungen ausstehen und keine Reanalyse erforderlich ist", + "redacted-tooltip": "In der Vorschau sehen Sie nur die Annotationen. Es handelt sich also um eine Vorschau der endgültigen Version. Diese Ansicht ist nur verfügbar, wenn für die Datei keine Änderungen ausstehen und keine Reanalyse erforderlich ist", "standard": "Standard", "standard-tooltip": "In der Standard-Ansicht des Workloads werden alle Hinweise, Schwärzungen, Empfehlungen und Vorschläge angezeigt. In dieser Ansicht ist die Bearbeitung möglich.", "tabs": { @@ -1538,27 +1541,27 @@ "hide-skipped": "", "jump-to-next": "Springe zu Nächster", "jump-to-previous": "Springe zu Vorheriger", - "label": "Arbeitsvorrat", - "no-annotations": "There are no annotations for the selected component. \n", + "label": "Liste", + "no-annotations": "Es sind keine Annotationen vorhanden.", "page-is": "Diese Seite ist", - "reset": "reset", + "reset": "Setzen Sie die Filter zurück", "select": "Auswählen", "select-all": "Alle", "select-none": "Keine", - "show-skipped": "Show skipped in document", - "the-filters": "the filters", - "wrong-filters": "No annotations for the selected filter combination. Please adjust or" + "show-skipped": "Ignorierte im Dokument anzeigen", + "the-filters": "Filter", + "wrong-filters": "Keine Annotationen für die ausgewählte Filterkombination. Bitte ändern Sie die Auswahl oder setzen die Filter zurück." }, "document-info": { - "close": "Dokumenteninformation schließen", + "close": "Datei-Info schließen", "details": { "created-on": "Erstellt am: {date}", "dossier": "in {dossierName}", "due": "Termin: {date}", "pages": "{pages} Seiten" }, - "edit": "Infos zum Dokument bearbeiten", - "label": "Infos zum Dokument" + "edit": "Datei-Info bearbeiten", + "label": "Datei-Info" }, "exclude-pages": { "close": "Schließen", @@ -1567,76 +1570,76 @@ "input-placeholder": "z. B. 1-20,22,32", "label": "Seiten ausschließen", "no-excluded": "Es sind keine Seiten ausgeschlossen.", - "put-back": "Rückgängig machen", + "put-back": "Zurücksetzen", "removed-from-redaction": "Von der Schwärzung ausgeschlossen" }, "highlights": { - "label": "Earmarks" + "label": "Markierungen" }, - "is-excluded": "Schwärzungen für dieses Dokument deaktiviert.", + "is-excluded": "Extraktion ist für dieses Dokument deaktiviert.", "multi-select": { "close": "" } }, - "text-highlights": "Earmarks", - "text-highlights-tooltip": "Shows all text-earmarks and allows removing or importing them as components", + "text-highlights": "Markierungen", + "text-highlights-tooltip": "In Markierungen können Textmarker entfernt oder in Schwärzungen konvertiert werden.", "toggle-analysis": { - "disable": "Schwärzen deaktivieren", - "enable": "Schwärzen aktivieren", - "only-managers": "Aktivieren/deaktivieren ist nur Managern gestattet" + "disable": "Extraktion deaktivieren", + "enable": "Extraktion aktivieren", + "only-managers": "Aktivieren/deaktivieren ist nur Bearbeiter" } }, "file-status": { - "analyse": "Analyzing", + "analyse": "Analyse läuft", "approved": "Genehmigt", "error": "Reanalyse erforderlich", "figure-detection-analyzing": "", - "full-processing": "Processing", - "full-reprocess": "Wird analysiert", + "full-processing": "Verarbeitung läuft", + "full-reprocess": "Verarbeitung läuft", "image-analyzing": "Bildanalyse", - "indexing": "Wird analysiert", - "initial-processing": "Initial processing...", - "ner-analyzing": "NER analyzing", + "indexing": "Verarbeitung läuft", + "initial-processing": "Initiale Verarbeitung läuft...", + "ner-analyzing": "NER-Analyse läuft", "new": "Neu", - "ocr-processing": "OCR-Analyse", + "ocr-processing": "OCR-Verarbeitung läuft", "processed": "Verarbeitet", - "processing": "Wird analysiert...", - "re-processing": "Re-processing...", - "reprocess": "Wird analysiert", - "table-parsing-analyzing": "Table parsing", + "processing": "Wird verarbeitet...", + "re-processing": "Erneute Verarbeitung läuft...", + "reprocess": "Wird verarbeitet", + "table-parsing-analyzing": "Table Parsing", "unassigned": "Nicht zugewiesen", - "under-approval": "In Genehmigung", - "under-review": "In Review", - "unprocessed": "Unbearbeitet" + "under-approval": "In Freigabe", + "under-review": "In Überprüfung", + "unprocessed": "Unverarbeitet" }, "file-upload": { "type": { - "csv": "File attributes were imported successfully from uploaded CSV file." + "csv": "Die Datei-Attribute wurden erfolgreich aus der hochgeladenen CSV-Datei importiert." } }, + "filter": { + "analysis": "Analyse erforderlich", + "comment": "Kommentare", + "hint": "Nur Hinweise", + "image": "Bilder", + "none": "Keine Annotationen", + "redaction": "Annotationen", + "updated": "Aktualisiert" + }, "filter-menu": { "filter-options": "Filteroptionen", "filter-types": "Filter", "label": "Filter", - "pages-without-annotations": "Only pages without annotations", - "redaction-changes": "Nur Anmerkungen mit Schwärzungsänderungen", - "unseen-pages": "Nur Anmerkungen auf unsichtbaren Seiten", + "pages-without-annotations": "Nur Seiten ohne Annotationen", + "redaction-changes": "Nur Annotationen mit lokalen manuellen Änderungen", + "unseen-pages": "Nur Anmerkungen auf ungesehenen Seiten", "with-comments": "Nur Anmerkungen mit Kommentaren" }, - "filter": { - "analysis": "Analyse erforderlich", - "comment": "Kommentare", - "hint": "Nut Hinweise", - "image": "Bilder", - "none": "Keine Anmerkungen", - "redaction": "Geschwärzt", - "updated": "Aktualisiert" - }, "filters": { - "assigned-people": "Beauftragt", - "documents-status": "Documents state", - "dossier-state": "Dossier state", - "dossier-templates": "Regelsätze", + "assigned-people": "Bearbeiter", + "documents-status": "Dokumentenstatus", + "dossier-state": "Dossier-Status", + "dossier-templates": "Dossier-Vorlagen", "empty": "Leer", "filter-by": "Filter:", "needs-work": "Arbeitsvorrat", @@ -1644,37 +1647,37 @@ }, "general-config-screen": { "actions": { - "save": "Einstellungen speichern", + "save": "Konfiguration speichern", "test-connection": "Verbindung testen" }, "app-name": { - "label": "Name der Applikation", + "label": "Anzeigename", "placeholder": "DocuMine" }, "form": { "auth": "Authentifizierung aktivieren", - "change-credentials": "Zugangsdaten ändern", - "envelope-from": "Ausgangsadresse", - "envelope-from-hint": "Infotext zum Feld „Ausgangsadresse“.", - "envelope-from-placeholder": "Ausgangsadresse", + "change-credentials": "Anmeldedaten ändern", + "envelope-from": "Envelope von", + "envelope-from-hint": "Infotext zum Feld „Envelope von“.", + "envelope-from-placeholder": "Envelope-Absenderadresse", "from": "Von", - "from-display-name": "Antworten an", - "from-display-name-hint": "Info-Text zum Absendernamen.", - "from-display-name-placeholder": "Anzeigename zur Ausgangsadresse", - "from-placeholder": "E-Mail-Adresse des Absenders", + "from-display-name": "Name für Absender", + "from-display-name-hint": "Hinweistext zum Namen für „Absender“", + "from-display-name-placeholder": "Anzeigename für „Absender-E-Mail-Adresse“", + "from-placeholder": "Absender-E-Mail-Adresse", "host": "Host", "host-placeholder": "SMTP-Host", "port": "Port", - "reply-to": "Antwortadresse", - "reply-to-display-name": "Name für Antwortadresse", + "reply-to": "Antwort an", + "reply-to-display-name": "Name für „Antwort an“", "reply-to-display-name-placeholder": "Anzeigename zu Antwort-E-Mail", - "reply-to-placeholder": "Antwort-E-Mail", + "reply-to-placeholder": "„Antwort an“-E-Mail-Adresse", "ssl": "SSL aktivieren", "starttls": "StartTLS aktivieren" }, "general": { "form": { - "forgot-password": "„Passwort vergessen?“-Link auf der Login-Seite anzeigen" + "forgot-password": "„Passwort vergessen?“-Link auf Login-Seite anzeigen" }, "subtitle": "", "title": "Allgemeine Einstellungen" @@ -1682,40 +1685,40 @@ "subtitle": "SMTP (Simple Mail Transfer Protocol) ermöglicht es Ihnen, Ihre E-Mails über die angegebenen Servereinstellungen zu versenden.", "system-preferences": { "labels": { - "download-cleanup-download-files-hours": "Delete downloaded packages automatically after X hours", - "download-cleanup-not-download-files-hours": "Keep the generated download package for X hours", - "soft-delete-cleanup-time": "Keep deleted files and dossiers for X hours in trash" + "download-cleanup-download-files-hours": "Heruntergeladene Pakete nach X Stunden automatisch löschen", + "download-cleanup-not-download-files-hours": "Generiertes Downloadpaket für X Stunden vorhalten", + "soft-delete-cleanup-time": "Gelöschte Dateien und Dossiers für X Stunden im Papierkorb vorhalten" }, "placeholders": { - "download-cleanup-download-files-hours": "(hours)", - "download-cleanup-not-download-files-hours": "(hours)", - "soft-delete-cleanup-time": "(hours)" + "download-cleanup-download-files-hours": "(Stunden)", + "download-cleanup-not-download-files-hours": "(Stunden)", + "soft-delete-cleanup-time": "(Stunden)" }, - "title": "System preferences" + "title": "Systemeinstellungen" }, "test": { - "error": "Die Test-E-Mail konnte nicht gesendet werden! Bitte überprüfen Sie die E-Mail-Adresse.", - "success": "Die Test-E-Mail wurde erfolgreich versendet!", - "warning": "Admin mail address not set. Test email sent to {recipientEmail} instead." + "error": "Die Test-E-Mail konnte nicht gesendet werden. Bitte überprüfen Sie die E-Mail-Adresse.", + "success": "Die Test-E-Mail wurde erfolgreich versendet.", + "warning": "Admin-E-Mail-Adresse nicht gesetzt. Die Test-E-Mail wurde stattdessen an {recipientEmail} gesendet." }, "title": "SMTP-Konto konfigurieren" }, "help-button": { - "disable": "Disable help mode", - "enable": "Enable help mode" + "disable": "Hilfemodus deaktivieren", + "enable": "Hilfemodus aktivieren" }, "help-mode": { "bottom-text": "Hilfe-Modus", - "clicking-anywhere-on": "Klicken Sie auf eine beliebige Stelle des Bildschirms um zu sehen, welche Bereiche interaktiv sind. Wenn Sie mit der Maus über einen interaktiven Bereich fahren, verändert sich der Mauszeiger, um Ihnen zu zeigen, ob ein Element interaktiv ist.", - "instructions": "Hilfe-Modus-Anleitungen öffnen", + "clicking-anywhere-on": "Klicken Sie auf eine beliebige Stelle, um zu sehen, welche Bereiche interaktiv sind. Wenn Sie mit der Maus über einen interaktiven Bereich fahren, verändert sich der Mauszeiger. So erkennen Sie, dass ein Element anklickbar ist.", + "instructions": "Anleitung für Hilfemodus öffnen", "options": { - "do-not-show-again": "Do not show again" + "do-not-show-again": "Nicht mehr anzeigen" }, - "welcome-to-help-mode": " Willkommen im Hilfe-Modus!
Klicken Sie auf interaktive Elemente, um in einem neuen Tab Infos dazu zu erhalten.
" + "welcome-to-help-mode": "Willkommen im Hilfemodus!
Klicken Sie auf die interaktive Elemente,
um in einem neuen Tab Infos zu den jeweiligen Funktionen zu erhalten." }, "highlight-action-dialog": { "actions": { - "cancel": "Cancel" + "cancel": "Abbrechen" }, "convert": { "confirmation": "The {count} selected {count, plural, one{earmark} other{earmarks}} will be converted", @@ -1910,6 +1913,13 @@ "user-promoted-to-approver": "{user} wurde im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} zum Genehmiger ernannt!", "user-removed-as-dossier-member": "{user} wurde als Mitglied von: {dossierHref, select, null{{dossierName}} other{{dossierName}}} entfernt!" }, + "notifications": { + "button-text": "Notifications", + "deleted-dossier": "Deleted dossier", + "label": "Benachrichtigungen", + "mark-all-as-read": "Alle als gelesen markieren", + "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}" + }, "notifications-screen": { "category": { "email-notifications": "E-Mail Benachrichtigungen", @@ -1923,7 +1933,6 @@ "dossier": "Dossierbezogene Benachrichtigungen", "other": "Andere Benachrichtigungen" }, - "options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten", "options": { "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen bin", "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Überprüfer zugewiesen bin", @@ -1941,6 +1950,7 @@ "USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde", "USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere" }, + "options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten", "schedule": { "daily": "Tägliche Zusammenfassung", "instant": "Sofortig", @@ -1948,13 +1958,6 @@ }, "title": "Benachrichtigungseinstellungen" }, - "notifications": { - "button-text": "Notifications", - "deleted-dossier": "Deleted dossier", - "label": "Benachrichtigungen", - "mark-all-as-read": "Alle als gelesen markieren", - "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}" - }, "ocr": { "confirmation-dialog": { "cancel": "Cancel", @@ -2001,34 +2004,14 @@ "previous": "Vorherige" }, "pdf-viewer": { - "header": { - "all-annotations-loaded": "Alle Annotationen geladen", - "compare-button": "Vergleichen", - "layers-panel-button": "Ebenen", - "left-panel-button": "Panel", - "load-all-annotations": "Alle Annotationen laden", - "no-outlines-text": "Keine Gliederung verfügbar", - "no-signatures-text": "In diesem Dokument gibt es keine Unterschriftenfelder", - "outline-multi-select": "Bearbeiten", - "outlines-panel-button": "Gliederung", - "pan-tool-button": "Verschieben", - "rectangle-tool-button": "Bereichsschwärzung", - "rotate-left-button": "Seite nach links drehen", - "rotate-right-button": "Seite nach rechts drehen", - "select-tool-button": "Auswählen", - "signature-panel-button": "Unterschriften", - "thumbnails-panel-button": "Miniaturansicht", - "toggle-layers": "Layout-Raster {active, select, true{deaktivieren} false{aktivieren} other{}}", - "toggle-readable-redactions": "Schwärzungen {active, select, true{wie im finalen Dokument} false{in Vorschau-Farbe} other{}} anzeigen", - "toggle-tooltips": "Tooltips zu Annotationen {active, select, true{deaktivieren} false{aktivieren} other{}}", - "zoom-in-button": "Vergrößern", - "zoom-out-button": "Verkleinern" - }, "text-popup": { "actions": { "search": "Search for selected text" } - } + }, + "toggle-layers": "{active, select, true{Disable} false{Enable} other{}} layout grid", + "toggle-readable-redactions": "Show components {active, select, true{as in final document} false{in preview color} other{}}", + "toggle-tooltips": "{active, select, true{Disable} false{Enable} other{}} Kurzinfos für Anmerkungen" }, "permissions-screen": { "dossier": { @@ -2066,16 +2049,16 @@ "warnings-label": "Prompts and dialogs", "warnings-subtitle": "Do not show again options" }, + "processing": { + "basic": "Processing", + "ocr": "OCR" + }, "processing-status": { "ocr": "OCR", "pending": "Pending", "processed": "Processed", "processing": "Processing" }, - "processing": { - "basic": "Processing", - "ocr": "OCR" - }, "readonly": "Lesemodus", "readonly-archived": "Read only (archived)", "redact-text": { @@ -2090,10 +2073,6 @@ "edit-text": "", "legal-basis": "Legal basis", "options": { - "in-document": { - "description": "", - "label": "" - }, "in-dossier": { "description": "Add redaction in every document in {dossierName}.", "extraOptionLabel": "Apply to all dossiers", @@ -2109,8 +2088,7 @@ "revert-text": "", "type": "Type", "type-placeholder": "Select type...", - "unchanged": "", - "value": "" + "unchanged": "" }, "title": "Redact text" } @@ -2134,10 +2112,6 @@ "description-bulk": "The selected items should not be annotated in their respective contexts.", "label": "False positive" }, - "in-document": { - "description": "", - "label": "" - }, "in-dossier": { "description": "Do not annotate ''{value}'' as ''{type}'' in any dossier.", "description-bulk": "Do not annotate the selected terms as their respective types in any dossier.", @@ -2178,10 +2152,6 @@ "extraOptionLabel": "Apply to all dossiers", "label": "False positive" }, - "in-document": { - "description": "", - "label": "" - }, "in-dossier": { "description": "Do not {type} \"{value}\" in any document of the current dossier.", "description-bulk": "", @@ -2324,6 +2294,12 @@ "red-user-admin": "Benutzer-Admin", "regular": "Regulär" }, + "search": { + "active-dossiers": "ganze Plattform", + "all-dossiers": "all documents", + "placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen", + "this-dossier": "in diesem Dossier" + }, "search-screen": { "cols": { "assignee": "Bevollmächtigter", @@ -2347,12 +2323,6 @@ "no-match": "Keine Dokumente entsprechen Ihren aktuellen Filtern.", "table-header": "{length} search {length, plural, one{result} other{results}}" }, - "search": { - "active-dossiers": "ganze Plattform", - "all-dossiers": "all documents", - "placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen", - "this-dossier": "in diesem Dossier" - }, "seconds": "seconds", "size": "Size", "smtp-auth-config": { @@ -2543,6 +2513,10 @@ "view-as": "Ansicht als:", "workflow": "Arbeitsablauf" }, + "viewer-header": { + "all-annotations-loaded": "All annotations loaded", + "load-all-annotations": "Load all annotations" + }, "watermark-screen": { "action": { "change-success": "Das Wasserzeichen wurde aktualisiert!", @@ -2571,10 +2545,6 @@ "orientation": "Ausrichtung", "text-label": "Watermark text", "text-placeholder": "Text eingeben" - }, - "pagination": { - "landscape": "", - "portrait": "" } }, "watermarks-listing": { diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index 20da78957..974651f57 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -37,7 +37,7 @@ "save-and-add-members": "Save and edit team" }, "errors": { - "dossier-already-exists": "Dossier with this name already exists! If it is in the trash, you need to permanently delete it first to re-use the name. If it is an active or archived dossier, please choose a different name." + "dossier-already-exists": "Dossier name already exists.\n
  • If the dossier is in trash, you can delete it permanently to reuse the name.
  • If the dossier is active or archived, please use a different name.
" }, "form": { "description": { @@ -159,8 +159,8 @@ "template-and-dossier-dictionaries": "" }, "success": { - "create": "Entity added!", - "edit": "Entity updated. Please note that other users need to refresh the browser to see your changes." + "create": "Success: Entity created.", + "edit": "Success: Entity updated.

Please ask the users to refresh the browser to see the changes." } }, "add-edit-file-attribute": { @@ -204,7 +204,7 @@ }, "error": { "email-already-used": "This e-mail address is already in use by a different user!", - "generic": "Failed to save user!" + "generic": "Failed to save user." }, "form": { "account-setup": "User account setup", @@ -265,7 +265,7 @@ "entities": "Entities", "entity-info": "Info", "entity-rule-editor": "Entity rule editor", - "false-positive": "False positive", + "false-positive": "False positives", "false-recommendations": "False recommendations", "file-attributes": "File attributes", "justifications": "Justifications", @@ -303,7 +303,7 @@ }, "remove": { "error": "Failed to remove dictionary entry: {error}", - "success": "Dictionary entry removed!" + "success": "Dictionary entry removed" }, "undo": { "error": "Failed to undo: {error}", @@ -313,15 +313,15 @@ "manual-redaction": { "add": { "error": "Failed to save annotation: {error}", - "success": "Annotation added!" + "success": "Annotation added" }, "force-hint": { "error": "Failed to save hint: {error}", - "success": "Hint added!" + "success": "Hint added" }, "force-redaction": { "error": "Failed to save annotation: {error}", - "success": "Annotation added!" + "success": "Annotation added" }, "recategorize-annotation": { "error": "", @@ -333,11 +333,11 @@ }, "remove-hint": { "error": "Failed to remove hint: {error}", - "success": "Hint removed!" + "success": "Hint removed" }, "remove": { "error": "Failed to remove annotation: {error}", - "success": "Annotation removed!" + "success": "Annotation removed" }, "undo": { "error": "Failed to undo: {error}", @@ -482,7 +482,7 @@ }, "auth-error": { "heading": "Your user is successfully logged in but has no role assigned yet. Please contact your DocuMine administrator to assign appropriate roles.", - "heading-with-link": "Your user is successfully logged in but has no role assigned yet. Please contact your DocuMine administrator to assign appropriate roles!", + "heading-with-link": "Your user is successfully logged in but has no role assigned yet. Please ask your DocuMine administrator to assign a role to you.", "heading-with-name": "Your user is successfully logged in but has no role assigned yet. Please contact {adminName} to assign appropriate roles.", "heading-with-name-and-link": "Your user is successfully logged in but has no role assigned yet. Please contact {adminName} to assign appropriate roles.", "logout": "Logout" @@ -600,22 +600,22 @@ "checkbox": { "documents": "All documents will be archived and cannot be put back to active" }, - "details": "Restoring an archived dossier is not possible anymore, once it got archived.", + "details": "Be aware that archiving is an irreversible action. Documents archived will no longer be available for active use.", "title": "Archive {dossierName}", - "toast-error": "Please confirm that you understand the ramifications of your action!", + "toast-error": "Please confirm that you understand the consequences of this action.", "warning": "Are you sure you want to archive the dossier?" }, "confirm-delete-attribute": { "cancel": "Keep {count, plural, one{attribute} other{attributes}}", "delete": "Delete {count, plural, one{attribute} other{attributes}}", - "dossier-impacted-documents": "All dossiers based on this template will be affected", - "dossier-lost-details": "All values for this attribute will be lost", + "dossier-impacted-documents": "This action will affect all dossiers that use this template.", + "dossier-lost-details": "The attribute values entered by users on document level will be lost.", "file-impacted-documents": "All documents {count, plural, one{it is} other{they are}} used on will be impacted", - "file-lost-details": "All inputted details on the documents will be lost", - "impacted-report": "{reportsCount} reports use the placeholder for this attribute and need to be adjusted", + "file-lost-details": "All information entered by users on document level will be lost.", + "impacted-report": "{reportsCount} reports currently use the placeholder for this attribute. Please update them.", "title": "Delete {count, plural, one{{name}} other{file attributes}}", - "toast-error": "Please confirm that you understand the ramifications of your action!", - "warning": "Warning: this cannot be undone!" + "toast-error": "Please confirm that you understand the consequences of this action.", + "warning": "Warning: This action cannot be undone!" }, "confirm-delete-dossier-state": { "cancel": "Cancel", @@ -623,9 +623,9 @@ "delete-replace": "Delete and replace", "form": { "state": "Replace state", - "state-placeholder": "Choose another state" + "state-placeholder": "Select another state" }, - "question": "Replace the {count, plural, one{dossier's} other{dossiers'}} state with another state", + "question": "Select another state to replace the current {count, plural, one{dossier} other{dossier}} state", "success": "Successfully deleted state!", "title": "Delete dossier state", "warning": "The {name} state is assigned to {count} {count, plural, one{dossier} other{dossiers}}." @@ -636,15 +636,15 @@ "impacted-documents": "All documents pending review from the {usersCount, plural, one{user} other{users}} will be impacted", "impacted-dossiers": "{dossiersCount} {dossiersCount, plural, one{dossier} other{dossiers}} will be impacted", "title": "Delete {usersCount, plural, one{user} other{users}} from workspace", - "toast-error": "Please confirm that you understand the ramifications of your action!", + "toast-error": "Please confirm that you understand the consequences of this action.", "warning": "Warning: this cannot be undone!" }, "confirmation-dialog": { "approve-file": { "confirmationText": "Approve anyway", "denyText": "No, cancel", - "question": "Do you still want to approve the {questionLength, plural, one{document} other{documents}}?", - "title": "Approval warning", + "question": "This document contains unseen changes that have been added during the reanalysis.\n

Do you still want to approve it?", + "title": "Warning!", "warning-reason": { "legal-basis-missing": "Legal basis missing", "pending-changes": "Pending Changes", @@ -654,19 +654,19 @@ "assign-file-to-me": { "question": { "multiple": "At least one document is currently assigned to someone else. Are you sure you want to replace them and assign yourself to these documents?", - "single": "This document is currently assigned to someone else. Are you sure you want to replace it and assign yourself to this document?" + "single": "This document is currently assigned to another user. Do you still want to assign the files to yourself?" }, "title": "Re-assign user" }, "compare-file": { - "question": "Warning!

Number of pages does not match, current document has {currentDocumentPageCount} page(s). Uploaded document has {compareDocumentPageCount} page(s).

Do you wish to proceed?", + "question": "Warning: page count mismatch

Current document: \n{currentDocumentPageCount} page(s).

Upload document: \n{compareDocumentPageCount} page(s).
This appears to be a different document. Do you wish to proceed?", "title": "Compare with file: {fileName}" }, "delete-dossier": { "confirmation-text": "Delete {dossiersCount, plural, one{dossier} other{dossiers}}", "deny-text": "Keep {dossiersCount, plural, one{dossier} other{dossiers}}", "question": "Are you sure you want to delete {dossiersCount, plural, one{this dossier} other{these dossiers}}?", - "title": "Delete {dossiersCount, plural, one{{dossierName}} other{Selected Dossiers}}" + "title": "Delete {dossiersCount, plural, one{{dossierName}} other{selected dossiers}}" }, "delete-file": { "question": "Do you wish to proceed?", @@ -689,23 +689,23 @@ }, "unsaved-changes": { "confirmation-text": "Save and leave", - "details": "If you leave the tab without saving, all the unsaved changes will be lost.", + "details": "Please save your changes. If you leave now, any unsaved progress will be lost.", "discard-changes-text": "DISCARD CHANGES", - "question": "Are you sure you want to leave the tab? You have unsaved changes.", + "question": "Do you still want to leave the tab?", "title": "You have unsaved changes" }, "upload-report-template": { "alternate-confirmation-text": "Upload as multi-file report", "confirmation-text": "Upload as single-file report", "deny-text": "Cancel upload", - "question": "Please choose if {fileName} is a single or multi-file report template", + "question": "Please indicate if {fileName} is a single or multi-file report template", "title": "Report template upload" } }, "content": "Reason", "dashboard": { "empty-template": { - "description": "This template does not contain any dossiers. Start by creating a dossier to use it on.", + "description": "This template does not contain any dossiers. Create a dossier that applies this ruleset.", "new-dossier": "New dossier" }, "greeting": { @@ -769,13 +769,13 @@ }, "download": "Download current entries", "error": { - "400": "Cannot update dictionary because at least one of the newly added words where recognized as a general term that appear too often in texts.", - "generic": "Something went wrong... Dictionary update failed!" + "400": "Dictionary update failed.

One or more of the newly added terms have been identified as frequently used general term. Please remove these terms to proceed with the update.", + "generic": "Error: Dictionary update failed." }, "revert-changes": "Revert", "save-changes": "Save changes", "search": "Search entries...", - "select-dictionary": "Select a dictionary above to compare with the current one.", + "select-dictionary": "Select a dictionary for comparison above.", "success": { "generic": "Dictionary updated!" } @@ -785,11 +785,11 @@ "actions": { "back": "Back", "cancel": "Cancel", - "certificate-not-valid-error": "Uploaded certificate is not valid!", + "certificate-not-valid-error": "Uploaded certificate is invalid.", "continue": "Continue", "save": "Save configurations", "save-error": "Failed to save digital signature!", - "save-success": "Digital signature certificate successfully saved!" + "save-success": "Digital signature certificate saved successfully" }, "forms": { "kms": { @@ -811,11 +811,11 @@ }, "options": { "kms": { - "description": "Provide a corresponding PEM file containing the certificate, along with Amazon KMS credentials needed for securing the private key.", + "description": "Please upload a PEM file with the certificate and provide Amazon KMS credentials to secure the private key.", "label": "I use an Amazon KMS private key" }, "pkcs": { - "description": "A PKCS#12 file is a file that bundles the private key and the X.509 certificate. The password protection is required to secure the private key. Unprotected PKCS#12 files are not supported.", + "description": "A PKCS#12 file combines your private key with an X.509 certificate. Password protection is essential to secure the private key, as unprotected PKCS#12 files are not supported.", "label": "I want to upload a PKCS#12 file" } }, @@ -833,7 +833,7 @@ "remove": "Remove", "save": "Save changes", "save-error": "Failed to save digital signature!", - "save-success": "Digital signature certificate successfully saved!" + "save-success": "No digital signature certificate available.
Please configure a certificate to sign redacted documents." }, "no-data": { "action": "Configure certificate", @@ -885,7 +885,7 @@ "dossier-details": { "assign-members": "Assign members", "collapse": "Hide details", - "document-status": "Document status", + "document-status": "Document processing status", "edit-owner": "Edit owner", "expand": "Show details", "members": "Members", @@ -897,7 +897,7 @@ "add-new": "New dossier", "archive": { "action": "Archive dossier", - "archive-failed": "Failed to archive dossier {dossierName}!", + "archive-failed": "Failed to archive dossier {dossierName}.", "archive-succeeded": "Successfully archived dossier {dossierName}." }, "delete": { @@ -1236,9 +1236,9 @@ "title": "" }, "entries-count": "{count} {count, plural, one{entry} other{entries}}", - "false-positives": "False positives ({count})", - "false-recommendations": "False recommendations ({count})", - "to-redact": "To redact ({count})" + "false-positives": "False positives", + "false-recommendations": "False recommendations", + "to-redact": "To redact" }, "general-info": { "form": { @@ -1368,12 +1368,12 @@ }, "file-preview": { "action": "Refresh", - "label": "An unknown error occurred. Please refresh the page." + "label": "Unknown error: Please refresh the page." }, "http": { - "generic": "Action failed with code {status}" + "generic": "Action failed. Error code: {status}" }, - "missing-types": "The dossier template has missing types ({missingTypes}). Data might not be displayed correctly.", + "missing-types": "Dossier template incomplete: missing types ({missingTypes}) may cause data display issues.", "offline": "Disconnected", "online": "Reconnected", "reload": "Reload", @@ -1393,7 +1393,7 @@ }, "file-attribute": { "update": { - "error": "Failed to update file attribute value!", + "error": "Update of file attribute value failed. Please try again.", "success": "File attribute value has been updated successfully!" } }, @@ -1429,7 +1429,7 @@ "key-column": "Key column", "key-column-placeholder": "Select column...", "no-data": { - "title": "No file attributes defined. Select a column from the left panel to start defining file attributes." + "title": "No file attributes defined. Select a CSV column from the left to start defining file attributes." }, "no-hovered-column": "Preview CSV column by hovering the entry.", "no-sample-data-for": "No sample data for {column}.", @@ -1450,7 +1450,7 @@ "table-col-names": { "name": "Name", "primary": "primary", - "primary-info-tooltip": "The value of the attribute set as primary shows up under the file name in the documents list.", + "primary-info-tooltip": "The value of the attribute set as primary is diplayed below the file name in the document list.", "read-only": "Read-only", "type": "Type" }, @@ -1478,8 +1478,8 @@ }, "configurations": "Configurations", "error": { - "conflict": "File-Attribute with this name already exists!", - "generic": "Failed to add file attribute" + "conflict": "File attribute name already exists. Please try another name.", + "generic": "Failed to add file attribute." }, "no-data": { "title": "There are no file attributes yet." @@ -1495,7 +1495,7 @@ "filterable": "Filterable", "name": "Name", "primary": "Primary", - "primary-info-tooltip": "The value of the attribute set as primary shows up under the file name in the documents list.", + "primary-info-tooltip": "The value of the attribute set as primary is diplayed below the file name in the document list.", "read-only": "Read-only", "type": "Input type" }, @@ -1509,20 +1509,20 @@ "assign-reviewer": "Assign user", "change-reviewer": "Change user", "delta": "Delta", - "delta-tooltip": "The delta view shows the unseen changes since your last visit to the page. This view is only available if there is at least 1 change.", + "delta-tooltip": "Delta shows the unseen changes since your last visit to the page. It is only available if there has been at least 1 change.", "document-info": "Document info", "download-original-file": "Download original file", "exclude-pages": "Exclude pages from extraction", - "excluded-from-redaction": "excluded", + "excluded-from-redaction": "Excluded", "fullscreen": "Full screen (F)", "get-tables": "Draw tables", "highlights": { "convert": "Convert earmarks", "remove": "Remove earmarks" }, - "last-assignee": "Last assignee", + "last-assignee": "{status, select, APPROVED{Approved} UNDER_APPROVAL{Reviewed} other{Last reviewed}} by:", "no-data": { - "title": "This page does not contain annotations for the selected component or filter." + "title": "There have been no changes to this page." }, "quick-nav": { "jump-first": "Jump to first page", @@ -1539,7 +1539,7 @@ "jump-to-next": "Jump to next", "jump-to-previous": "Jump to previous", "label": "Workload", - "no-annotations": "There are no annotations for the selected component. \n", + "no-annotations": "There are no annotations for the selected component.\n", "page-is": "This page is", "reset": "reset", "select": "Select", @@ -1547,7 +1547,7 @@ "select-none": "None", "show-skipped": "Show skipped in document", "the-filters": "the filters", - "wrong-filters": "No annotations for the selected filter combination. Please adjust or" + "wrong-filters": "No annotations for the selected filter combination. Please adjust or reset the filters" }, "document-info": { "close": "Close document info", @@ -1579,7 +1579,7 @@ } }, "text-highlights": "Earmarks", - "text-highlights-tooltip": "Shows all text-earmarks and allows removing or importing them as components", + "text-highlights-tooltip": "Earmark allows removing text highlights or converting them into redactions.", "toggle-analysis": { "disable": "Disable extraction", "enable": "Enable for extraction", @@ -1588,7 +1588,7 @@ }, "file-status": { "analyse": "Analyzing", - "approved": "Done", + "approved": "Approved", "error": "Re-processing required", "figure-detection-analyzing": "", "full-processing": "Processing", @@ -1619,7 +1619,7 @@ "filter-types": "Filter", "label": "Filter", "pages-without-annotations": "Only pages without annotations", - "redaction-changes": "Only annotations with changes", + "redaction-changes": "Only annotations with local manual changes", "unseen-pages": "Only annotations on unseen pages", "with-comments": "Only annotations with comments" }, @@ -1694,7 +1694,7 @@ "title": "System preferences" }, "test": { - "error": "Test e-mail could not be sent! Please revise the e-mail address.", + "error": "Test e-mail could not be sent. Please double-check the email address.", "success": "Test e-mail was sent successfully!", "warning": "Admin mail address not set. Test email sent to {recipientEmail} instead." }, @@ -1706,12 +1706,12 @@ }, "help-mode": { "bottom-text": "Help mode", - "clicking-anywhere-on": " Clicking anywhere on the screen will show you which areas are interactive. Hovering an interactive area will change the mouse cursor to let you know if the element is interactive.", + "clicking-anywhere-on": "Click anywhere on the screen to display the interactive elements. When you hover over an interactive element, the mouse cursor changes to show the element is clickable.", "instructions": "Open help mode instructions", "options": { "do-not-show-again": "Do not show again" }, - "welcome-to-help-mode": " Welcome to help mode!
Clicking on interactive elements will open info about them in new tab.
" + "welcome-to-help-mode": "Welcome to Help Mode!
Click on interactive elements to learn more about their functionality in a new tab." }, "highlight-action-dialog": { "actions": { From 7a1e968a52bc4cd8c864768ab3406963ab201666 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Sat, 5 Oct 2024 20:50:40 +0300 Subject: [PATCH 061/125] RED-7340 - converted ManualAnnotationDialog into RectangleAnnotationDialog --- .../change-legal-basis-dialog.component.ts | 7 +- .../edit-redaction-dialog.component.ts | 3 +- .../force-annotation-dialog.component.ts | 10 +- ...ectangle-annotation-dialog.component.html} | 38 +----- ...ectangle-annotation-dialog.component.scss} | 5 + .../rectangle-annotation-dialog.component.ts} | 123 ++++++------------ .../redact-recommendation-dialog.component.ts | 2 +- .../redact-text-dialog.component.ts | 10 +- .../file-preview-screen.component.ts | 41 +++--- .../services/annotation-actions.service.ts | 2 +- .../services/file-preview-dialog.service.ts | 7 +- .../services/manual-redaction.service.ts | 2 + .../file-preview/utils/dialog-options.ts | 2 +- .../file-preview/utils/dialog-types.ts | 6 + .../enhance-manual-redaction-request.utils.ts | 39 +++++- apps/red-ui/src/assets/config/config.json | 4 +- libs/common-ui | 2 +- .../redaction-log/add-redaction.request.ts | 2 + 18 files changed, 139 insertions(+), 166 deletions(-) rename apps/red-ui/src/app/modules/file-preview/dialogs/{manual-redaction-dialog/manual-annotation-dialog.component.html => rectangle-annotation-dialog/rectangle-annotation-dialog.component.html} (71%) rename apps/red-ui/src/app/modules/file-preview/dialogs/{manual-redaction-dialog/manual-annotation-dialog.component.scss => rectangle-annotation-dialog/rectangle-annotation-dialog.component.scss} (84%) rename apps/red-ui/src/app/modules/file-preview/dialogs/{manual-redaction-dialog/manual-annotation-dialog.component.ts => rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts} (63%) diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component.ts index dccb2181d..457bd752c 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component.ts @@ -11,12 +11,7 @@ import { MatOption, MatSelect, MatSelectTrigger } from '@angular/material/select import { NgForOf, NgIf } from '@angular/common'; import { MatTooltip } from '@angular/material/tooltip'; import { TranslateModule } from '@ngx-translate/core'; - -export interface LegalBasisOption { - label?: string; - legalBasis?: string; - description?: string; -} +import { LegalBasisOption } from '../../utils/dialog-types'; @Component({ templateUrl: './change-legal-basis-dialog.component.html', diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts index 2191aff10..8f3a13cb2 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts @@ -26,8 +26,7 @@ import { ValueColumn, } from '../../components/selected-annotations-table/selected-annotations-table.component'; import { getEditRedactionOptions } from '../../utils/dialog-options'; -import { EditRedactionData, EditRedactionOption, EditRedactResult } from '../../utils/dialog-types'; -import { LegalBasisOption } from '../manual-redaction-dialog/manual-annotation-dialog.component'; +import { EditRedactionData, EditRedactionOption, EditRedactResult, LegalBasisOption } from '../../utils/dialog-types'; import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component'; import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option'; diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts index df634df2e..243f88bef 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts @@ -26,17 +26,11 @@ import { MatOption, MatSelect, MatSelectTrigger } from '@angular/material/select import { MatTooltip } from '@angular/material/tooltip'; import { TranslateModule } from '@ngx-translate/core'; import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option'; -import { ForceAnnotationOption, RedactOrHintOption } from '../../utils/dialog-types'; -import { getForceAnnotationOptions, getRedactOrHintOptions } from '../../utils/dialog-options'; +import { ForceAnnotationOption, LegalBasisOption } from '../../utils/dialog-types'; +import { getForceAnnotationOptions } from '../../utils/dialog-options'; import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component'; import { SystemDefaults } from '../../../account/utils/dialog-defaults'; -export interface LegalBasisOption { - label?: string; - legalBasis?: string; - description?: string; -} - const DOCUMINE_LEGAL_BASIS = 'n-a.'; @Component({ diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.html similarity index 71% rename from apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.html rename to apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.html index ea503b117..57cb3dbf3 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.html +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.html @@ -3,35 +3,11 @@
- - - -
- -
- {{ form.get('selectedText').value }} - -
- - -
- -
- -
+
-
+
-
+
diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.scss b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.scss similarity index 84% rename from apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.scss rename to apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.scss index a0421d753..a60ee0967 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.scss @@ -2,6 +2,11 @@ width: 100%; } +.dialog-content { + height: 650px; + overflow-y: auto; +} + .apply-on-multiple-pages { min-height: 55px; display: flex; diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts similarity index 63% rename from apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts rename to apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts index 4755981ef..7aaf1072c 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts @@ -1,24 +1,23 @@ -import { Component, Inject, OnChanges, OnInit, SimpleChanges } from '@angular/core'; -import { ReactiveFormsModule, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, ReactiveFormsModule, UntypedFormGroup, Validators } from '@angular/forms'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { - BaseDialogComponent, CircleButtonComponent, HasScrollbarDirective, IconButtonComponent, IqserDenyDirective, + IqserDialogComponent, IqserPermissionsService, + Toaster, } from '@iqser/common-ui'; import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper'; -import { Dictionary, Dossier, File, IAddRedactionRequest, SuperTypes } from '@red/domain'; +import { Dictionary, Dossier, File, IAddRedactionRequest, IManualRedactionEntry, SuperTypes } from '@red/domain'; import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service'; import { DictionaryService } from '@services/entity-services/dictionary.service'; import { JustificationsService } from '@services/entity-services/justifications.service'; import { Roles } from '@users/roles'; import { firstValueFrom } from 'rxjs'; import { ManualRedactionService } from '../../services/manual-redaction.service'; -import { REDAnnotationManager } from '../../../pdf-viewer/services/annotation-manager.service'; import { NgForOf, NgIf } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; import { MatFormField } from '@angular/material/form-field'; @@ -26,23 +25,28 @@ import { MatOption, MatSelect, MatSelectTrigger } from '@angular/material/select import { MatTooltip } from '@angular/material/tooltip'; import { MatCheckbox } from '@angular/material/checkbox'; import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option'; -import { RectangleRedactOption, RectangleRedactOptions, RedactOrHintOption } from '../../utils/dialog-types'; +import { LegalBasisOption, RectangleRedactOption, RectangleRedactOptions } from '../../utils/dialog-types'; import { getRectangleRedactOptions } from '../../utils/dialog-options'; import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component'; import { SystemDefaults } from '../../../account/utils/dialog-defaults'; import { validatePageRange } from '../../utils/form-validators'; +import { getMultiplePagesRectangle } from '../../utils/enhance-manual-redaction-request.utils'; -export interface LegalBasisOption { - label?: string; - legalBasis?: string; - description?: string; +interface RectangleDialogData { + dossierId: string; + manualRedactionEntryWrapper: ManualRedactionEntryWrapper; + file: File; +} +export interface RectangleDialogResult { + annotation: IManualRedactionEntry; + dictionary: Dictionary; } export const NON_READABLE_CONTENT = 'non-readable content'; @Component({ - templateUrl: './manual-annotation-dialog.component.html', - styleUrls: ['./manual-annotation-dialog.component.scss'], + templateUrl: './rectangle-annotation-dialog.component.html', + styleUrls: ['./rectangle-annotation-dialog.component.scss'], standalone: true, imports: [ ReactiveFormsModule, @@ -63,29 +67,30 @@ export const NON_READABLE_CONTENT = 'non-readable content'; ], providers: [ManualRedactionService], }) -export class ManualAnnotationDialogComponent extends BaseDialogComponent implements OnInit { +export class RectangleAnnotationDialog + extends IqserDialogComponent + implements OnInit +{ readonly #dossier: Dossier; protected readonly roles = Roles; protected readonly options: DetailsRadioOption[]; protected isDictionaryRequest: boolean; protected isFalsePositiveRequest: boolean; - protected isEditingSelectedText = false; - protected applyOnMultiplePages = false; protected manualRedactionTypeExists = true; protected possibleDictionaries: Dictionary[] = []; protected legalOptions: LegalBasisOption[] = []; + readonly form: UntypedFormGroup; constructor( - readonly iqserPermissionsService: IqserPermissionsService, + private readonly iqserPermissionsService: IqserPermissionsService, private readonly _justificationsService: JustificationsService, private readonly _manualRedactionService: ManualRedactionService, - activeDossiersService: ActiveDossiersService, + private readonly activeDossiersService: ActiveDossiersService, private readonly _dictionaryService: DictionaryService, - protected readonly _dialogRef: MatDialogRef, - private readonly _annotationManager: REDAnnotationManager, - @Inject(MAT_DIALOG_DATA) readonly data: { manualRedactionEntryWrapper: ManualRedactionEntryWrapper; dossierId: string; file: File }, + private readonly _formBuilder: FormBuilder, + private readonly _toaster: Toaster, ) { - super(_dialogRef); + super(); this.#dossier = activeDossiersService.find(this.data.dossierId); this.isFalsePositiveRequest = this.data.manualRedactionEntryWrapper.type === 'FALSE_POSITIVE'; @@ -111,10 +116,6 @@ export class ManualAnnotationDialogComponent extends BaseDialogComponent impleme return this._manualRedactionService.getTitle(this.data.manualRedactionEntryWrapper.type); } - get isRectangle() { - return !!this.data.manualRedactionEntryWrapper.manualRedactionEntry.rectangle; - } - get displayedDictionaryLabel() { const dictType = this.form.get('dictionary').value; if (dictType) { @@ -124,7 +125,7 @@ export class ManualAnnotationDialogComponent extends BaseDialogComponent impleme } get disabled() { - return this.form.invalid || (this.applyOnMultiplePages && !this.form.get('multiplePages')?.value); + return this.form.invalid; } async ngOnInit() { @@ -142,21 +143,17 @@ export class ManualAnnotationDialogComponent extends BaseDialogComponent impleme this.legalOptions.sort((a, b) => a.label.localeCompare(b.label)); this.#selectReason(); - - if (!this.isRectangle) { - this.#formatSelectedTextValue(); - } } save() { this.#enhanceManualRedaction(this.data.manualRedactionEntryWrapper.manualRedactionEntry); try { - const annotations = - this.isRectangle && !!this.form.get('multiplePages').value - ? this.#getRectangles() - : [this.data.manualRedactionEntryWrapper]; - this._dialogRef.close({ - annotations, + const annotation = + this.form.get('option').value.value === RectangleRedactOptions.MULTIPLE_PAGES + ? getMultiplePagesRectangle(this.#multiplePagesRectangleData).manualRedactionEntry + : this.data.manualRedactionEntryWrapper; + super.close({ + annotation, dictionary: this.possibleDictionaries.find(d => d.type === this.form.get('dictionary').value), }); } catch (e) { @@ -164,47 +161,12 @@ export class ManualAnnotationDialogComponent extends BaseDialogComponent impleme } } - close() { - super.close(); - if (this.isRectangle) { - this._annotationManager.delete(this._annotationManager.selected[0].Id); - } - } - - #getRectangles() { - const quads = this.data.manualRedactionEntryWrapper.manualRedactionEntry.positions.find(a => !!a); - const value: string = this.form.get('multiplePages').value.replace(/[^0-9-,]/g, ''); - const entry = { ...this.data.manualRedactionEntryWrapper.manualRedactionEntry }; - const wrapper = { ...this.data.manualRedactionEntryWrapper }; - const wrappers: ManualRedactionEntryWrapper[] = [wrapper]; - - value.split(',').forEach(range => { - const splitted = range.split('-'); - const startPage = parseInt(splitted[0], 10); - const endPage = splitted.length > 1 ? parseInt(splitted[1], 10) : startPage; - if (!startPage || !endPage || startPage > this.data.file.numberOfPages || endPage > this.data.file.numberOfPages) { - throw new Error(); - } - - for (let page = startPage; page <= endPage; page++) { - if (page === wrapper.manualRedactionEntry.positions[0].page) { - continue; - } - const manualRedactionEntry = { ...entry, positions: [{ ...quads, page }] }; - wrappers.push({ ...wrapper, manualRedactionEntry }); - } - }); - - return wrappers; - } - - #formatSelectedTextValue() { - this.data.manualRedactionEntryWrapper.manualRedactionEntry.value = - this.data.manualRedactionEntryWrapper.manualRedactionEntry.value.replace( - // eslint-disable-next-line no-control-regex,max-len - /([^\s\d-]{2,})[-\u00AD]\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]/gi, - '$1', - ); + get #multiplePagesRectangleData() { + return { + manualRedactionEntryWrapper: this.data.manualRedactionEntryWrapper, + pages: this.form.get('option').value.additionalInput.value, + file: this.data.file, + }; } #getForm() { @@ -217,7 +179,6 @@ export class ManualAnnotationDialogComponent extends BaseDialogComponent impleme : [this.manualRedactionTypeExists ? SuperTypes.ManualRedaction : null, Validators.required], comment: [null], classification: [NON_READABLE_CONTENT], - multiplePages: '', option: [this.#getOption(SystemDefaults.RECTANGLE_REDACT_DEFAULT), validatePageRange()], }); } @@ -243,9 +204,7 @@ export class ManualAnnotationDialogComponent extends BaseDialogComponent impleme const commentValue = this.form.get('comment').value; addRedactionRequest.comment = commentValue ? { text: commentValue } : null; addRedactionRequest.section = this.form.get('section').value; - addRedactionRequest.value = addRedactionRequest.rectangle - ? this.form.get('classification').value - : this.form.get('selectedText').value; + addRedactionRequest.value = this.form.get('classification').value; } #getOption(option: RectangleRedactOption): DetailsRadioOption { diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts index 163b8363c..1bca4ff37 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts @@ -23,13 +23,13 @@ import { } from '../../components/selected-annotations-table/selected-annotations-table.component'; import { getRedactOrHintOptions } from '../../utils/dialog-options'; import { + LegalBasisOption, RedactOrHintOption, RedactOrHintOptions, RedactRecommendationData, RedactRecommendationResult, ResizeOptions, } from '../../utils/dialog-types'; -import { LegalBasisOption } from '../manual-redaction-dialog/manual-annotation-dialog.component'; @Component({ templateUrl: './redact-recommendation-dialog.component.html', diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts index 6a9d46536..21c95b325 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts @@ -21,8 +21,14 @@ import { firstValueFrom, Observable } from 'rxjs'; import { map, tap } from 'rxjs/operators'; import { SystemDefaultOption, SystemDefaults } from '../../../account/utils/dialog-defaults'; import { getRedactOrHintOptions } from '../../utils/dialog-options'; -import { RedactOrHintOption, RedactOrHintOptions, RedactTextData, RedactTextResult, ResizeOptions } from '../../utils/dialog-types'; -import { LegalBasisOption } from '../manual-redaction-dialog/manual-annotation-dialog.component'; +import { + LegalBasisOption, + RedactOrHintOption, + RedactOrHintOptions, + RedactTextData, + RedactTextResult, + ResizeOptions, +} from '../../utils/dialog-types'; import { enhanceManualRedactionRequest, EnhanceRequestData } from '../../utils/enhance-manual-redaction-request.utils'; const MAXIMUM_TEXT_AREA_WIDTH = 421; diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts index 7701d687c..e6d6227e8 100644 --- a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts @@ -21,7 +21,7 @@ import { copyLocalStorageFiltersValues, FilterService, NestedFilter, processFilt import { AutoUnsubscribe, Bind, bool, List, OnAttach, OnDetach } from '@iqser/common-ui/lib/utils'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { ManualRedactionEntryTypes, ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper'; -import { Dictionary, File, ViewModes } from '@red/domain'; +import { File, ViewModes } from '@red/domain'; import { ConfigService } from '@services/config.service'; import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service'; import { DossiersService } from '@services/dossiers/dossiers.service'; @@ -71,6 +71,7 @@ import { TypeFilterComponent } from '@shared/components/type-filter/type-filter. import { FileHeaderComponent } from './components/file-header/file-header.component'; import { StructuredComponentManagementComponent } from './components/structured-component-management/structured-component-management.component'; import { DocumentInfoService } from './services/document-info.service'; +import { RectangleAnnotationDialog } from './dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component'; @Component({ templateUrl: './file-preview-screen.component.html', @@ -363,29 +364,27 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this._viewerHeaderService.resetLayers(); } - openManualAnnotationDialog(manualRedactionEntryWrapper: ManualRedactionEntryWrapper) { + async openRectangleAnnotationDialog(manualRedactionEntryWrapper: ManualRedactionEntryWrapper) { const file = this.state.file(); - this._dialogService.openDialog( - 'manualAnnotation', - { manualRedactionEntryWrapper, dossierId: this.dossierId, file }, - (result: { annotations: ManualRedactionEntryWrapper[]; dictionary?: Dictionary }) => { - const selectedAnnotations = this._annotationManager.selected; - if (selectedAnnotations.length > 0) { - this._annotationManager.delete([selectedAnnotations[0].Id]); - } + const data = { manualRedactionEntryWrapper, file, dossierId: this.dossierId }; + const result = await this._iqserDialog.openDefault(RectangleAnnotationDialog, { data }).result(); - const add$ = this._manualRedactionService.addAnnotation( - result.annotations.map(w => w.manualRedactionEntry).filter(e => e.positions[0].page <= file.numberOfPages), - this.dossierId, - this.fileId, - { dictionaryLabel: result.dictionary?.label }, - ); + if (!result) { + return; + } - const addAndReload$ = add$.pipe(switchMap(() => this._filesService.reload(this.dossierId, file))); - return firstValueFrom(addAndReload$.pipe(catchError(() => of(undefined)))); - }, - ); + const selectedAnnotations = this._annotationManager.selected; + if (selectedAnnotations.length > 0) { + this._annotationManager.delete([selectedAnnotations[0].Id]); + } + + const add$ = this._manualRedactionService.addAnnotation([result.annotation], this.dossierId, this.fileId, { + dictionaryLabel: result.dictionary?.label, + }); + + const addAndReload$ = add$.pipe(switchMap(() => this._filesService.reload(this.dossierId, file))); + return firstValueFrom(addAndReload$.pipe(catchError(() => of(undefined)))); } async viewerReady(pageNumber?: string) { @@ -622,7 +621,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni .subscribe(); this.addActiveScreenSubscription = this.pdfProxyService.manualAnnotationRequested$.subscribe($event => { - this.openManualAnnotationDialog($event); + this.openRectangleAnnotationDialog($event).then(); }); this.addActiveScreenSubscription = this.pdfProxyService.redactTextRequested$.subscribe($event => { diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts index bd89af035..aed308032 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts @@ -48,7 +48,7 @@ import { FilePreviewDialogService } from './file-preview-dialog.service'; import { FilePreviewStateService } from './file-preview-state.service'; import { ManualRedactionService } from './manual-redaction.service'; import { SkippedService } from './skipped.service'; -import { NON_READABLE_CONTENT } from '../dialogs/manual-redaction-dialog/manual-annotation-dialog.component'; +import { NON_READABLE_CONTENT } from '../dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component'; @Injectable() export class AnnotationActionsService { diff --git a/apps/red-ui/src/app/modules/file-preview/services/file-preview-dialog.service.ts b/apps/red-ui/src/app/modules/file-preview/services/file-preview-dialog.service.ts index 59af5fef2..4028b154a 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/file-preview-dialog.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/file-preview-dialog.service.ts @@ -5,9 +5,8 @@ import { ChangeLegalBasisDialogComponent } from '../dialogs/change-legal-basis-d import { DocumentInfoDialogComponent } from '../dialogs/document-info-dialog/document-info-dialog.component'; import { ForceAnnotationDialogComponent } from '../dialogs/force-redaction-dialog/force-annotation-dialog.component'; import { HighlightActionDialogComponent } from '../dialogs/highlight-action-dialog/highlight-action-dialog.component'; -import { ManualAnnotationDialogComponent } from '../dialogs/manual-redaction-dialog/manual-annotation-dialog.component'; -type DialogType = 'confirm' | 'documentInfo' | 'changeLegalBasis' | 'forceAnnotation' | 'manualAnnotation' | 'highlightAction'; +type DialogType = 'confirm' | 'documentInfo' | 'changeLegalBasis' | 'forceAnnotation' | 'highlightAction'; @Injectable() export class FilePreviewDialogService extends DialogService { @@ -26,10 +25,6 @@ export class FilePreviewDialogService extends DialogService { forceAnnotation: { component: ForceAnnotationDialogComponent, }, - manualAnnotation: { - component: ManualAnnotationDialogComponent, - dialogConfig: { autoFocus: true }, - }, highlightAction: { component: HighlightActionDialogComponent, }, diff --git a/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts b/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts index 0ed5aa351..675ad5407 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts @@ -139,7 +139,9 @@ export class ManualRedactionService extends GenericService { } add(body: List, dossierId: string, fileId: string, bulkLocal = false) { + bulkLocal = bulkLocal || !!body[0].pageNumbers.length; const bulkPath = bulkLocal ? this.#bulkLocal : this.#bulkRedaction; + return this._post(bulkLocal ? body[0] : body, `${bulkPath}/add/${dossierId}/${fileId}`).pipe(this.#log('Add', body)); } diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts index 8f5830e0f..19f6b7b79 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts @@ -148,7 +148,7 @@ export const getResizeRedactionOptions = ( tooltip: !dictBasedType ? translations.inDossier.tooltip : null, icon: FOLDER_ICON, value: ResizeOptions.IN_DOSSIER, - extraOption: { + additionalCheck: { label: translations.inDossier.extraOptionLabel, checked: applyToAllDossiers, hidden: !isApprover, diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts index 94aff4a00..2b8a44dc4 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts @@ -47,6 +47,12 @@ export const RemoveAnnotationOptions = RemoveRedactionOptions; export type RemoveRedactionOption = keyof typeof RemoveRedactionOptions; export type RemoveAnnotationOption = RemoveRedactionOption; +export interface LegalBasisOption { + label?: string; + legalBasis?: string; + description?: string; +} + export interface RedactTextData { manualRedactionEntryWrapper: ManualRedactionEntryWrapper; dossierId: string; diff --git a/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts b/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts index 25291fd22..701028276 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts @@ -1,5 +1,6 @@ -import { Dictionary, IAddRedactionRequest, SuperType } from '@red/domain'; -import { LegalBasisOption } from '../dialogs/manual-redaction-dialog/manual-annotation-dialog.component'; +import { Dictionary, File, IAddRedactionRequest, SuperType } from '@red/domain'; +import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper'; +import { LegalBasisOption } from './dialog-types'; export interface EnhanceRequestData { readonly type: SuperType | null; @@ -12,6 +13,12 @@ export interface EnhanceRequestData { readonly applyToAllDossiers: boolean; } +interface MultiplePagesRectangleData { + manualRedactionEntryWrapper: ManualRedactionEntryWrapper; + pages: string; + file: File; +} + export const enhanceManualRedactionRequest = (addRedactionRequest: IAddRedactionRequest, data: EnhanceRequestData) => { addRedactionRequest.type = data.type; addRedactionRequest.section = null; @@ -38,3 +45,31 @@ export const enhanceManualRedactionRequest = (addRedactionRequest: IAddRedaction addRedactionRequest.comment = commentValue ? { text: commentValue } : null; addRedactionRequest.addToAllDossiers = data.isApprover && data.dictionaryRequest && data.applyToAllDossiers; }; + +export const getMultiplePagesRectangle = (data: MultiplePagesRectangleData) => { + const value: string = data.pages.replace(/[^0-9-,]/g, ''); + const entry = { ...data.manualRedactionEntryWrapper.manualRedactionEntry, pageNumbers: [] }; + const wrapper = { + ...data.manualRedactionEntryWrapper, + manualRedactionEntry: entry, + }; + + value.split(',').forEach(range => { + const splitted = range.split('-'); + const startPage = parseInt(splitted[0], 10); + const endPage = splitted.length > 1 ? parseInt(splitted[1], 10) : startPage; + if (!startPage || !endPage || startPage > data.file.numberOfPages || endPage > data.file.numberOfPages) { + throw new Error(); + } + + for (let page = startPage; page <= endPage; page++) { + if (page === wrapper.manualRedactionEntry.positions[0].page) { + continue; + } + + wrapper.manualRedactionEntry.pageNumbers.push(page); + } + }); + + return wrapper; +}; diff --git a/apps/red-ui/src/assets/config/config.json b/apps/red-ui/src/assets/config/config.json index deb14e6da..5f6c0ce6e 100644 --- a/apps/red-ui/src/assets/config/config.json +++ b/apps/red-ui/src/assets/config/config.json @@ -1,7 +1,7 @@ { "ADMIN_CONTACT_NAME": null, "ADMIN_CONTACT_URL": null, - "API_URL": "https://dan1.iqser.cloud", + "API_URL": "https://dan2.iqser.cloud", "APP_NAME": "RedactManager", "IS_DOCUMINE": false, "RULE_EDITOR_DEV_ONLY": false, @@ -13,7 +13,7 @@ "MAX_RETRIES_ON_SERVER_ERROR": 3, "OAUTH_CLIENT_ID": "redaction", "OAUTH_IDP_HINT": null, - "OAUTH_URL": "https://dan1.iqser.cloud/auth", + "OAUTH_URL": "https://dan2.iqser.cloud/auth", "RECENT_PERIOD_IN_HOURS": 24, "SELECTION_MODE": "structural", "MANUAL_BASE_URL": "https://docs.redactmanager.com/preview", diff --git a/libs/common-ui b/libs/common-ui index 34387d49d..3c89b8f7e 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 34387d49d29ba6449c1311cc1c5434b540398660 +Subproject commit 3c89b8f7e71eb9253aa40f40c1598eac2c400c71 diff --git a/libs/red-domain/src/lib/redaction-log/add-redaction.request.ts b/libs/red-domain/src/lib/redaction-log/add-redaction.request.ts index 189d16a88..2665fa420 100644 --- a/libs/red-domain/src/lib/redaction-log/add-redaction.request.ts +++ b/libs/red-domain/src/lib/redaction-log/add-redaction.request.ts @@ -14,4 +14,6 @@ export interface IAddRedactionRequest { section?: string; rectangle?: boolean; addToAllDossiers?: boolean; + pageNumbers?: []; + caseSensitive?: boolean; } From 2377fbff55ce620ff10e5a393dc6912094343ea4 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Sat, 5 Oct 2024 22:55:28 +0300 Subject: [PATCH 062/125] RED-7340 - removed dictionary & false positive logic from rectangle annotation dialog --- ...rectangle-annotation-dialog.component.html | 41 +++--------- .../rectangle-annotation-dialog.component.ts | 66 +++---------------- .../file-preview-screen.component.ts | 4 +- .../services/manual-redaction.service.ts | 4 +- 4 files changed, 21 insertions(+), 94 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.html index 57cb3dbf3..deeeb9113 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.html +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.html @@ -1,6 +1,6 @@
-
+
-
- - - - - - {{ displayedDictionaryLabel }} - - {{ dictionary.label }} - - - -
- -
+
- - {{ option.label }} - + @for (option of legalOptions; track option) { + + {{ option.label }} + + }
-
+
diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts index 7aaf1072c..4e565ff06 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts @@ -7,13 +7,11 @@ import { IconButtonComponent, IqserDenyDirective, IqserDialogComponent, - IqserPermissionsService, Toaster, } from '@iqser/common-ui'; import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper'; -import { Dictionary, Dossier, File, IAddRedactionRequest, IManualRedactionEntry, SuperTypes } from '@red/domain'; +import { Dossier, File, IAddRedactionRequest, IManualRedactionEntry, SuperTypes } from '@red/domain'; import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service'; -import { DictionaryService } from '@services/entity-services/dictionary.service'; import { JustificationsService } from '@services/entity-services/justifications.service'; import { Roles } from '@users/roles'; import { firstValueFrom } from 'rxjs'; @@ -39,7 +37,6 @@ interface RectangleDialogData { } export interface RectangleDialogResult { annotation: IManualRedactionEntry; - dictionary: Dictionary; } export const NON_READABLE_CONTENT = 'non-readable content'; @@ -74,30 +71,19 @@ export class RectangleAnnotationDialog readonly #dossier: Dossier; protected readonly roles = Roles; protected readonly options: DetailsRadioOption[]; - protected isDictionaryRequest: boolean; - protected isFalsePositiveRequest: boolean; - protected manualRedactionTypeExists = true; - protected possibleDictionaries: Dictionary[] = []; protected legalOptions: LegalBasisOption[] = []; + readonly form: UntypedFormGroup; constructor( - private readonly iqserPermissionsService: IqserPermissionsService, - private readonly _justificationsService: JustificationsService, - private readonly _manualRedactionService: ManualRedactionService, private readonly activeDossiersService: ActiveDossiersService, - private readonly _dictionaryService: DictionaryService, + private readonly _justificationsService: JustificationsService, private readonly _formBuilder: FormBuilder, private readonly _toaster: Toaster, ) { super(); this.#dossier = activeDossiersService.find(this.data.dossierId); - this.isFalsePositiveRequest = this.data.manualRedactionEntryWrapper.type === 'FALSE_POSITIVE'; - this.isDictionaryRequest = this.data.manualRedactionEntryWrapper.type === 'DICTIONARY' || this.isFalsePositiveRequest; - - this.manualRedactionTypeExists = this._dictionaryService.hasManualType(this.#dossier.dossierTemplateId); - this.options = getRectangleRedactOptions(); this.form = this.#getForm(); @@ -112,27 +98,7 @@ export class RectangleAnnotationDialog } } - get title() { - return this._manualRedactionService.getTitle(this.data.manualRedactionEntryWrapper.type); - } - - get displayedDictionaryLabel() { - const dictType = this.form.get('dictionary').value; - if (dictType) { - return this.possibleDictionaries.find(d => d.type === dictType).label; - } - return null; - } - - get disabled() { - return this.form.invalid; - } - async ngOnInit() { - this.possibleDictionaries = this.isDictionaryRequest - ? this._dictionaryService.getDictionariesOptions(this.#dossier.dossierTemplateId) - : this._dictionaryService.getRedactionTypes(this.#dossier.dossierTemplateId); - const data = await firstValueFrom(this._justificationsService.getForDossierTemplate(this.#dossier.dossierTemplateId)); this.legalOptions = data.map(lbm => ({ legalBasis: lbm.reason, @@ -148,13 +114,13 @@ export class RectangleAnnotationDialog save() { this.#enhanceManualRedaction(this.data.manualRedactionEntryWrapper.manualRedactionEntry); try { - const annotation = + const annotation = ( this.form.get('option').value.value === RectangleRedactOptions.MULTIPLE_PAGES - ? getMultiplePagesRectangle(this.#multiplePagesRectangleData).manualRedactionEntry - : this.data.manualRedactionEntryWrapper; + ? getMultiplePagesRectangle(this.#multiplePagesRectangleData) + : this.data.manualRedactionEntryWrapper + ).manualRedactionEntry; super.close({ annotation, - dictionary: this.possibleDictionaries.find(d => d.type === this.form.get('dictionary').value), }); } catch (e) { this._toaster.error(_('manual-annotation.dialog.error')); @@ -173,10 +139,7 @@ export class RectangleAnnotationDialog return this._formBuilder.group({ selectedText: this.data?.manualRedactionEntryWrapper?.manualRedactionEntry?.value, section: [null], - reason: this.isDictionaryRequest ? [null] : [null, Validators.required], - dictionary: this.isDictionaryRequest - ? [this.isFalsePositiveRequest ? 'false_positive' : null, Validators.required] - : [this.manualRedactionTypeExists ? SuperTypes.ManualRedaction : null, Validators.required], + reason: [null, Validators.required], comment: [null], classification: [NON_READABLE_CONTENT], option: [this.#getOption(SystemDefaults.RECTANGLE_REDACT_DEFAULT), validatePageRange()], @@ -185,22 +148,13 @@ export class RectangleAnnotationDialog #enhanceManualRedaction(addRedactionRequest: IAddRedactionRequest) { const legalOption: LegalBasisOption = this.form.get('reason').value; - addRedactionRequest.type = this.form.get('dictionary').value; + addRedactionRequest.type = SuperTypes.ManualRedaction; if (legalOption) { addRedactionRequest.reason = legalOption.description; addRedactionRequest.legalBasis = legalOption.legalBasis; } - if (this.iqserPermissionsService.has(Roles.getRss)) { - const selectedType = this.possibleDictionaries.find(d => d.type === addRedactionRequest.type); - addRedactionRequest.addToDictionary = selectedType.hasDictionary; - } else { - addRedactionRequest.addToDictionary = this.isDictionaryRequest && addRedactionRequest.type !== 'dossier_redaction'; - } - - if (!addRedactionRequest.reason) { - addRedactionRequest.reason = 'Dictionary Request'; - } + addRedactionRequest.addToDictionary = false; const commentValue = this.form.get('comment').value; addRedactionRequest.comment = commentValue ? { text: commentValue } : null; addRedactionRequest.section = this.form.get('section').value; diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts index e51db9282..512f783bd 100644 --- a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts @@ -324,9 +324,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this._annotationManager.delete([selectedAnnotations[0].Id]); } - const add$ = this._manualRedactionService.addAnnotation([result.annotation], this.dossierId, this.fileId, { - dictionaryLabel: result.dictionary?.label, - }); + const add$ = this._manualRedactionService.addAnnotation([result.annotation], this.dossierId, this.fileId); const addAndReload$ = add$.pipe(switchMap(() => this._filesService.reload(this.dossierId, file))); return firstValueFrom(addAndReload$.pipe(catchError(() => of(undefined)))); diff --git a/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts b/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts index 675ad5407..e8017d6df 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts @@ -97,7 +97,7 @@ export class ManualRedactionService extends GenericService { : this.#showToast(options?.hint ? 'force-hint' : 'add'); const canAddRedaction = this._iqserPermissionsService.has(Roles.redactions.write); if (canAddRedaction) { - return this.add(requests, dossierId, fileId, options.bulkLocal).pipe(toast); + return this.add(requests, dossierId, fileId, options?.bulkLocal).pipe(toast); } return of(undefined); @@ -139,7 +139,7 @@ export class ManualRedactionService extends GenericService { } add(body: List, dossierId: string, fileId: string, bulkLocal = false) { - bulkLocal = bulkLocal || !!body[0].pageNumbers.length; + bulkLocal = bulkLocal || !!body[0].pageNumbers?.length; const bulkPath = bulkLocal ? this.#bulkLocal : this.#bulkRedaction; return this._post(bulkLocal ? body[0] : body, `${bulkPath}/add/${dossierId}/${fileId}`).pipe(this.#log('Add', body)); From 671c44438db69f47af27f65a20cd1400b0ff551c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 30 Sep 2024 18:30:30 +0300 Subject: [PATCH 063/125] RED-10034: File workload improvementes - WIP --- .../file-workload.component.html | 10 +- .../file-workload/file-workload.component.ts | 121 ++++++++++-------- 2 files changed, 72 insertions(+), 59 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.html b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.html index 32b509d90..47d3dc13b 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.html +++ b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.html @@ -32,11 +32,11 @@ -@if (displayedAnnotations$ | async; as annotations) { +@if (filteredAnnotations$ | async; as annotations) {
@@ -112,7 +112,7 @@ > @@ -200,7 +200,7 @@
} @@ -224,7 +224,7 @@ - + diff --git a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts index 6ccf8e4c7..f65803d1d 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts @@ -9,6 +9,7 @@ import { OnDestroy, OnInit, TemplateRef, + untracked, viewChild, } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; @@ -89,23 +90,30 @@ const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown']; ], }) export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, OnDestroy { - private readonly _annotationsElement = viewChild('annotationsElement'); - private readonly _quickNavigationElement = viewChild('quickNavigation'); readonly multiSelectTemplate = viewChild>('multiSelect'); - readonly #isIqserDevMode = this._userPreferenceService.isIqserDevMode; + readonly annotationsList$: Observable[]>; + readonly allPages = computed(() => Array.from({ length: this.state.file()?.numberOfPages }, (_x, i) => i + 1)); protected readonly iconButtonTypes = IconButtonTypes; protected readonly circleButtonTypes = CircleButtonTypes; - protected readonly displayedAnnotations$: Observable[]>>; + protected readonly filteredAnnotations$: Observable[]>>; protected readonly title = computed(() => this.viewModeService.isEarmarks() ? _('file-preview.tabs.highlights.label') : _('file-preview.tabs.annotations.label'), ); protected readonly currentPageIsExcluded = computed(() => this.state.file().excludedPages.includes(this.pdf.currentPage())); protected readonly translations = workloadTranslations; protected readonly isDocumine = getConfig().IS_DOCUMINE; + readonly showAnalysisDisabledBanner = computed(() => { + const file = this.state.file(); + return this.isDocumine && file.excludedFromAutomaticAnalysis && file.workflowStatus !== WorkflowFileStatuses.APPROVED; + }); protected displayedAnnotations = new Map(); + readonly activeAnnotations = computed(() => this.displayedAnnotations.get(this.pdf.currentPage()) || []); protected displayedPages: number[] = []; protected pagesPanelActive = true; protected enabledFilters = []; + private readonly _annotationsElement = viewChild('annotationsElement'); + private readonly _quickNavigationElement = viewChild('quickNavigation'); + readonly #isIqserDevMode = this._userPreferenceService.isIqserDevMode; #displayedPagesChanged = false; constructor( @@ -129,10 +137,9 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On ) { super(); - // TODO: ngOnDetach is not called here, so we need to unsubscribe manually - this.addActiveScreenSubscription = this.pdf.currentPage$.subscribe(pageNumber => { + effect(() => { this._scrollViews(); - this.scrollAnnotationsToPage(pageNumber, 'always'); + this.scrollAnnotationsToPage(this.pdf.currentPage(), 'always'); }); this.addActiveScreenSubscription = this.listingService.selected$.subscribe(annotationIds => { @@ -146,7 +153,11 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On this.handleKeyEvent($event); }); - this.displayedAnnotations$ = this._displayedAnnotations$; + this.filteredAnnotations$ = this._filteredAnnotations$; + + this.annotationsList$ = combineLatest([this.filteredAnnotations$, this.pdf.currentPage$]).pipe( + map(([annotations, page]) => annotations.get(page)), + ); effect(() => { if (this.multiSelectService.inactive()) { @@ -169,20 +180,11 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On ); } - get activeAnnotations(): AnnotationWrapper[] { - return this.displayedAnnotations.get(this.pdf.currentPage()) || []; - } - - get showAnalysisDisabledBanner() { - const file = this.state.file(); - return this.isDocumine && file.excludedFromAutomaticAnalysis && file.workflowStatus !== WorkflowFileStatuses.APPROVED; - } - private get _firstSelectedAnnotation() { return this.listingService.selected.length ? this.listingService.selected[0] : null; } - private get _displayedAnnotations$(): Observable[]>> { + private get _filteredAnnotations$(): Observable[]>> { const primary$ = this.filterService.getFilterModels$('primaryFilters'); const secondary$ = this.filterService.getFilterModels$('secondaryFilters'); @@ -205,10 +207,6 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On ); } - get #allPages() { - return Array.from({ length: this.state.file()?.numberOfPages }, (_x, i) => i + 1); - } - private static _scrollToFirstElement(elements: HTMLElement[], mode: 'always' | 'if-needed' = 'if-needed') { if (elements.length > 0) { scrollIntoView(elements[0], { @@ -222,12 +220,13 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On ngOnInit(): void { setTimeout(() => { - const showExcludePages = getLocalStorageDataByFileId(this.state.file()?.id, 'show-exclude-pages') ?? false; + const file = untracked(this.state.file); + const showExcludePages = getLocalStorageDataByFileId(file?.id, 'show-exclude-pages') ?? false; if (showExcludePages) { this.excludedPagesService.show(); } - const showDocumentInfo = getLocalStorageDataByFileId(this.state.file()?.id, 'show-document-info') ?? false; + const showDocumentInfo = getLocalStorageDataByFileId(file?.id, 'show-document-info') ?? false; if (showDocumentInfo) { this.documentInfoService.show(); } @@ -235,16 +234,20 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On } selectAllOnActivePage() { - this.listingService.selectAnnotations(this.activeAnnotations); + const activeAnnotations = untracked(this.activeAnnotations); + this.listingService.selectAnnotations(activeAnnotations); } deselectAllOnActivePage(): void { - this.listingService.deselect(this.activeAnnotations); - this.annotationManager.deselect(this.activeAnnotations); + const activeAnnotations = untracked(this.activeAnnotations); + this.listingService.deselect(activeAnnotations); + this.annotationManager.deselect(activeAnnotations); } @HostListener('window:keyup', ['$event']) handleKeyEvent($event: KeyboardEvent): void { + const multiSelectServiceInactive = untracked(this.multiSelectService.inactive); + if ( !ALL_HOTKEY_ARRAY.includes($event.key) || this._dialog.openDialogs.length || @@ -264,7 +267,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On // if we activated annotationsPanel - // select first annotation from this page in case there is no // selected annotation on this page and not in multi select mode - if (!this.pagesPanelActive && this.multiSelectService.inactive()) { + if (!this.pagesPanelActive && multiSelectServiceInactive) { this._documentViewer.clearSelection(); this.#selectFirstAnnotationOnCurrentPageIfNecessary(); } @@ -275,7 +278,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On if (!this.pagesPanelActive) { // Disable annotation navigation in multi select mode // => TODO: maybe implement selection on enter? - if (this.multiSelectService.inactive()) { + if (multiSelectServiceInactive) { this.navigateAnnotations($event); } } else { @@ -286,7 +289,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On } scrollAnnotations(): void { - const currentPage = this.pdf.currentPage(); + const currentPage = untracked(this.pdf.currentPage); if (this._firstSelectedAnnotation?.pageNumber === currentPage) { return; } @@ -294,27 +297,27 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On } scrollAnnotationsToPage(page: number, mode: 'always' | 'if-needed' = 'if-needed'): void { - if (this._annotationsElement()) { - const elements: HTMLElement[] = this._annotationsElement().nativeElement.querySelectorAll( - `div[anotation-page-header="${page}"]`, - ); + const annotationsElement = untracked(this._annotationsElement); + if (annotationsElement) { + const elements: HTMLElement[] = annotationsElement.nativeElement.querySelectorAll(`div[anotation-page-header="${page}"]`); FileWorkloadComponent._scrollToFirstElement(elements, mode); } } @Debounce() scrollToSelectedAnnotation(): void { - if (this.listingService.selected.length === 0 || !this._annotationsElement()) { + const annotationsElement = untracked(this._annotationsElement); + if (this.listingService.selected.length === 0 || annotationsElement) { return; } - const elements: HTMLElement[] = this._annotationsElement().nativeElement.querySelectorAll( + const elements: HTMLElement[] = annotationsElement.nativeElement.querySelectorAll( `[annotation-id="${this._firstSelectedAnnotation?.id}"]`, ); FileWorkloadComponent._scrollToFirstElement(elements); } scrollQuickNavigation(): void { - const currentPage = this.pdf.currentPage(); + const currentPage = untracked(this.pdf.currentPage); let quickNavPageIndex = this.displayedPages.findIndex(p => p >= currentPage); if (quickNavPageIndex === -1 || this.displayedPages[quickNavPageIndex] !== currentPage) { quickNavPageIndex = Math.max(0, quickNavPageIndex - 1); @@ -327,7 +330,8 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On } scrollQuickNavLast() { - this.pdf.navigateTo(this.state.file().numberOfPages); + const file = untracked(this.state.file); + this.pdf.navigateTo(file.numberOfPages); } preventKeyDefault($event: KeyboardEvent): void { @@ -345,11 +349,12 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On } navigateAnnotations($event: KeyboardEvent) { - const currentPage = this.pdf.currentPage(); + const currentPage = untracked(this.pdf.currentPage); + const activeAnnotations = untracked(this.activeAnnotations); if (!this._firstSelectedAnnotation || currentPage !== this._firstSelectedAnnotation.pageNumber) { if (this.displayedPages.indexOf(currentPage) !== -1) { // Displayed page has annotations - return this.listingService.selectAnnotations(this.activeAnnotations ? this.activeAnnotations[0] : null); + return this.listingService.selectAnnotations(activeAnnotations ? activeAnnotations[0] : null); } // Displayed page doesn't have annotations if ($event.key === 'ArrowDown') { @@ -422,14 +427,16 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On secondary: INestedFilter[] = [], componentReferenceIds: string[], ): Map { - const onlyPageWithAnnotations = this.viewModeService.onlyPagesWithAnnotations(); + const onlyPageWithAnnotations = untracked(this.viewModeService.onlyPagesWithAnnotations); + const isRedacted = untracked(this.viewModeService.isRedacted); + const allPages = untracked(this.allPages); if (!primary || primary.length === 0) { - const pages = onlyPageWithAnnotations ? [] : this.#allPages; + const pages = onlyPageWithAnnotations ? [] : allPages; this.#setDisplayedPages(pages); return; } - if (this.viewModeService.isRedacted()) { + if (isRedacted) { annotations = annotations.filter(a => !a.isRemoved); } @@ -447,7 +454,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On this.enabledFilters = this.filterService.enabledFlatFilters; if (this.enabledFilters.some(f => f.id === 'pages-without-annotations')) { if (this.enabledFilters.length === 1 && !onlyPageWithAnnotations) { - const pages = this.#allPages.filter(page => !pagesThatDisplayAnnotations.includes(page)); + const pages = allPages.filter(page => !pagesThatDisplayAnnotations.includes(page)); this.#setDisplayedPages(pages); } else { this.#setDisplayedPages([]); @@ -456,7 +463,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On } else if (this.enabledFilters.length || onlyPageWithAnnotations || componentReferenceIds) { this.#setDisplayedPages(pagesThatDisplayAnnotations); } else { - this.#setDisplayedPages(this.#allPages); + this.#setDisplayedPages(allPages); } this.displayedPages.sort((a, b) => a - b); @@ -464,18 +471,20 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On } #selectFirstAnnotationOnCurrentPageIfNecessary() { - const currentPage = this.pdf.currentPage(); + const currentPage = untracked(this.pdf.currentPage); + const activeAnnotations = untracked(this.activeAnnotations); if ( (!this._firstSelectedAnnotation || currentPage !== this._firstSelectedAnnotation.pageNumber) && this.displayedPages.indexOf(currentPage) >= 0 && - this.activeAnnotations.length > 0 + activeAnnotations.length > 0 ) { - this.listingService.selectAnnotations(this.activeAnnotations[0]); + this.listingService.selectAnnotations(activeAnnotations[0]); } } #navigatePages($event: KeyboardEvent) { - const pageIdx = this.displayedPages.indexOf(this.pdf.currentPage()); + const currentPage = untracked(this.pdf.currentPage); + const pageIdx = this.displayedPages.indexOf(currentPage); if ($event.key !== 'ArrowDown') { if (pageIdx === -1) { @@ -507,9 +516,10 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On } #nextPageWithAnnotations() { + const currentPage = untracked(this.pdf.currentPage); let idx = 0; for (const page of this.displayedPages) { - if (page > this.pdf.currentPage() && this.displayedAnnotations.get(page)) { + if (page > currentPage && this.displayedAnnotations.get(page)) { break; } ++idx; @@ -518,10 +528,11 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On } #prevPageWithAnnotations() { + const currentPage = untracked(this.pdf.currentPage); let idx = this.displayedPages.length - 1; const reverseDisplayedPages = [...this.displayedPages].reverse(); for (const page of reverseDisplayedPages) { - if (page < this.pdf.currentPage() && this.displayedAnnotations.get(page)) { + if (page < currentPage && this.displayedAnnotations.get(page)) { break; } --idx; @@ -530,8 +541,9 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On } #scrollQuickNavigationToPage(page: number) { - if (this._quickNavigationElement()) { - const elements: HTMLElement[] = this._quickNavigationElement().nativeElement.querySelectorAll(`#quick-nav-page-${page}`); + const quickNavigationElement = untracked(this._quickNavigationElement); + if (quickNavigationElement) { + const elements: HTMLElement[] = quickNavigationElement.nativeElement.querySelectorAll(`#quick-nav-page-${page}`); FileWorkloadComponent._scrollToFirstElement(elements); } } @@ -552,7 +564,8 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On } #scrollToFirstAnnotationPage(annotations: Map[]>) { - if (this.isDocumine && annotations.size && this.#displayedPagesChanged && !this.displayedPages.includes(this.pdf.currentPage())) { + const currentPage = untracked(this.pdf.currentPage); + if (this.isDocumine && annotations.size && this.#displayedPagesChanged && !this.displayedPages.includes(currentPage)) { const page = annotations.keys().next().value; this.pdf.navigateTo(page); } From 9fabb7223a61d829bd22840403c62a14cf8a6539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 7 Oct 2024 19:10:33 +0300 Subject: [PATCH 064/125] RED-10034: More performance improvements --- .../annotation-details.component.html | 34 +++++++++--------- .../annotation-details.component.ts | 35 ++++++++----------- .../annotation-wrapper.component.html | 18 +++++----- .../annotations-list.component.ts | 4 +-- 4 files changed, 44 insertions(+), 47 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotation-details/annotation-details.component.html b/apps/red-ui/src/app/modules/file-preview/components/annotation-details/annotation-details.component.html index c5dbee02b..4dffb7bf4 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/annotation-details/annotation-details.component.html +++ b/apps/red-ui/src/app/modules/file-preview/components/annotation-details/annotation-details.component.html @@ -1,29 +1,31 @@ -
- -
+@if (_noSelection() && _changesTooltip()) { +
+ +
+} - -
- +@if (_noSelection() && _engines()) { +
+
-
+
- +
- +} diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotation-details/annotation-details.component.ts b/apps/red-ui/src/app/modules/file-preview/components/annotation-details/annotation-details.component.ts index 2c647bd76..a092c15b3 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/annotation-details/annotation-details.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/annotation-details/annotation-details.component.ts @@ -1,4 +1,4 @@ -import { Component, inject, Input, OnChanges } from '@angular/core'; +import { Component, computed, inject, input, signal } from '@angular/core'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { KeysOf } from '@iqser/common-ui/lib/utils'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; @@ -33,30 +33,27 @@ const changesProperties: KeysOf[] = [ ]; @Component({ - selector: 'redaction-annotation-details [annotation]', + selector: 'redaction-annotation-details', templateUrl: './annotation-details.component.html', styleUrls: ['./annotation-details.component.scss'], standalone: true, imports: [NgIf, MatTooltip, MatIcon, CdkOverlayOrigin, NgForOf, CdkConnectedOverlay, TranslateModule], }) -export class AnnotationDetailsComponent implements OnChanges { - @Input() annotation: ListItem; - isPopoverOpen = false; - engines: Engine[]; - changesTooltip: string; - noSelection: boolean; +export class AnnotationDetailsComponent { + readonly annotation = input.required>(); + protected readonly _isPopoverOpen = signal(false); + protected readonly _engines = computed(() => this.#extractEngines(this.annotation().item).filter(engine => engine.show)); private readonly _translateService = inject(TranslateService); - private readonly _multiSelectService = inject(MultiSelectService); + protected readonly _changesTooltip = computed(() => { + const annotation = this.annotation().item; + const changes = changesProperties.filter(key => annotation[key]); - getChangesTooltip(): string | undefined { - const changes = changesProperties.filter(key => this.annotation.item[key]); - - if (!changes.length && !this.annotation.item.engines?.includes(LogEntryEngines.MANUAL)) { + if (!changes.length && !annotation.engines?.includes(LogEntryEngines.MANUAL)) { return; } const details = []; - if (this.annotation.item.engines?.includes(LogEntryEngines.MANUAL)) { + if (annotation.engines?.includes(LogEntryEngines.MANUAL)) { details.push(this._translateService.instant(_('annotation-changes.added-locally'))); } @@ -66,13 +63,9 @@ export class AnnotationDetailsComponent implements OnChanges { const header = this._translateService.instant(_('annotation-changes.header')); return [header, ...details.map(change => `• ${change}`)].join('\n'); - } - - ngOnChanges() { - this.engines = this.#extractEngines(this.annotation.item).filter(engine => engine.show); - this.changesTooltip = this.getChangesTooltip(); - this.noSelection = !this.annotation.isSelected || this._multiSelectService.inactive(); - } + }); + private readonly _multiSelectService = inject(MultiSelectService); + protected readonly _noSelection = computed(() => !this.annotation().isSelected || this._multiSelectService.inactive()); #extractEngines(annotation: AnnotationWrapper): Engine[] { return [ diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotation-wrapper/annotation-wrapper.component.html b/apps/red-ui/src/app/modules/file-preview/components/annotation-wrapper/annotation-wrapper.component.html index e3eeb5b22..8c22e3273 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/annotation-wrapper/annotation-wrapper.component.html +++ b/apps/red-ui/src/app/modules/file-preview/components/annotation-wrapper/annotation-wrapper.component.html @@ -1,6 +1,6 @@
-
+
- -
+ @defer (on hover(annotationDiv)) { +
+ +
+ } }
} diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts b/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts index c30366d23..a6364564f 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts @@ -11,7 +11,7 @@ import { AnnotationReferencesService } from '../../services/annotation-reference import { AnnotationsListingService } from '../../services/annotations-listing.service'; import { MultiSelectService } from '../../services/multi-select.service'; import { ViewModeService } from '../../services/view-mode.service'; -import { NgForOf, NgIf } from '@angular/common'; +import { JsonPipe, NgForOf, NgIf } from '@angular/common'; import { HighlightsSeparatorComponent } from '../highlights-separator/highlights-separator.component'; import { AnnotationWrapperComponent } from '../annotation-wrapper/annotation-wrapper.component'; import { AnnotationReferencesListComponent } from '../annotation-references-list/annotation-references-list.component'; @@ -21,7 +21,7 @@ import { AnnotationReferencesListComponent } from '../annotation-references-list templateUrl: './annotations-list.component.html', styleUrls: ['./annotations-list.component.scss'], standalone: true, - imports: [NgForOf, NgIf, HighlightsSeparatorComponent, AnnotationWrapperComponent, AnnotationReferencesListComponent], + imports: [NgForOf, NgIf, HighlightsSeparatorComponent, AnnotationWrapperComponent, AnnotationReferencesListComponent, JsonPipe], }) export class AnnotationsListComponent extends HasScrollbarDirective { readonly annotations = input.required[]>(); From 76d329b888eae6ab831618ced28c80f18cfe2172 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Tue, 8 Oct 2024 00:51:21 +0300 Subject: [PATCH 065/125] RED-7340 - Rectangle redactions: Use bulk-local redactions + New dialog design --- .../edit-redaction-dialog.component.html | 1 + .../edit-redaction-dialog.component.ts | 34 ++- .../rectangle-annotation-dialog.component.ts | 59 +++-- .../remove-redaction-dialog.component.html | 7 +- .../remove-redaction-dialog.component.ts | 39 ++- .../services/annotation-actions.service.ts | 28 +- .../file-preview/utils/dialog-options.ts | 24 +- .../file-preview/utils/dialog-types.ts | 19 +- .../enhance-manual-redaction-request.utils.ts | 38 ++- .../rectangle-redact-translations.ts | 28 ++ apps/red-ui/src/assets/i18n/redact/de.json | 250 +++++++++++------- apps/red-ui/src/assets/i18n/redact/en.json | 48 +++- apps/red-ui/src/assets/i18n/scm/de.json | 246 ++++++++++------- apps/red-ui/src/assets/i18n/scm/en.json | 48 +++- .../redaction-log/recategorization.request.ts | 7 +- 15 files changed, 598 insertions(+), 278 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html index a1f9c2ce9..55bfda05b 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html @@ -18,6 +18,7 @@ diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts index 8f3a13cb2..1a4e8384e 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts @@ -25,10 +25,19 @@ import { SelectedAnnotationsTableComponent, ValueColumn, } from '../../components/selected-annotations-table/selected-annotations-table.component'; -import { getEditRedactionOptions } from '../../utils/dialog-options'; -import { EditRedactionData, EditRedactionOption, EditRedactResult, LegalBasisOption } from '../../utils/dialog-types'; +import { getEditRedactionOptions, getRectangleRedactOptions } from '../../utils/dialog-options'; +import { + EditRedactionData, + EditRedactionOption, + EditRedactResult, + LegalBasisOption, + RectangleRedactOption, + RectangleRedactOptions, +} from '../../utils/dialog-types'; import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component'; import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option'; +import { validatePageRange } from '../../utils/form-validators'; +import { parseRectanglePosition, parseSelectedPageNumbers } from '../../utils/enhance-manual-redaction-request.utils'; interface TypeSelectOptions { type: string; @@ -79,7 +88,7 @@ export class EditRedactionDialogComponent { label: redaction.value, bold: true }, { label: redaction.typeLabel }, ]); - options = getEditRedactionOptions(); + options = this.allRectangles ? getRectangleRedactOptions('edit') : getEditRedactionOptions(); legalOptions: LegalBasisOption[] = []; dictionaries: Dictionary[] = []; typeSelectOptions: TypeSelectOptions[] = []; @@ -96,6 +105,14 @@ export class EditRedactionDialogComponent super(); } + extraOptionChanged(option: DetailsRadioOption): void { + if (option.value === RectangleRedactOptions.MULTIPLE_PAGES) { + setTimeout(() => { + this.form.get('option')?.updateValueAndValidity(); + }, 0); + } + } + get displayedDictionaryLabel() { const selectedDictionaryType = this.form.controls.type.value; if (selectedDictionaryType) { @@ -188,6 +205,13 @@ export class EditRedactionDialogComponent const value = this.form.value; const initialReason: LegalBasisOption = this.initialFormValue.reason; const initialLegalBasis = initialReason?.legalBasis ?? ''; + const pageNumbers = parseSelectedPageNumbers( + this.form.get('option').value.additionalInput?.value, + this.data.file, + this.data.annotations[0], + ); + const position = parseRectanglePosition(this.annotations[0]); + this.close({ legalBasis: value.reason?.legalBasis ?? (this.isImage ? initialLegalBasis : ''), section: value.section, @@ -195,6 +219,8 @@ export class EditRedactionDialogComponent type: value.type, value: this.allRectangles ? value.value : null, option: value.option.value, + position, + pageNumbers, }); } @@ -229,7 +255,7 @@ export class EditRedactionDialogComponent disabled: this.isImported, }), section: new FormControl({ value: sameSection ? this.annotations[0].section : null, disabled: this.isImported }), - option: new FormControl>(this.options[0]), + option: new FormControl>(this.options[0], validatePageRange()), value: new FormControl(this.allRectangles ? this.annotations[0].value : null), }); } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts index 4e565ff06..7bbe89cdb 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts @@ -9,8 +9,7 @@ import { IqserDialogComponent, Toaster, } from '@iqser/common-ui'; -import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper'; -import { Dossier, File, IAddRedactionRequest, IManualRedactionEntry, SuperTypes } from '@red/domain'; +import { Dossier, IAddRedactionRequest, SuperTypes } from '@red/domain'; import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service'; import { JustificationsService } from '@services/entity-services/justifications.service'; import { Roles } from '@users/roles'; @@ -23,21 +22,17 @@ import { MatOption, MatSelect, MatSelectTrigger } from '@angular/material/select import { MatTooltip } from '@angular/material/tooltip'; import { MatCheckbox } from '@angular/material/checkbox'; import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option'; -import { LegalBasisOption, RectangleRedactOption, RectangleRedactOptions } from '../../utils/dialog-types'; +import { + LegalBasisOption, + RectangleDialogData, + RectangleDialogResult, + RectangleRedactOption, + RectangleRedactOptions, +} from '../../utils/dialog-types'; import { getRectangleRedactOptions } from '../../utils/dialog-options'; import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component'; import { SystemDefaults } from '../../../account/utils/dialog-defaults'; import { validatePageRange } from '../../utils/form-validators'; -import { getMultiplePagesRectangle } from '../../utils/enhance-manual-redaction-request.utils'; - -interface RectangleDialogData { - dossierId: string; - manualRedactionEntryWrapper: ManualRedactionEntryWrapper; - file: File; -} -export interface RectangleDialogResult { - annotation: IManualRedactionEntry; -} export const NON_READABLE_CONTENT = 'non-readable content'; @@ -116,7 +111,7 @@ export class RectangleAnnotationDialog try { const annotation = ( this.form.get('option').value.value === RectangleRedactOptions.MULTIPLE_PAGES - ? getMultiplePagesRectangle(this.#multiplePagesRectangleData) + ? this.#multiplePagesRectangle : this.data.manualRedactionEntryWrapper ).manualRedactionEntry; super.close({ @@ -127,14 +122,6 @@ export class RectangleAnnotationDialog } } - get #multiplePagesRectangleData() { - return { - manualRedactionEntryWrapper: this.data.manualRedactionEntryWrapper, - pages: this.form.get('option').value.additionalInput.value, - file: this.data.file, - }; - } - #getForm() { return this._formBuilder.group({ selectedText: this.data?.manualRedactionEntryWrapper?.manualRedactionEntry?.value, @@ -165,6 +152,34 @@ export class RectangleAnnotationDialog return this.options.find(o => o.value === option); } + get #multiplePagesRectangle() { + const value: string = this.form.get('option').value.additionalInput.value.replace(/[^0-9-,]/g, ''); + const entry = { ...this.data.manualRedactionEntryWrapper.manualRedactionEntry, pageNumbers: [] }; + const wrapper = { + ...this.data.manualRedactionEntryWrapper, + manualRedactionEntry: entry, + }; + + value.split(',').forEach(range => { + const splitted = range.split('-'); + const startPage = parseInt(splitted[0], 10); + const endPage = splitted.length > 1 ? parseInt(splitted[1], 10) : startPage; + if (!startPage || !endPage || startPage > this.data.file.numberOfPages || endPage > this.data.file.numberOfPages) { + throw new Error(); + } + + for (let page = startPage; page <= endPage; page++) { + if (page === wrapper.manualRedactionEntry.positions[0].page) { + continue; + } + + wrapper.manualRedactionEntry.pageNumbers.push(page); + } + }); + + return wrapper; + } + #selectReason() { if (this.legalOptions.length === 1) { this.form.get('reason').setValue(this.legalOptions[0]); diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.html index 67b718ed6..af6631396 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.html +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.html @@ -14,7 +14,11 @@ >
- +
@@ -31,6 +35,7 @@
acc && a.AREA, true); readonly #applyToAllDossiers = this.systemDefaultByType[this.annotationsType].extra; readonly isSystemDefault = this.optionByType[this.annotationsType].main === SystemDefaultOption.SYSTEM_DEFAULT; readonly isExtraOptionSystemDefault = this.optionByType[this.annotationsType].extra === 'undefined'; @@ -96,15 +102,17 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< ? this.systemDefaultByType[this.annotationsType].main : this.optionByType[this.annotationsType].main; readonly extraOptionPreference = stringToBoolean(this.optionByType[this.annotationsType].extra); - readonly options: DetailsRadioOption[] = getRemoveRedactionOptions( - this.data, - this.isSystemDefault || this.isExtraOptionSystemDefault ? this.#applyToAllDossiers : this.extraOptionPreference, - ); + readonly options: DetailsRadioOption[] = this.#allRectangles + ? getRectangleRedactOptions('remove') + : getRemoveRedactionOptions( + this.data, + this.isSystemDefault || this.isExtraOptionSystemDefault ? this.#applyToAllDossiers : this.extraOptionPreference, + ); readonly skipped = this.data.redactions.some(annotation => annotation.isSkipped); readonly redactedTexts = this.data.redactions.map(annotation => annotation.value); form: UntypedFormGroup = this._formBuilder.group({ comment: [null], - option: [this.defaultOption], + option: [this.defaultOption, validatePageRange()], }); readonly selectedOption = toSignal(this.form.get('option').valueChanges.pipe(map(value => value.value))); @@ -160,14 +168,31 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< return this.options.length * 75 + 230; } + extraOptionChanged(option: DetailsRadioOption): void { + if (option.value === RectangleRedactOptions.MULTIPLE_PAGES) { + setTimeout(() => { + this.form.get('option')?.updateValueAndValidity(); + }, 0); + } + } + save(): void { + const pageNumbers = parseSelectedPageNumbers( + this.form.get('option').value.additionalInput?.value, + this.data.file, + this.data.redactions[0], + ); + const position = parseRectanglePosition(this.data.redactions[0]); + this.close({ ...this.form.getRawValue(), bulkLocal: this.form.controls.option.value.value === ResizeOptions.IN_DOCUMENT, + pageNumbers, + position, }); } - #getOption(option: RemoveRedactionOption): DetailsRadioOption { + #getOption(option: RemoveRedactionOption): DetailsRadioOption { return this.options.find(o => o.value === option); } } diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts index 598fcf674..ecf5b5300 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts @@ -35,7 +35,9 @@ import { EditRedactionData, EditRedactResult, ForceAnnotationOptions, + RectangleRedactOptions, RedactOrHintOptions, + RedactRecommendationData, RemoveRedactionData, RemoveRedactionOptions, RemoveRedactionPermissions, @@ -49,6 +51,7 @@ import { FilePreviewStateService } from './file-preview-state.service'; import { ManualRedactionService } from './manual-redaction.service'; import { SkippedService } from './skipped.service'; import { NON_READABLE_CONTENT } from '../dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component'; +import { result } from 'lodash-es'; @Injectable() export class AnnotationActionsService { @@ -110,11 +113,12 @@ export class AnnotationActionsService { } async editRedaction(annotations: AnnotationWrapper[]) { - const { dossierId, fileId } = this._state; + const { dossierId, file } = this._state; const includeUnprocessed = annotations.every(annotation => this.#includeUnprocessed(annotation, true)); const data = { annotations, dossierId, + file: file(), }; const result = await this.#getEditRedactionDialog(data).result(); @@ -124,7 +128,7 @@ export class AnnotationActionsService { let recategorizeBody: List | IBulkRecategorizationRequest; - if (result.option === RedactOrHintOptions.ONLY_HERE) { + if (result.option === RedactOrHintOptions.ONLY_HERE || result.option === RectangleRedactOptions.ONLY_THIS_PAGE) { recategorizeBody = annotations.map(annotation => { const body: IRecategorizationRequest = { annotationId: annotation.id, @@ -151,7 +155,9 @@ export class AnnotationActionsService { section: result.section, originTypes, originLegalBases, - rectangle: false, + rectangle: annotations[0].AREA, + pageNumbers: result.pageNumbers, + position: result.position, }; } @@ -160,10 +166,10 @@ export class AnnotationActionsService { .recategorizeRedactions( recategorizeBody, dossierId, - fileId, + file().id, this.#getChangedFields(annotations, result), includeUnprocessed, - result.option === RedactOrHintOptions.IN_DOCUMENT, + result.option === RedactOrHintOptions.IN_DOCUMENT || !!result.pageNumbers.length, ) .pipe(log()), ); @@ -177,9 +183,11 @@ export class AnnotationActionsService { }; const dossierTemplate = this._dossierTemplatesService.find(this._state.dossierTemplateId); const isApprover = this._permissionsService.isApprover(this._state.dossier()); + const { file } = this._state; const data = { redactions, + file: file(), dossier: this._state.dossier(), falsePositiveContext: redactions.map(r => this.#getFalsePositiveText(r)), permissions: removePermissions, @@ -217,7 +225,7 @@ export class AnnotationActionsService { async convertRecommendationToAnnotation(recommendations: AnnotationWrapper[]) { const { dossierId, fileId } = this._state; - const data = this.#getRedactRecommendationDialogData(recommendations); + const data = this.#getRedactRecommendationDialogData(recommendations) as RedactRecommendationData; const dialog = this._iqserDialog.openDefault(RedactRecommendationDialogComponent, { data }); const result = await dialog.result(); if (!result) { @@ -508,7 +516,7 @@ export class AnnotationActionsService { removeFromDictionary, isHint, includeUnprocessed, - dialogResult.bulkLocal, + dialogResult.bulkLocal || !!dialogResult.pageNumbers.length, ), ).then(); } @@ -584,15 +592,15 @@ export class AnnotationActionsService { redactions: AnnotationWrapper[], dialogResult: RemoveRedactionResult, ): List | IBulkLocalRemoveRequest { - if (dialogResult.bulkLocal) { + if (dialogResult.bulkLocal || !!dialogResult.pageNumbers.length) { const redaction = redactions[0]; if (redaction.value === NON_READABLE_CONTENT) { return { value: redaction.value, rectangle: true, - position: redaction.entry.positions[0], originTypes: [redaction.entry.type], - pageNumbers: [redaction.pageNumber], + pageNumbers: dialogResult.pageNumbers, + position: dialogResult.position, }; } diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts index 19f6b7b79..5b4288ccd 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts @@ -19,7 +19,11 @@ import { ResizeOptions, ResizeRedactionOption, } from './dialog-types'; -import { rectangleRedactTranslations } from '@translations/rectangle-redact-translations'; +import { + editRectangleTranslations, + rectangleRedactTranslations, + removeRectangleTranslations, +} from '@translations/rectangle-redact-translations'; const PIN_ICON = 'red:push-pin'; const DOCUMENT_ICON = 'iqser:document'; @@ -94,23 +98,25 @@ export const getRedactOrHintOptions = ( return options; }; -export const getRectangleRedactOptions = (): DetailsRadioOption[] => { +export const getRectangleRedactOptions = (action: 'add' | 'edit' | 'remove' = 'add'): DetailsRadioOption[] => { + const translations = + action === 'add' ? rectangleRedactTranslations : action === 'edit' ? editRectangleTranslations : removeRectangleTranslations; return [ { - label: rectangleRedactTranslations.onlyThisPage.label, - description: rectangleRedactTranslations.onlyThisPage.description, + label: translations.onlyThisPage.label, + description: translations.onlyThisPage.description, icon: PIN_ICON, value: RectangleRedactOptions.ONLY_THIS_PAGE, }, { - label: rectangleRedactTranslations.multiplePages.label, - description: rectangleRedactTranslations.multiplePages.description, + label: translations.multiplePages.label, + description: translations.multiplePages.description, icon: DOCUMENT_ICON, value: RectangleRedactOptions.MULTIPLE_PAGES, additionalInput: { - label: rectangleRedactTranslations.multiplePages.extraOptionLabel, - description: rectangleRedactTranslations.multiplePages.extraOptionDescription, - placeholder: rectangleRedactTranslations.multiplePages.extraOptionPlaceholder, + label: translations.multiplePages.extraOptionLabel, + description: translations.multiplePages.extraOptionDescription, + placeholder: translations.multiplePages.extraOptionPlaceholder, value: '', }, }, diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts index 2b8a44dc4..00131bcda 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts @@ -1,7 +1,7 @@ import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper'; -import { Dictionary, Dossier, File, IAddRedactionRequest, IManualRedactionEntry } from '@red/domain'; +import { Dictionary, Dossier, File, IAddRedactionRequest, IEntityLogEntryPosition, IManualRedactionEntry } from '@red/domain'; export const EditRedactionOptions = { ONLY_HERE: 'ONLY_HERE', @@ -65,6 +65,7 @@ export interface RedactTextData { export interface EditRedactionData { annotations: AnnotationWrapper[]; dossierId: string; + file: File; isApprover?: boolean; } @@ -93,7 +94,9 @@ export interface EditRedactResult { comment: string; type: string; value: string; - option: EditRedactionOption; + option: EditRedactionOption | RectangleRedactOption; + position: IEntityLogEntryPosition; + pageNumbers?: number[]; } export type AddHintResult = RedactTextResult; @@ -133,6 +136,7 @@ export interface RemoveRedactionPermissions { export interface RemoveRedactionData { redactions: AnnotationWrapper[]; dossier: Dossier; + file?: File; falsePositiveContext: string[]; permissions: RemoveRedactionPermissions; applyToAllDossiers: boolean; @@ -146,6 +150,17 @@ export interface RemoveRedactionResult { option: DetailsRadioOption; applyToAllDossiers?: boolean; bulkLocal?: boolean; + pageNumbers?: number[]; + position: IEntityLogEntryPosition; } export type RemoveAnnotationResult = RemoveRedactionResult; + +export interface RectangleDialogData { + dossierId: string; + manualRedactionEntryWrapper: ManualRedactionEntryWrapper; + file: File; +} +export interface RectangleDialogResult { + annotation: IManualRedactionEntry; +} diff --git a/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts b/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts index 701028276..635549d37 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts @@ -1,6 +1,7 @@ -import { Dictionary, File, IAddRedactionRequest, SuperType } from '@red/domain'; +import { Dictionary, File, IAddRedactionRequest, IEntityLogEntryPosition, SuperType } from '@red/domain'; import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper'; import { LegalBasisOption } from './dialog-types'; +import { AnnotationWrapper } from '@models/file/annotation.wrapper'; export interface EnhanceRequestData { readonly type: SuperType | null; @@ -46,30 +47,41 @@ export const enhanceManualRedactionRequest = (addRedactionRequest: IAddRedaction addRedactionRequest.addToAllDossiers = data.isApprover && data.dictionaryRequest && data.applyToAllDossiers; }; -export const getMultiplePagesRectangle = (data: MultiplePagesRectangleData) => { - const value: string = data.pages.replace(/[^0-9-,]/g, ''); - const entry = { ...data.manualRedactionEntryWrapper.manualRedactionEntry, pageNumbers: [] }; - const wrapper = { - ...data.manualRedactionEntryWrapper, - manualRedactionEntry: entry, - }; +export const parseSelectedPageNumbers = (inputValue: string, file: File, annotation: AnnotationWrapper) => { + if (!inputValue) { + return []; + } - value.split(',').forEach(range => { + inputValue = inputValue.replace(/[^0-9-,]/g, ''); + const pageNumbers = []; + + inputValue.split(',').forEach(range => { const splitted = range.split('-'); const startPage = parseInt(splitted[0], 10); const endPage = splitted.length > 1 ? parseInt(splitted[1], 10) : startPage; - if (!startPage || !endPage || startPage > data.file.numberOfPages || endPage > data.file.numberOfPages) { + if (!startPage || !endPage || startPage > file.numberOfPages || endPage > file.numberOfPages) { throw new Error(); } for (let page = startPage; page <= endPage; page++) { - if (page === wrapper.manualRedactionEntry.positions[0].page) { + if (page === annotation.positions[0].page) { continue; } - wrapper.manualRedactionEntry.pageNumbers.push(page); + pageNumbers.push(page); } }); - return wrapper; + return pageNumbers; +}; + +export const parseRectanglePosition = (annotation: AnnotationWrapper) => { + if (annotation.AREA) { + const position = annotation.positions[0]; + return { + rectangle: [position.topLeft.x, position.topLeft.y, position.width, position.height], + pageNumber: position.page, + } as IEntityLogEntryPosition; + } + return null; }; diff --git a/apps/red-ui/src/app/translations/rectangle-redact-translations.ts b/apps/red-ui/src/app/translations/rectangle-redact-translations.ts index 2feb6c67b..65359c754 100644 --- a/apps/red-ui/src/app/translations/rectangle-redact-translations.ts +++ b/apps/red-ui/src/app/translations/rectangle-redact-translations.ts @@ -14,3 +14,31 @@ export const rectangleRedactTranslations: Record<'onlyThisPage' | 'multiplePages extraOptionPlaceholder: _('manual-annotation.dialog.content.options.multiple-pages.extraOptionPlaceholder'), }, } as const; + +export const editRectangleTranslations: Record<'onlyThisPage' | 'multiplePages', DialogOption> = { + onlyThisPage: { + label: _('edit-rectangle.dialog.content.options.only-this-page.label'), + description: _('edit-rectangle.dialog.content.options.only-this-page.description'), + }, + multiplePages: { + label: _('edit-rectangle.dialog.content.options.multiple-pages.label'), + description: _('edit-rectangle.dialog.content.options.multiple-pages.description'), + extraOptionLabel: _('edit-rectangle.dialog.content.options.multiple-pages.extraOptionLabel'), + extraOptionDescription: _('edit-rectangle.dialog.content.options.multiple-pages.extraOptionDescription'), + extraOptionPlaceholder: _('edit-rectangle.dialog.content.options.multiple-pages.extraOptionPlaceholder'), + }, +} as const; + +export const removeRectangleTranslations: Record<'onlyThisPage' | 'multiplePages', DialogOption> = { + onlyThisPage: { + label: _('remove-rectangle.dialog.content.options.only-this-page.label'), + description: _('remove-rectangle.dialog.content.options.only-this-page.description'), + }, + multiplePages: { + label: _('remove-rectangle.dialog.content.options.multiple-pages.label'), + description: _('remove-rectangle.dialog.content.options.multiple-pages.description'), + extraOptionLabel: _('remove-rectangle.dialog.content.options.multiple-pages.extraOptionLabel'), + extraOptionDescription: _('remove-rectangle.dialog.content.options.multiple-pages.extraOptionDescription'), + extraOptionPlaceholder: _('remove-rectangle.dialog.content.options.multiple-pages.extraOptionPlaceholder'), + }, +} as const; diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index 3e729eb92..430e48213 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -243,7 +243,8 @@ } }, "type": "Typ", - "type-placeholder": "Typ auswählen..." + "type-placeholder": "Typ auswählen...", + "value": "" }, "title": "Hinweis hinzufügen" } @@ -275,9 +276,6 @@ "watermarks": "Wasserzeichen" }, "analysis-disabled": "", - "annotation": { - "pending": "(Analyse steht aus)" - }, "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" @@ -333,14 +331,14 @@ "error": "Rekategorisierung des Bilds fehlgeschlagen: {error}", "success": "Bild wurde einer neuen Kategorie zugeordnet." }, - "remove": { - "error": "Entfernen der Schwärzung fehlgeschlagen: {error}", - "success": "Schwärzung wurde entfernt" - }, "remove-hint": { "error": "Entfernen des Hinweises fehlgeschlagen: {error}", "success": "Hinweis wurde entfernt" }, + "remove": { + "error": "Entfernen der Schwärzung fehlgeschlagen: {error}", + "success": "Schwärzung wurde entfernt" + }, "undo": { "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", "success": "Rücksetzung erfolgreich" @@ -353,15 +351,15 @@ "remove-highlights": { "label": "Ausgewählte Markierungen entfernen" }, - "resize": { - "label": "Größe ändern" - }, "resize-accept": { "label": "Neue Größe speichern" }, "resize-cancel": { "label": "Größenänderung abbrechen" }, + "resize": { + "label": "Größe ändern" + }, "see-references": { "label": "Referenzen anzeigen" }, @@ -378,6 +376,7 @@ "removed-manual": "Schwärzung/Hinweis wurde entfernt", "resized": "Schwärzungsbereich wurde geändert" }, + "annotation-content": "", "annotation-engines": { "dictionary": "Basiert auf Wörterbuch", "dossier-dictionary": "Basiert auf Dossier-Wörterbuch", @@ -395,6 +394,9 @@ "skipped": "Ignorierte Schwärzung", "text-highlight": "Markierung" }, + "annotation": { + "pending": "(Analyse steht aus)" + }, "annotations": "Annotationen", "archived-dossiers-listing": { "no-data": { @@ -1018,13 +1020,13 @@ "recent": "Neu ({hours} h)", "unassigned": "Keinem Bearbeiter zugewiesen" }, - "reanalyse": { - "action": "Datei analysieren" - }, "reanalyse-dossier": { "error": "Einplanung der Dateien für die Reanalyse fehlgeschlagen. Bitte versuchen Sie es noch einmal.", "success": "Dateien für Reanalyse vorgesehen." }, + "reanalyse": { + "action": "Datei analysieren" + }, "report-download": "", "start-auto-analysis": "Auto-Analyse aktivieren", "stop-auto-analysis": "Auto-Analyse anhalten", @@ -1094,14 +1096,6 @@ "total-documents": "Dokumente", "total-people": "{count} {count, plural, one{Benutzer} other {Benutzer}}" }, - "dossier-templates": { - "label": "Dossier-Vorlagen", - "status": { - "active": "Aktiv", - "inactive": "Inaktiv", - "incomplete": "Unvollständig" - } - }, "dossier-templates-listing": { "action": { "clone": "Vorlage klonen", @@ -1136,6 +1130,14 @@ "title": "{length} {length, plural, one{Dossier-Vorlage} other{Dossier-Vorlagen}}" } }, + "dossier-templates": { + "label": "Dossier-Vorlagen", + "status": { + "active": "Aktiv", + "inactive": "Inaktiv", + "incomplete": "Unvollständig" + } + }, "dossier-watermark-selector": { "heading": "Wasserzeichen auf Dokumenten", "no-watermark": "Kein Wasserzeichen in der Dossier-Vorlage verfügbar:
Bitten Sie Ihren Admin, eines zu konfigurieren.", @@ -1233,10 +1235,8 @@ "save": "Speichern", "title": "{label} bearbeiten" }, - "entries": "{length} {length, plural, one{Eintrag} other{Einträge}}", - "false-positive-entries": "{length} {length, plural, one{Falsch-Positiver} other{Falsch-Positive}}", + "entries-count": "", "false-positives": "Falsch-Positive", - "false-recommendation-entries": "{length} {length, plural, one{falsche Empfehlung} other{falsche Empfehlungen}}", "false-recommendations": "Falsche Empfehlungen", "to-redact": "Schwärzungen" }, @@ -1273,6 +1273,25 @@ }, "side-nav-title": "Konfiguration" }, + "edit-rectangle": { + "dialog": { + "content": { + "options": { + "multiple-pages": { + "description": "", + "extraOptionDescription": "", + "extraOptionLabel": "", + "extraOptionPlaceholder": "", + "label": "" + }, + "only-this-page": { + "description": "", + "label": "" + } + } + } + } + }, "edit-redaction": { "dialog": { "actions": { @@ -1282,14 +1301,11 @@ "content": { "comment": "Kommentar", "comment-placeholder": "Bemerkungen oder Notizen hinzufügen...", - "custom-rectangle": "Bereichsschwärzung", - "imported": "Importierte Schwärzung", "legal-basis": "Rechtsgrundlage", "options": { - "in-dossier": { - "description": "Schwärzung in jedem Dokument in {dossierName} bearbeiten.", - "extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen", - "label": "Typ in Dossier ändern" + "in-document": { + "description": "", + "label": "" }, "only-here": { "description": "Bearbeiten Sie die Schwärzung nur an dieser Stelle im Dokument.", @@ -1332,15 +1348,6 @@ "title": "{length} {length, plural, one{Wörterbuch} other{Wörterbücher}}" } }, - "entity": { - "info": { - "actions": { - "revert": "Zurücksetzen", - "save": "Änderungen speichern" - }, - "heading": "Entität bearbeiten" - } - }, "entity-rules-screen": { "error": { "generic": "Fehler: Aktualisierung der Entitätsregeln fehlgeschlagen." @@ -1354,19 +1361,28 @@ "title": "Entitätsregeln-Editor", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} in Regeln gefunden" }, + "entity": { + "info": { + "actions": { + "revert": "Zurücksetzen", + "save": "Änderungen speichern" + }, + "heading": "Entität bearbeiten" + } + }, "error": { "deleted-entity": { "dossier": { "action": "Zurück zur Übersicht", "label": "Dieses Dossier wurde gelöscht!" }, - "file": { - "action": "Zurück zum Dossier", - "label": "Diese Datei wurde gelöscht!" - }, "file-dossier": { "action": "Zurück zur Übersicht", "label": "Das Dossier dieser Datei wurde gelöscht!" + }, + "file": { + "action": "Zurück zum Dossier", + "label": "Diese Datei wurde gelöscht!" } }, "file-preview": { @@ -1384,12 +1400,6 @@ }, "exact-date": "{day}. {month} {year} um {hour}:{minute} Uhr", "file": "Datei", - "file-attribute": { - "update": { - "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", - "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." - } - }, "file-attribute-encoding-types": { "ascii": "ASCII", "iso": "ISO-8859-1", @@ -1400,6 +1410,12 @@ "number": "Nummer", "text": "Freier Text" }, + "file-attribute": { + "update": { + "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", + "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." + } + }, "file-attributes-configurations": { "cancel": "Abbrechen", "form": { @@ -1617,15 +1633,6 @@ "csv": "Die Datei-Attribute wurden erfolgreich aus der hochgeladenen CSV-Datei importiert." } }, - "filter": { - "analysis": "Analyse erforderlich", - "comment": "Kommentare", - "hint": "Nur Hinweise", - "image": "Bilder", - "none": "Keine Annotationen", - "redaction": "Schwärzung", - "updated": "Aktualisiert" - }, "filter-menu": { "filter-options": "Filteroptionen", "filter-types": "Filter", @@ -1635,6 +1642,15 @@ "unseen-pages": "Nur Annotationen auf ungesehenen Seiten", "with-comments": "Nur Annotationen mit Kommentaren" }, + "filter": { + "analysis": "Analyse erforderlich", + "comment": "Kommentare", + "hint": "Nur Hinweise", + "image": "Bilder", + "none": "Keine Annotationen", + "redaction": "Schwärzung", + "updated": "Aktualisiert" + }, "filters": { "assigned-people": "Bearbeiter", "documents-status": "Dokumentenstatus", @@ -1868,13 +1884,8 @@ "save": "Speichern" }, "content": { - "apply-on-multiple-pages": "Auf mehreren Seiten anwenden", - "apply-on-multiple-pages-hint": "Minus (-) für Bereich und Komma (,) für Aufzählung.", - "apply-on-multiple-pages-placeholder": "z. B. 1-20,22,32", "classification": "Wert / Klassifizierung", "comment": "Kommentar", - "dictionary": "Wörterbuch", - "edit-selected-text": "Ausgewählten Text bearbeiten", "legalBasis": "Rechtsgrundlage", "options": { "multiple-pages": { @@ -1891,10 +1902,7 @@ }, "reason": "Grund", "reason-placeholder": "Grund auswählen...", - "rectangle": "Bereichsschwärzung", - "section": "Absatz / Textstelle", - "text": "Ausgewählter Text:", - "type": "Entität" + "section": "Absatz / Textstelle" }, "error": "Fehler: Ungültige Seitenauswahl", "header": { @@ -1926,13 +1934,6 @@ "user-promoted-to-approver": "{user} wurde im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} zum Genehmiger ernannt!", "user-removed-as-dossier-member": "{user} wurde als Mitglied von: {dossierHref, select, null{{dossierName}} other{{dossierName}}} entfernt!" }, - "notifications": { - "button-text": "Benachrichtigungen", - "deleted-dossier": "Gelöschtes Dossier", - "label": "Benachrichtigungen", - "mark-all-as-read": "Alle als gelesen markieren", - "mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren" - }, "notifications-screen": { "category": { "email-notifications": "E-Mail-Benachrichtigungen", @@ -1946,6 +1947,7 @@ "dossier": "Benachrichtigungen zu Dossiers", "other": "Andere Benachrichtigungen" }, + "options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten", "options": { "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen werde", "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Prüfer zugewiesen werde", @@ -1963,7 +1965,6 @@ "USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde", "USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere" }, - "options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten", "schedule": { "daily": "Tägliche Zusammenfassung", "instant": "Sofort", @@ -1971,6 +1972,13 @@ }, "title": "Benachrichtigungseinstellungen" }, + "notifications": { + "button-text": "Benachrichtigungen", + "deleted-dossier": "Gelöschtes Dossier", + "label": "Benachrichtigungen", + "mark-all-as-read": "Alle als gelesen markieren", + "mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren" + }, "ocr": { "confirmation-dialog": { "cancel": "Abbrechen", @@ -2017,14 +2025,34 @@ "previous": "Vorherige" }, "pdf-viewer": { + "header": { + "all-annotations-loaded": "", + "compare-button": "", + "layers-panel-button": "", + "left-panel-button": "", + "load-all-annotations": "", + "no-outlines-text": "", + "no-signatures-text": "", + "outline-multi-select": "", + "outlines-panel-button": "", + "pan-tool-button": "", + "rectangle-tool-button": "", + "rotate-left-button": "", + "rotate-right-button": "", + "select-tool-button": "", + "signature-panel-button": "", + "thumbnails-panel-button": "", + "toggle-layers": "", + "toggle-readable-redactions": "", + "toggle-tooltips": "", + "zoom-in-button": "", + "zoom-out-button": "" + }, "text-popup": { "actions": { "search": "Ausgewählten Text suchen" } - }, - "toggle-layers": "Layout-Raster {active, select, true{deaktivieren} false{aktivieren} other{}}", - "toggle-readable-redactions": "Schwärzungen {active, select, true{wie im finalen Dokument} false{in Vorschau-Farbe} other{}} anzeigen", - "toggle-tooltips": "Tooltips zu Annotationen {active, select, true{deaktivieren} false{aktivieren} other{}}" + } }, "permissions-screen": { "dossier": { @@ -2062,16 +2090,16 @@ "warnings-label": "Dialoge und Meldungen", "warnings-subtitle": "„Nicht mehr anzeigen“-Optionen" }, - "processing": { - "basic": "Verarbeitung läuft", - "ocr": "OCR" - }, "processing-status": { "ocr": "OCR", "pending": "Ausstehend", "processed": "Verarbeitet", "processing": "Verarbeitung läuft" }, + "processing": { + "basic": "Verarbeitung läuft", + "ocr": "OCR" + }, "readonly": "Lesemodus", "readonly-archived": "Lesemodus (archiviert)", "redact-text": { @@ -2086,6 +2114,10 @@ "edit-text": "Text bearbeiten", "legal-basis": "Rechtsgrundlage", "options": { + "in-document": { + "description": "", + "label": "" + }, "in-dossier": { "description": "Fügen Sie die Schwärzung zu jedem Dokument in {dossierName} hinzu.", "extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen", @@ -2101,7 +2133,8 @@ "revert-text": "Zurück zu ursprünglicher Auswahl", "type": "Typ", "type-placeholder": "Typ auswählen...", - "unchanged": "Ungeändert" + "unchanged": "Ungeändert", + "value": "" }, "title": "Text schwärzen" } @@ -2125,6 +2158,10 @@ "description-bulk": "", "label": "In diesem Kontext aus dem Dossier entfernen" }, + "in-document": { + "description": "", + "label": "" + }, "in-dossier": { "description": "Annotieren Sie den Begriff in diesem Dossier nicht.", "description-bulk": "", @@ -2142,6 +2179,25 @@ "title": "{count, plural, one{Annotation} other {Annotationen}} entfernen" } }, + "remove-rectangle": { + "dialog": { + "content": { + "options": { + "multiple-pages": { + "description": "", + "extraOptionDescription": "", + "extraOptionLabel": "", + "extraOptionPlaceholder": "", + "label": "" + }, + "only-this-page": { + "description": "", + "label": "" + } + } + } + } + }, "remove-redaction": { "dialog": { "actions": { @@ -2165,6 +2221,10 @@ "extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen", "label": "In diesem Kontext aus Dossier entfernen" }, + "in-document": { + "description": "", + "label": "" + }, "in-dossier": { "description": "Der Begriff wird in keinem Dokument dieses Dossiers {type, select, hint{annotiert} other{automatisch geschwärzt}}.", "description-bulk": "Die ausgewählten Begriffe werden in diesem Dossier nicht {type, select, hint{annotiert} other{automatisch geschwärzt}}.", @@ -2307,12 +2367,6 @@ "red-user-admin": "Benutzeradmin", "regular": "regulärer Benutzer" }, - "search": { - "active-dossiers": "Dokumente in aktiven Dossiers", - "all-dossiers": "Alle Dokumente", - "placeholder": "Dokumente durchsuchen...", - "this-dossier": "In diesem Dossier" - }, "search-screen": { "cols": { "assignee": "Bearbeiter", @@ -2336,6 +2390,12 @@ "no-match": "Der Suchbegriff wurde in keinem der Dokumente gefunden.", "table-header": "{length} {length, plural, one{Suchergebnis} other{Suchergebnisse}}" }, + "search": { + "active-dossiers": "Dokumente in aktiven Dossiers", + "all-dossiers": "Alle Dokumente", + "placeholder": "Dokumente durchsuchen...", + "this-dossier": "In diesem Dossier" + }, "seconds": "Sekunden", "size": "Größe", "smtp-auth-config": { @@ -2526,10 +2586,6 @@ "view-as": "Ansicht:", "workflow": "Workflow-Spalten" }, - "viewer-header": { - "all-annotations-loaded": "Alle Annotationen geladen", - "load-all-annotations": "Alle Annotationen laden" - }, "watermark-screen": { "action": { "change-success": "Wasserzeichen wurde aktualisiert.", @@ -2558,6 +2614,10 @@ "orientation": "Textrichtung", "text-label": "Text für Wasserzeichen", "text-placeholder": "Text eingeben" + }, + "pagination": { + "landscape": "", + "portrait": "" } }, "watermarks-listing": { diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index e8db36f2d..b4b07efe4 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -1273,6 +1273,25 @@ }, "side-nav-title": "Configurations" }, + "edit-rectangle": { + "dialog": { + "content": { + "options": { + "multiple-pages": { + "description": "Edit redaction the range of pages", + "extraOptionDescription": "Minus(-) for range and comma(,) for enumeration", + "extraOptionLabel": "Range", + "extraOptionPlaceholder": "e.g. 1-20,22,32", + "label": "Change on all pages" + }, + "only-this-page": { + "description": "Edit redaction only at this position in this document", + "label": "Change only on this page" + } + } + } + } + }, "edit-redaction": { "dialog": { "actions": { @@ -1865,13 +1884,8 @@ "save": "Save" }, "content": { - "apply-on-multiple-pages": "Apply on multiple pages", - "apply-on-multiple-pages-hint": "Minus(-) for range and comma(,) for enumeration.", - "apply-on-multiple-pages-placeholder": "e.g. 1-20,22,32", "classification": "Value / classification", "comment": "Comment", - "dictionary": "Dictionary", - "edit-selected-text": "Edit selected text", "legalBasis": "Legal basis", "options": { "multiple-pages": { @@ -1888,10 +1902,7 @@ }, "reason": "Reason", "reason-placeholder": "Select a reason...", - "rectangle": "Custom rectangle", - "section": "Paragraph / location", - "text": "Selected text:", - "type": "Entity" + "section": "Paragraph / location" }, "error": "Error! Invalid page selection", "header": { @@ -2168,6 +2179,25 @@ "title": "Remove {count, plural, one{annotation} other {annotations}}" } }, + "remove-rectangle": { + "dialog": { + "content": { + "options": { + "multiple-pages": { + "description": "Edit redaction the range of pages", + "extraOptionDescription": "Minus(-) for range and comma(,) for enumeration", + "extraOptionLabel": "Range", + "extraOptionPlaceholder": "e.g. 1-20,22,32", + "label": "Remove on all pages" + }, + "only-this-page": { + "description": "Edit redaction only at this position in this document", + "label": "Remove only on this page" + } + } + } + } + }, "remove-redaction": { "dialog": { "actions": { diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 7f79dfc40..d90f55996 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -243,7 +243,8 @@ } }, "type": "Typ", - "type-placeholder": "Typ auswählen..." + "type-placeholder": "Typ auswählen...", + "value": "" }, "title": "Hinweis hinzufügen" } @@ -275,9 +276,6 @@ "watermarks": "Wasserzeichen" }, "analysis-disabled": "Analyse deaktiviert", - "annotation": { - "pending": "(Analyse steht aus)" - }, "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" @@ -333,14 +331,14 @@ "error": "Rekategorisierung des Bilds fehlgeschlagen: {error}", "success": "Bild wurde einer neuen Kategorie zugeordnet." }, - "remove": { - "error": "Entfernen der Annotation fehlgeschlagen: {error}", - "success": "Annotation wurde entfernt" - }, "remove-hint": { "error": "Entfernen des Hinweises fehlgeschlagen: {error}", "success": "Hinweis wurde entfernt" }, + "remove": { + "error": "Entfernen der Annotation fehlgeschlagen: {error}", + "success": "Annotation wurde entfernt" + }, "undo": { "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", "success": "erfolgreich Rückgängig gemacht" @@ -353,15 +351,15 @@ "remove-highlights": { "label": "Ausgewählte Markierungen entfernen" }, - "resize": { - "label": "Größe ändern" - }, "resize-accept": { "label": "Neue Größe speichern" }, "resize-cancel": { "label": "Größenänderung abbrechen" }, + "resize": { + "label": "Größe ändern" + }, "see-references": { "label": "See references" }, @@ -378,6 +376,7 @@ "removed-manual": "Schwärzung/Hinweis entfernt", "resized": "Schwärzungsbereich wurde geändert" }, + "annotation-content": "", "annotation-engines": { "dictionary": "{isHint, select, true{Hinweis} other{Schwärzung}} basiert auf Wörterbuch", "dossier-dictionary": "Annotation basiert auf Dossier-Wörterbuch", @@ -395,6 +394,9 @@ "skipped": "Übersprungen", "text-highlight": "Markierung" }, + "annotation": { + "pending": "(Analyse steht aus)" + }, "annotations": "Annotationen", "archived-dossiers-listing": { "no-data": { @@ -1018,13 +1020,13 @@ "recent": "Neu ({hours} h)", "unassigned": "Niemandem zugewiesen" }, - "reanalyse": { - "action": "Datei analysieren" - }, "reanalyse-dossier": { "error": "Die Dateien konnten nicht für eine Reanalyse eingeplant werden. Bitte versuchen Sie es erneut.", "success": "Dateien für Reanalyse vorgesehen." }, + "reanalyse": { + "action": "Datei analysieren" + }, "report-download": "Report download", "start-auto-analysis": "Enable auto-analysis", "stop-auto-analysis": "Stop auto-analysis", @@ -1094,14 +1096,6 @@ "total-documents": "Anzahl der Dokumente", "total-people": "{count} {count, plural, one{user} other {users}}" }, - "dossier-templates": { - "label": "Dossier-Vorlagen", - "status": { - "active": "Active", - "inactive": "Inactive", - "incomplete": "Incomplete" - } - }, "dossier-templates-listing": { "action": { "clone": "Clone template", @@ -1136,6 +1130,14 @@ "title": "{length} dossier {length, plural, one{template} other{templates}}" } }, + "dossier-templates": { + "label": "Dossier-Vorlagen", + "status": { + "active": "Active", + "inactive": "Inactive", + "incomplete": "Incomplete" + } + }, "dossier-watermark-selector": { "heading": "Watermarks on documents", "no-watermark": "There is no watermark defined for the dossier template.
Contact your app admin to define one.", @@ -1233,10 +1235,8 @@ "save": "", "title": "" }, - "entries": "{length} {length, plural, one{entry} other{entries}} to {hint, select, true{annotate} other{redact}}", - "false-positive-entries": "{length} false positive {length, plural, one{entry} other{entries}}", + "entries-count": "", "false-positives": "False positives", - "false-recommendation-entries": "{length} false recommendation {length, plural, one{entry} other{entries}}", "false-recommendations": "False recommendations", "to-redact": "To redact" }, @@ -1273,6 +1273,25 @@ }, "side-nav-title": "Konfiguration" }, + "edit-rectangle": { + "dialog": { + "content": { + "options": { + "multiple-pages": { + "description": "", + "extraOptionDescription": "", + "extraOptionLabel": "", + "extraOptionPlaceholder": "", + "label": "" + }, + "only-this-page": { + "description": "", + "label": "" + } + } + } + } + }, "edit-redaction": { "dialog": { "actions": { @@ -1282,13 +1301,10 @@ "content": { "comment": "Comment", "comment-placeholder": "Add remarks or mentions...", - "custom-rectangle": "", - "imported": "", "legal-basis": "", "options": { - "in-dossier": { + "in-document": { "description": "", - "extraOptionLabel": "", "label": "" }, "only-here": { @@ -1332,15 +1348,6 @@ "title": "{length} {length, plural, one{entity} other{entities}}" } }, - "entity": { - "info": { - "actions": { - "revert": "Revert", - "save": "Save changes" - }, - "heading": "Edit entity" - } - }, "entity-rules-screen": { "error": { "generic": "Something went wrong... Entity rules update failed!" @@ -1354,19 +1361,28 @@ "title": "Entity rule editor", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} found in rules" }, + "entity": { + "info": { + "actions": { + "revert": "Revert", + "save": "Save changes" + }, + "heading": "Edit entity" + } + }, "error": { "deleted-entity": { "dossier": { "action": "Zurück zur Übersicht", "label": "Dieses Dossier wurde gelöscht!" }, - "file": { - "action": "Zurück zum Dossier", - "label": "Diese Datei wurde gelöscht!" - }, "file-dossier": { "action": "Zurück zur Übersicht", "label": "Das Dossier dieser Datei wurde gelöscht!" + }, + "file": { + "action": "Zurück zum Dossier", + "label": "Diese Datei wurde gelöscht!" } }, "file-preview": { @@ -1384,12 +1400,6 @@ }, "exact-date": "{day} {month} {year} um {hour}:{minute} Uhr", "file": "Datei", - "file-attribute": { - "update": { - "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", - "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." - } - }, "file-attribute-encoding-types": { "ascii": "ASCII", "iso": "ISO-8859-1", @@ -1400,6 +1410,12 @@ "number": "Nummer", "text": "Freier Text" }, + "file-attribute": { + "update": { + "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", + "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." + } + }, "file-attributes-configurations": { "cancel": "Abbrechen", "form": { @@ -1617,15 +1633,6 @@ "csv": "Die Datei-Attribute wurden erfolgreich aus der hochgeladenen CSV-Datei importiert." } }, - "filter": { - "analysis": "Analyse erforderlich", - "comment": "Kommentare", - "hint": "Nur Hinweise", - "image": "Bilder", - "none": "Keine Annotationen", - "redaction": "Annotationen", - "updated": "Aktualisiert" - }, "filter-menu": { "filter-options": "Filteroptionen", "filter-types": "Filter", @@ -1635,6 +1642,15 @@ "unseen-pages": "Nur Anmerkungen auf ungesehenen Seiten", "with-comments": "Nur Anmerkungen mit Kommentaren" }, + "filter": { + "analysis": "Analyse erforderlich", + "comment": "Kommentare", + "hint": "Nur Hinweise", + "image": "Bilder", + "none": "Keine Annotationen", + "redaction": "Annotationen", + "updated": "Aktualisiert" + }, "filters": { "assigned-people": "Bearbeiter", "documents-status": "Dokumentenstatus", @@ -1868,13 +1884,8 @@ "save": "Speichern" }, "content": { - "apply-on-multiple-pages": "Apply on multiple pages", - "apply-on-multiple-pages-hint": "Minus(-) for range and comma(,) for enumeration.", - "apply-on-multiple-pages-placeholder": "e.g. 1-20,22,32", "classification": "Wert / Klassifizierung", "comment": "Kommentar", - "dictionary": "Wörterbuch", - "edit-selected-text": "Edit selected text", "legalBasis": "Rechtsgrundlage", "options": { "multiple-pages": { @@ -1891,10 +1902,7 @@ }, "reason": "Begründung", "reason-placeholder": "Wählen Sie eine Begründung aus ...", - "rectangle": "Benutzerdefinierter Bereich", - "section": "Absatz / Ort", - "text": "Ausgewählter Text:", - "type": "Entity" + "section": "Absatz / Ort" }, "error": "Error! Invalid page selection", "header": { @@ -1926,13 +1934,6 @@ "user-promoted-to-approver": "{user} wurde im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} zum Genehmiger ernannt!", "user-removed-as-dossier-member": "{user} wurde als Mitglied von: {dossierHref, select, null{{dossierName}} other{{dossierName}}} entfernt!" }, - "notifications": { - "button-text": "Notifications", - "deleted-dossier": "Deleted dossier", - "label": "Benachrichtigungen", - "mark-all-as-read": "Alle als gelesen markieren", - "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}" - }, "notifications-screen": { "category": { "email-notifications": "E-Mail Benachrichtigungen", @@ -1946,6 +1947,7 @@ "dossier": "Dossierbezogene Benachrichtigungen", "other": "Andere Benachrichtigungen" }, + "options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten", "options": { "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen bin", "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Überprüfer zugewiesen bin", @@ -1963,7 +1965,6 @@ "USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde", "USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere" }, - "options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten", "schedule": { "daily": "Tägliche Zusammenfassung", "instant": "Sofortig", @@ -1971,6 +1972,13 @@ }, "title": "Benachrichtigungseinstellungen" }, + "notifications": { + "button-text": "Notifications", + "deleted-dossier": "Deleted dossier", + "label": "Benachrichtigungen", + "mark-all-as-read": "Alle als gelesen markieren", + "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}" + }, "ocr": { "confirmation-dialog": { "cancel": "Cancel", @@ -2017,14 +2025,34 @@ "previous": "Vorherige" }, "pdf-viewer": { + "header": { + "all-annotations-loaded": "", + "compare-button": "", + "layers-panel-button": "", + "left-panel-button": "", + "load-all-annotations": "", + "no-outlines-text": "", + "no-signatures-text": "", + "outline-multi-select": "", + "outlines-panel-button": "", + "pan-tool-button": "", + "rectangle-tool-button": "", + "rotate-left-button": "", + "rotate-right-button": "", + "select-tool-button": "", + "signature-panel-button": "", + "thumbnails-panel-button": "", + "toggle-layers": "", + "toggle-readable-redactions": "", + "toggle-tooltips": "", + "zoom-in-button": "", + "zoom-out-button": "" + }, "text-popup": { "actions": { "search": "Search for selected text" } - }, - "toggle-layers": "{active, select, true{Disable} false{Enable} other{}} layout grid", - "toggle-readable-redactions": "Show components {active, select, true{as in final document} false{in preview color} other{}}", - "toggle-tooltips": "{active, select, true{Disable} false{Enable} other{}} Kurzinfos für Anmerkungen" + } }, "permissions-screen": { "dossier": { @@ -2062,16 +2090,16 @@ "warnings-label": "Prompts and dialogs", "warnings-subtitle": "Do not show again options" }, - "processing": { - "basic": "Processing", - "ocr": "OCR" - }, "processing-status": { "ocr": "OCR", "pending": "Pending", "processed": "Processed", "processing": "Processing" }, + "processing": { + "basic": "Processing", + "ocr": "OCR" + }, "readonly": "Lesemodus", "readonly-archived": "Read only (archived)", "redact-text": { @@ -2086,6 +2114,10 @@ "edit-text": "", "legal-basis": "Legal basis", "options": { + "in-document": { + "description": "", + "label": "" + }, "in-dossier": { "description": "Add redaction in every document in {dossierName}.", "extraOptionLabel": "Apply to all dossiers", @@ -2101,7 +2133,8 @@ "revert-text": "", "type": "Type", "type-placeholder": "Select type...", - "unchanged": "" + "unchanged": "", + "value": "" }, "title": "Redact text" } @@ -2125,6 +2158,10 @@ "description-bulk": "The selected items should not be annotated in their respective contexts.", "label": "False positive" }, + "in-document": { + "description": "", + "label": "" + }, "in-dossier": { "description": "Do not annotate ''{value}'' as ''{type}'' in any dossier.", "description-bulk": "Do not annotate the selected terms as their respective types in any dossier.", @@ -2142,6 +2179,25 @@ "title": "Remove {count, plural, one{annotation} other {annotations}}" } }, + "remove-rectangle": { + "dialog": { + "content": { + "options": { + "multiple-pages": { + "description": "", + "extraOptionDescription": "", + "extraOptionLabel": "", + "extraOptionPlaceholder": "", + "label": "" + }, + "only-this-page": { + "description": "", + "label": "" + } + } + } + } + }, "remove-redaction": { "dialog": { "actions": { @@ -2165,6 +2221,10 @@ "extraOptionLabel": "Apply to all dossiers", "label": "False positive" }, + "in-document": { + "description": "", + "label": "" + }, "in-dossier": { "description": "Do not {type} \"{value}\" in any document of the current dossier.", "description-bulk": "", @@ -2307,12 +2367,6 @@ "red-user-admin": "Benutzer-Admin", "regular": "Regulär" }, - "search": { - "active-dossiers": "ganze Plattform", - "all-dossiers": "all documents", - "placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen", - "this-dossier": "in diesem Dossier" - }, "search-screen": { "cols": { "assignee": "Bevollmächtigter", @@ -2336,6 +2390,12 @@ "no-match": "Keine Dokumente entsprechen Ihren aktuellen Filtern.", "table-header": "{length} search {length, plural, one{result} other{results}}" }, + "search": { + "active-dossiers": "ganze Plattform", + "all-dossiers": "all documents", + "placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen", + "this-dossier": "in diesem Dossier" + }, "seconds": "seconds", "size": "Size", "smtp-auth-config": { @@ -2526,10 +2586,6 @@ "view-as": "Ansicht als:", "workflow": "Arbeitsablauf" }, - "viewer-header": { - "all-annotations-loaded": "All annotations loaded", - "load-all-annotations": "Load all annotations" - }, "watermark-screen": { "action": { "change-success": "Das Wasserzeichen wurde aktualisiert!", @@ -2558,6 +2614,10 @@ "orientation": "Ausrichtung", "text-label": "Watermark text", "text-placeholder": "Text eingeben" + }, + "pagination": { + "landscape": "", + "portrait": "" } }, "watermarks-listing": { diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index fbbb9229d..5b74c260d 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -1273,6 +1273,25 @@ }, "side-nav-title": "Configurations" }, + "edit-rectangle": { + "dialog": { + "content": { + "options": { + "multiple-pages": { + "description": "", + "extraOptionDescription": "", + "extraOptionLabel": "", + "extraOptionPlaceholder": "", + "label": "" + }, + "only-this-page": { + "description": "", + "label": "" + } + } + } + } + }, "edit-redaction": { "dialog": { "actions": { @@ -1865,13 +1884,8 @@ "save": "Save" }, "content": { - "apply-on-multiple-pages": "Apply on multiple pages", - "apply-on-multiple-pages-hint": "Minus(-) for range and comma(,) for enumeration.", - "apply-on-multiple-pages-placeholder": "e.g. 1-20,22,32", "classification": "Value / classification", "comment": "Comment", - "dictionary": "Dictionary", - "edit-selected-text": "Edit selected text", "legalBasis": "Legal Basis", "options": { "multiple-pages": { @@ -1888,10 +1902,7 @@ }, "reason": "Reason", "reason-placeholder": "Select a reason ...", - "rectangle": "Custom Rectangle", - "section": "Paragraph / Location", - "text": "Selected text:", - "type": "Entity" + "section": "Paragraph / Location" }, "error": "Error! Invalid page selection", "header": { @@ -2168,6 +2179,25 @@ "title": "Remove {count, plural, one{annotation} other {annotations}}" } }, + "remove-rectangle": { + "dialog": { + "content": { + "options": { + "multiple-pages": { + "description": "", + "extraOptionDescription": "", + "extraOptionLabel": "", + "extraOptionPlaceholder": "", + "label": "" + }, + "only-this-page": { + "description": "", + "label": "" + } + } + } + } + }, "remove-redaction": { "dialog": { "actions": { diff --git a/libs/red-domain/src/lib/redaction-log/recategorization.request.ts b/libs/red-domain/src/lib/redaction-log/recategorization.request.ts index 815d28acf..edf967fc8 100644 --- a/libs/red-domain/src/lib/redaction-log/recategorization.request.ts +++ b/libs/red-domain/src/lib/redaction-log/recategorization.request.ts @@ -1,3 +1,5 @@ +import { IEntityLogEntryPosition } from './entity-log-entry'; + export interface IRecategorizationRequest { readonly annotationId?: string; readonly comment?: string; @@ -15,9 +17,6 @@ export interface IBulkRecategorizationRequest { readonly originTypes: string[]; readonly originLegalBases: string[]; readonly rectangle: boolean; - readonly position?: { - readonly rectangle: number[]; - readonly pageNumber: number; - }; + readonly position?: IEntityLogEntryPosition; readonly pageNumbers?: number[]; } From 05799650e69fe6ad030596ce1d23a48e8be55f5e Mon Sep 17 00:00:00 2001 From: maverickstuder Date: Tue, 8 Oct 2024 14:05:15 +0200 Subject: [PATCH 066/125] RED-10128: Incorrect File Extension for Downloaded (Multi-file) Reports --- .../reports/reports-screen/reports-screen.component.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen/reports-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen/reports-screen.component.ts index 814fbc2da..45956528e 100644 --- a/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen/reports-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen/reports-screen.component.ts @@ -137,7 +137,15 @@ export default class ReportsScreenComponent implements OnInit { } #getTemplateFilename(template: IReportTemplate): string { - return `${template.fileName} ${template.multiFileReport ? this.#translateService.instant(_('reports-screen.multi-file-report')) : ''}`.trim(); + const extensionIndex = template.fileName.lastIndexOf('.'); + const hasExtension = extensionIndex !== -1; + + const baseName = hasExtension ? template.fileName.substring(0, extensionIndex) : template.fileName; + const extension = hasExtension ? template.fileName.substring(extensionIndex) : ''; + + const multiFileSuffix = template.multiFileReport ? ` ${this.#translateService.instant(_('reports-screen.multi-file-report'))}` : ''; + + return `${baseName}${multiFileSuffix}${extension}`.trim(); } async #openOverwriteConfirmationDialog(file: File, multiFileReport: boolean): Promise { From 4526138fae3f53c618ed8068d45f6ea599c9521b Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Wed, 9 Oct 2024 16:54:38 +0300 Subject: [PATCH 067/125] RED-10144: fixed multi-selection randomly activating. --- .../file-workload/file-workload.component.ts | 6 ++- .../services/annotations-listing.service.ts | 38 +++++++++---------- .../services/multi-select.service.ts | 10 +++-- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts index f65803d1d..89a6b6246 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts @@ -58,6 +58,7 @@ import { PageExclusionComponent } from '../page-exclusion/page-exclusion.compone import { PagesComponent } from '../pages/pages.component'; import { ReadonlyBannerComponent } from '../readonly-banner/readonly-banner.component'; import { DocumentInfoComponent } from '../document-info/document-info.component'; +import { getLast } from '@utils/functions'; const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape']; const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown']; @@ -348,6 +349,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On this.pdf.navigateTo(this.#nextPageWithAnnotations()); } + @Debounce(15) navigateAnnotations($event: KeyboardEvent) { const currentPage = untracked(this.pdf.currentPage); const activeAnnotations = untracked(this.activeAnnotations); @@ -366,7 +368,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On const prevPage = this.#prevPageWithAnnotations(); const prevPageAnnotations = this.displayedAnnotations.get(prevPage); - return this.listingService.selectAnnotations(prevPageAnnotations[prevPageAnnotations.length - 1]); + return this.listingService.selectAnnotations(getLast(prevPageAnnotations)); } const page = this._firstSelectedAnnotation.pageNumber; @@ -403,7 +405,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On for (let i = previousPageIdx; i >= 0; i--) { const prevPageAnnotations = this.displayedAnnotations.get(this.displayedPages[i]); if (prevPageAnnotations) { - this.listingService.selectAnnotations(prevPageAnnotations[prevPageAnnotations.length - 1]); + this.listingService.selectAnnotations(getLast(prevPageAnnotations)); break; } } diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotations-listing.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotations-listing.service.ts index fee463b7a..596994c1c 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotations-listing.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotations-listing.service.ts @@ -1,17 +1,16 @@ import { AnnotationWrapper } from '@models/file/annotation.wrapper'; -import { Injectable, OnDestroy } from '@angular/core'; +import { effect, Injectable, untracked } from '@angular/core'; import { EntitiesService, ListingService, SearchService } from '@iqser/common-ui'; -import { filter, tap } from 'rxjs/operators'; import { MultiSelectService } from './multi-select.service'; import { PdfViewer } from '../../pdf-viewer/services/pdf-viewer.service'; import { REDAnnotationManager } from '../../pdf-viewer/services/annotation-manager.service'; -import { Subscription } from 'rxjs'; import { FilterService } from '@iqser/common-ui/lib/filtering'; import { SortingService } from '@iqser/common-ui/lib/sorting'; +import { toSignal } from '@angular/core/rxjs-interop'; @Injectable() -export class AnnotationsListingService extends ListingService implements OnDestroy { - readonly #subscriptions: Subscription; +export class AnnotationsListingService extends ListingService { + readonly selectedLength = toSignal(this.selectedLength$); constructor( protected readonly _filterService: FilterService, @@ -24,23 +23,22 @@ export class AnnotationsListingService extends ListingService ) { super(_filterService, _searchService, _entitiesService, _sortingService); - this.#subscriptions = this.selectedLength$ - .pipe( - filter(length => length > 1), - tap(() => this._multiSelectService.activate()), - ) - .subscribe(); - } - - ngOnDestroy() { - this.#subscriptions.unsubscribe(); + effect( + () => { + if (this.selectedLength() > 1) { + this._multiSelectService.activate(); + } + }, + { allowSignalWrites: true }, + ); } selectAnnotations(annotations: AnnotationWrapper[] | AnnotationWrapper) { annotations = Array.isArray(annotations) ? annotations : [annotations]; const pageNumber = annotations[annotations.length - 1].pageNumber; - const annotationsToSelect = this._multiSelectService.active() ? [...this.selected, ...annotations] : annotations; + const multiSelectActive = untracked(this._multiSelectService.active); + const annotationsToSelect = multiSelectActive ? [...this.selected, ...annotations] : annotations; this.#selectAnnotations(annotationsToSelect, pageNumber); } @@ -49,16 +47,18 @@ export class AnnotationsListingService extends ListingService return; } - if (this._multiSelectService.inactive()) { + const multiSelectInactive = untracked(this._multiSelectService.inactive); + if (multiSelectInactive) { this._annotationManager.deselect(); } - if (pageNumber === this._pdf.currentPage()) { + const currentPage = untracked(this._pdf.currentPage); + if (pageNumber === currentPage) { return this._annotationManager.jumpAndSelect(annotations); } this._pdf.navigateTo(pageNumber); // wait for page to be loaded and to draw annotations - setTimeout(() => this._annotationManager.jumpAndSelect(annotations), 300); + setTimeout(() => this._annotationManager.jumpAndSelect(annotations), 10); } } diff --git a/apps/red-ui/src/app/modules/file-preview/services/multi-select.service.ts b/apps/red-ui/src/app/modules/file-preview/services/multi-select.service.ts index 650e4cde9..c1217ab55 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/multi-select.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/multi-select.service.ts @@ -1,4 +1,4 @@ -import { computed, Injectable, Signal, signal } from '@angular/core'; +import { computed, Injectable, Signal, signal, untracked } from '@angular/core'; import { ViewModeService } from './view-mode.service'; import { FilePreviewStateService } from './file-preview-state.service'; import { ViewMode, ViewModes } from '@red/domain'; @@ -13,13 +13,17 @@ export class MultiSelectService { readonly #active = signal(false); - constructor(protected readonly _viewModeService: ViewModeService, protected readonly _state: FilePreviewStateService) { + constructor( + protected readonly _viewModeService: ViewModeService, + protected readonly _state: FilePreviewStateService, + ) { this.active = this.#active.asReadonly(); this.inactive = computed(() => !this.#active()); } activate() { - if (this.enabled()) { + const enabled = untracked(this.enabled); + if (enabled) { this.#active.set(true); } } From eb255daac26c1b1f3a3ac21090c5546357625dcc Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Wed, 9 Oct 2024 17:57:40 +0300 Subject: [PATCH 068/125] RED-9381: recovered translations for pdf viewer and annotation content. --- apps/red-ui/src/assets/i18n/redact/de.json | 44 +++++++++++----------- apps/red-ui/src/assets/i18n/scm/de.json | 44 +++++++++++----------- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index 430e48213..b99dec7de 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -376,7 +376,7 @@ "removed-manual": "Schwärzung/Hinweis wurde entfernt", "resized": "Schwärzungsbereich wurde geändert" }, - "annotation-content": "", + "annotation-content": "{hasRule, select, true {Regel {matchedRule} trifft zu auf{ruleSymbol}} other {}} {hasReason, select, true {{reason}} other {}} {hasLb, select, true {Rechstgrundlage: {legalBasis}} other {}} {hasOverride, select, true {Entfernt durch manuelles Überschreiben} other {}} {hasSection, select, true {{shouldLower, plural, =0 {I} other {i}}n Abschnitt{sectionSymbol} \"{section}\"} other {}}", "annotation-engines": { "dictionary": "Basiert auf Wörterbuch", "dossier-dictionary": "Basiert auf Dossier-Wörterbuch", @@ -2026,27 +2026,27 @@ }, "pdf-viewer": { "header": { - "all-annotations-loaded": "", - "compare-button": "", - "layers-panel-button": "", - "left-panel-button": "", - "load-all-annotations": "", - "no-outlines-text": "", - "no-signatures-text": "", - "outline-multi-select": "", - "outlines-panel-button": "", - "pan-tool-button": "", - "rectangle-tool-button": "", - "rotate-left-button": "", - "rotate-right-button": "", - "select-tool-button": "", - "signature-panel-button": "", - "thumbnails-panel-button": "", - "toggle-layers": "", - "toggle-readable-redactions": "", - "toggle-tooltips": "", - "zoom-in-button": "", - "zoom-out-button": "" + "all-annotations-loaded": "Alle Annotationen geladen", + "compare-button": "Vergleichen", + "layers-panel-button": "Ebenen", + "left-panel-button": "Panel", + "load-all-annotations": "Alle Annotationen laden", + "no-outlines-text": "Keine Gliederung verfügbar", + "no-signatures-text": "In diesem Dokument gibt es keine Unterschriftenfelder", + "outline-multi-select": "Bearbeiten", + "outlines-panel-button": "Gliederung", + "pan-tool-button": "Verschieben", + "rectangle-tool-button": "Bereichsschwärzung", + "rotate-left-button": "Seite nach links drehen", + "rotate-right-button": "Seite nach rechts drehen", + "select-tool-button": "Auswählen", + "signature-panel-button": "Unterschriften", + "thumbnails-panel-button": "Miniaturansicht", + "toggle-layers": "Layout-Raster {active, select, true{deaktivieren} false{aktivieren} other{}}", + "toggle-readable-redactions": "Schwärzungen {active, select, true{wie im finalen Dokument} false{in Vorschau-Farbe} other{}} anzeigen", + "toggle-tooltips": "Tooltips zu Annotationen {active, select, true{deaktivieren} false{aktivieren} other{}}", + "zoom-in-button": "Vergrößern", + "zoom-out-button": "Verkleinern" }, "text-popup": { "actions": { diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index d90f55996..625377b13 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -376,7 +376,7 @@ "removed-manual": "Schwärzung/Hinweis entfernt", "resized": "Schwärzungsbereich wurde geändert" }, - "annotation-content": "", + "annotation-content": "{hasRule, select, true {Regel {matchedRule} trifft zu auf{ruleSymbol}} other {}} {hasReason, select, true {{reason}} other {}} {hasLb, select, true {Rechstgrundlage: {legalBasis}} other {}} {hasOverride, select, true {Entfernt durch manuelles Überschreiben} other {}} {hasSection, select, true {{shouldLower, plural, =0 {I} other {i}}n Abschnitt{sectionSymbol} \"{section}\"} other {}}", "annotation-engines": { "dictionary": "{isHint, select, true{Hinweis} other{Schwärzung}} basiert auf Wörterbuch", "dossier-dictionary": "Annotation basiert auf Dossier-Wörterbuch", @@ -2026,27 +2026,27 @@ }, "pdf-viewer": { "header": { - "all-annotations-loaded": "", - "compare-button": "", - "layers-panel-button": "", - "left-panel-button": "", - "load-all-annotations": "", - "no-outlines-text": "", - "no-signatures-text": "", - "outline-multi-select": "", - "outlines-panel-button": "", - "pan-tool-button": "", - "rectangle-tool-button": "", - "rotate-left-button": "", - "rotate-right-button": "", - "select-tool-button": "", - "signature-panel-button": "", - "thumbnails-panel-button": "", - "toggle-layers": "", - "toggle-readable-redactions": "", - "toggle-tooltips": "", - "zoom-in-button": "", - "zoom-out-button": "" + "all-annotations-loaded": "Alle Annotationen geladen", + "compare-button": "Vergleichen", + "layers-panel-button": "Ebenen", + "left-panel-button": "Panel", + "load-all-annotations": "Alle Annotationen laden", + "no-outlines-text": "Keine Gliederung verfügbar", + "no-signatures-text": "In diesem Dokument gibt es keine Unterschriftenfelder", + "outline-multi-select": "Bearbeiten", + "outlines-panel-button": "Gliederung", + "pan-tool-button": "Verschieben", + "rectangle-tool-button": "Bereichsschwärzung", + "rotate-left-button": "Seite nach links drehen", + "rotate-right-button": "Seite nach rechts drehen", + "select-tool-button": "Auswählen", + "signature-panel-button": "Unterschriften", + "thumbnails-panel-button": "Miniaturansicht", + "toggle-layers": "Layout-Raster {active, select, true{deaktivieren} false{aktivieren} other{}}", + "toggle-readable-redactions": "Schwärzungen {active, select, true{wie im finalen Dokument} false{in Vorschau-Farbe} other{}} anzeigen", + "toggle-tooltips": "Tooltips zu Annotationen {active, select, true{deaktivieren} false{aktivieren} other{}}", + "zoom-in-button": "Vergrößern", + "zoom-out-button": "Verkleinern" }, "text-popup": { "actions": { From 60e151db0f178182509dd01fc416d081fb0f07ea Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Wed, 9 Oct 2024 18:20:11 +0300 Subject: [PATCH 069/125] RED-9554: use backend error message for dossier attributes. --- .../add-edit-dossier-attribute-dialog.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/red-ui/src/app/modules/admin/screens/dossier-attributes-listing/add-edit-dossier-attribute-dialog/add-edit-dossier-attribute-dialog.component.ts b/apps/red-ui/src/app/modules/admin/screens/dossier-attributes-listing/add-edit-dossier-attribute-dialog/add-edit-dossier-attribute-dialog.component.ts index 52c973b00..51bfcc330 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dossier-attributes-listing/add-edit-dossier-attribute-dialog/add-edit-dossier-attribute-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/dossier-attributes-listing/add-edit-dossier-attribute-dialog/add-edit-dossier-attribute-dialog.component.ts @@ -91,7 +91,7 @@ export class AddEditDossierAttributeDialogComponent extends BaseDialogComponent const createOrUpdate = this._dossierAttributesService.createOrUpdate(attribute, this.data.dossierTemplateId); const result = await createOrUpdate.catch((error: HttpErrorResponse) => { this._loadingService.stop(); - this._toaster.error(_('add-edit-dossier-attribute.error.generic'), { error }); + this._toaster.rawError(error.error.message); return undefined; }); From 6f9d2a7c85b4d20dbf0f19f1d7d80a66f6a8b8c2 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Thu, 10 Oct 2024 12:49:56 +0300 Subject: [PATCH 070/125] RED-10105: added ids on dossier state related buttons. --- .../add-edit-dossier-state-dialog.component.html | 1 + ...confirm-delete-dossier-state-dialog.component.html | 11 ++++++++--- .../dossier-states-table-item.component.html | 4 +++- .../dossier-states-table-item.component.ts | 3 ++- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/screens/dossier-states-listing/add-edit-dossier-state-dialog/add-edit-dossier-state-dialog.component.html b/apps/red-ui/src/app/modules/admin/screens/dossier-states-listing/add-edit-dossier-state-dialog/add-edit-dossier-state-dialog.component.html index 0b6be06f3..0dd00996a 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dossier-states-listing/add-edit-dossier-state-dialog/add-edit-dossier-state-dialog.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/dossier-states-listing/add-edit-dossier-state-dialog/add-edit-dossier-state-dialog.component.html @@ -47,6 +47,7 @@
-
+
- {{ 'confirm-delete-dossier-state.question' | translate : { count: data.dossierCount } }} + {{ 'confirm-delete-dossier-state.question' | translate: { count: data.dossierCount } }}
@@ -30,7 +30,12 @@
- +
diff --git a/apps/red-ui/src/app/modules/admin/screens/dossier-states-listing/dossier-states-table-item/dossier-states-table-item.component.html b/apps/red-ui/src/app/modules/admin/screens/dossier-states-listing/dossier-states-table-item/dossier-states-table-item.component.html index 55c248181..1c30af680 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dossier-states-listing/dossier-states-table-item/dossier-states-table-item.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/dossier-states-listing/dossier-states-table-item/dossier-states-table-item.component.html @@ -13,18 +13,20 @@ {{ state.dossierCount }}
-
+
diff --git a/apps/red-ui/src/app/modules/admin/screens/dossier-states-listing/dossier-states-table-item/dossier-states-table-item.component.ts b/apps/red-ui/src/app/modules/admin/screens/dossier-states-listing/dossier-states-table-item/dossier-states-table-item.component.ts index 93dad3a49..333590477 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dossier-states-listing/dossier-states-table-item/dossier-states-table-item.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/dossier-states-listing/dossier-states-table-item/dossier-states-table-item.component.ts @@ -14,13 +14,14 @@ import { import { MatTooltip } from '@angular/material/tooltip'; import { TranslateModule } from '@ngx-translate/core'; import { NgIf } from '@angular/common'; +import { SnakeCasePipe } from '@common-ui/pipes/snake-case.pipe'; @Component({ selector: 'redaction-dossier-states-table-item', templateUrl: './dossier-states-table-item.component.html', styleUrls: ['./dossier-states-table-item.component.scss'], standalone: true, - imports: [MatTooltip, CircleButtonComponent, TranslateModule, NgIf], + imports: [MatTooltip, CircleButtonComponent, TranslateModule, NgIf, SnakeCasePipe], }) export class DossierStatesTableItemComponent { readonly #dialog = inject(MatDialog); From 46fba3ca5ae7c5f1a3ee2ed9d5cce24771ed694e Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Thu, 10 Oct 2024 14:53:22 +0300 Subject: [PATCH 071/125] RED-9381: added back the watermark pagination translations. --- apps/red-ui/src/assets/i18n/redact/de.json | 4 ++-- apps/red-ui/src/assets/i18n/scm/de.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index b99dec7de..fb5ee644d 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -2616,8 +2616,8 @@ "text-placeholder": "Text eingeben" }, "pagination": { - "landscape": "", - "portrait": "" + "landscape": "Querformat", + "portrait": "Hoch-" } }, "watermarks-listing": { diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 625377b13..570840332 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -2616,8 +2616,8 @@ "text-placeholder": "Text eingeben" }, "pagination": { - "landscape": "", - "portrait": "" + "landscape": "Querformat", + "portrait": "Hoch-" } }, "watermarks-listing": { From 287b95a53878bdc8c524da79b24d7faba16fbb42 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Thu, 10 Oct 2024 16:48:06 +0300 Subject: [PATCH 072/125] RED-9944 - Action Items don't appear in document area in webviewer when bulk-select is still unintenionally active --- .../annotations-list/annotations-list.component.ts | 1 + .../file-preview/services/pdf-proxy.service.ts | 5 ++++- .../services/annotation-manager.service.ts | 13 ++++++++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts b/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts index a6364564f..a57c30e43 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts @@ -79,6 +79,7 @@ export class AnnotationsListComponent extends HasScrollbarDirective { this._multiSelectService.activate(); } this._listingService.selectAnnotations(annotation); + this._annotationManager.setSelectedFromWorkload(); } referenceClicked(annotation: AnnotationWrapper): void { diff --git a/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts b/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts index 7b7560376..0355df684 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts @@ -404,11 +404,14 @@ export class PdfProxyService { const annotationChangesAllowed = !this.#isDocumine || !this._state.file().excludedFromAutomaticAnalysis; const somePending = annotationWrappers.some(a => a.pending); + const selectedFromWorkload = untracked(this._annotationManager.selectedFromWorkload); + actions = - this._multiSelectService.inactive() && !this._documentViewer.selectedText.length && !somePending + (this._multiSelectService.inactive() || !selectedFromWorkload) && !this._documentViewer.selectedText.length && !somePending ? [...actions, ...this._pdfAnnotationActionsService.get(annotationWrappers, annotationChangesAllowed)] : []; this._pdf.instance.UI.annotationPopup.update(actions); + this._annotationManager.resetSelectedFromWorkload(); } #getTitle(type: ManualRedactionEntryType) { diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-manager.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-manager.service.ts index 201d3560c..e214bf07e 100644 --- a/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-manager.service.ts +++ b/apps/red-ui/src/app/modules/pdf-viewer/services/annotation-manager.service.ts @@ -1,5 +1,5 @@ import { inject, Injectable, signal } from '@angular/core'; -import { bool, List } from '@iqser/common-ui/lib/utils'; +import { bool, Debounce, List } from '@iqser/common-ui/lib/utils'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { Core } from '@pdftron/webviewer'; import { getLast, urlFileId } from '@utils/functions'; @@ -23,6 +23,8 @@ export class REDAnnotationManager { annotationHasBeenResized?: boolean = false; readonly #hidden = signal(new Set()); readonly hidden = this.#hidden.asReadonly(); + readonly #selectedFromWorkload = signal(false); + readonly selectedFromWorkload = this.#selectedFromWorkload.asReadonly(); #manager: AnnotationManager; readonly #logger = inject(NGXLogger); readonly #annotationSelected$ = new Subject<[Annotation[], string]>(); @@ -155,6 +157,15 @@ export class REDAnnotationManager { }); } + setSelectedFromWorkload() { + this.#selectedFromWorkload.set(true); + } + + @Debounce() + resetSelectedFromWorkload() { + this.#selectedFromWorkload.set(false); + } + #getById(annotation: AnnotationWrapper | string) { return this.#manager.getAnnotationById(getId(annotation)); } From d4653ca983025c481b7d6b483fdf04410edc0be7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominique=20Eifl=C3=A4nder?= Date: Fri, 11 Oct 2024 11:22:24 +0200 Subject: [PATCH 073/125] RED-10011: Fixed broken menu after accessing configuration --- .../screens/general-config/general-config-screen.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/red-ui/src/app/modules/admin/screens/general-config/general-config-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/general-config/general-config-screen.component.ts index e12195ba4..f40841ee9 100644 --- a/apps/red-ui/src/app/modules/admin/screens/general-config/general-config-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/general-config/general-config-screen.component.ts @@ -29,7 +29,7 @@ export class GeneralConfigScreenComponent extends BaseFormComponent implements A get changed(): boolean { for (const child of this.children) { - if (child.changed) { + if (child?.changed) { return true; } } From 6f5cd79a7fdb92960881efbb80a492a69a478584 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Mon, 14 Oct 2024 13:10:23 +0300 Subject: [PATCH 074/125] RED-10183: use the user preferred language + component refactoring. --- .../user-profile-screen.component.html | 3 +- .../user-profile-screen.component.ts | 113 ++++++++---------- apps/red-ui/src/app/utils/functions.ts | 6 + apps/red-ui/src/app/utils/main.guard.ts | 4 +- libs/common-ui | 2 +- 5 files changed, 64 insertions(+), 64 deletions(-) diff --git a/apps/red-ui/src/app/modules/account/screens/user-profile/user-profile-screen/user-profile-screen.component.html b/apps/red-ui/src/app/modules/account/screens/user-profile/user-profile-screen/user-profile-screen.component.html index 701b675c5..6c7e7b9aa 100644 --- a/apps/red-ui/src/app/modules/account/screens/user-profile/user-profile-screen/user-profile-screen.component.html +++ b/apps/red-ui/src/app/modules/account/screens/user-profile/user-profile-screen/user-profile-screen.component.html @@ -20,6 +20,7 @@ + {{ languageSelectLabel() | translate }} {{ translations[language] | translate }} @@ -41,7 +42,7 @@
> = this.#getForm(); + initialFormValue = this.form.getRawValue(); readonly translations = languagesTranslations; readonly devMode = this._userPreferenceService.isIqserDevMode; + readonly profileKeys = ['email', 'firstName', 'lastName']; + readonly languages = this._translateService.langs; + readonly language = formControlToSignal(this.form.controls.language); + readonly languageSelectLabel = computed(() => this.translations[this.language()]); + constructor( private readonly _userService: UserService, private readonly _loadingService: LoadingService, @@ -49,41 +76,26 @@ export class UserProfileScreenComponent extends BaseFormComponent implements OnI private readonly _pdfViewer: PdfViewer, ) { super(); - this._loadingService.start(); + if (!this._permissionsService.has(Roles.updateMyProfile)) { + this.form.disable(); + } + this._loadingService.stop(); } get languageChanged(): boolean { - return this.#profileModel['language'] !== this.form.get('language').value; + return this.initialFormValue['language'] !== this.form.controls.language.value; } get themeChanged(): boolean { - return this.#profileModel['darkTheme'] !== this.form.get('darkTheme').value; + return this.initialFormValue['darkTheme'] !== this.form.controls.darkTheme.value; } get emailChanged(): boolean { - return this.#profileModel['email'] !== this.form.get('email').value; + return this.initialFormValue['email'] !== this.form.controls.email.value; } get profileChanged(): boolean { - const keys = Object.keys(this.form.getRawValue()); - keys.splice(keys.indexOf('language'), 1); - keys.splice(keys.indexOf('darkTheme'), 1); - - for (const key of keys) { - if (this.#profileModel[key] !== this.form.get(key).value) { - return true; - } - } - - return false; - } - - get languages(): string[] { - return this._translateService.langs; - } - - ngOnInit() { - this._initializeForm(); + return this.profileKeys.some(key => this.initialFormValue[key] !== this.form.get(key).value); } async save(): Promise { @@ -108,16 +120,17 @@ export class UserProfileScreenComponent extends BaseFormComponent implements OnI } if (this.languageChanged) { - await this._languageService.change(this.form.get('language').value); + await this._languageService.change(this.form.controls.language.value); await this._pdfViewer.instance?.UI.setLanguage(this._languageService.currentLanguage); } if (this.themeChanged) { - await this._userPreferenceService.saveTheme(this.form.get('darkTheme').value ? 'dark' : 'light'); + await this._userPreferenceService.saveTheme(this.form.controls.darkTheme.value ? 'dark' : 'light'); } - this._initializeForm(); - + this.initialFormValue = this.form.getRawValue(); + this._changeRef.markForCheck(); + this._loadingService.stop(); this._toaster.success(_('user-profile-screen.update.success')); } catch (e) { this._loadingService.stop(); @@ -128,35 +141,13 @@ export class UserProfileScreenComponent extends BaseFormComponent implements OnI await this._userService.createResetPasswordAction(); } - private _getForm(): UntypedFormGroup { + #getForm() { return this._formBuilder.group({ - email: ['', [Validators.required, Validators.email]], - firstName: [''], - lastName: [''], - language: [''], - darkTheme: [false], + email: [this._userService.currentUser.email ?? '', [Validators.required, Validators.email]], + firstName: [this._userService.currentUser.firstName ?? ''], + lastName: [this._userService.currentUser.lastName ?? ''], + language: [this._userPreferenceService.getLanguage()], + darkTheme: [this._userPreferenceService.getTheme() === 'dark'], }); } - - private _initializeForm(): void { - try { - this.form = this._getForm(); - if (!this._permissionsService.has(Roles.updateMyProfile)) { - this.form.disable(); - } - this.#profileModel = { - email: this._userService.currentUser.email ?? '', - firstName: this._userService.currentUser.firstName ?? '', - lastName: this._userService.currentUser.lastName ?? '', - language: this._languageService.currentLanguage ?? '', - darkTheme: this._userPreferenceService.getTheme() === 'dark', - }; - this.form.patchValue(this.#profileModel, { emitEvent: false }); - this.initialFormValue = this.form.getRawValue(); - } catch (e) { - } finally { - this._loadingService.stop(); - this._changeRef.markForCheck(); - } - } } diff --git a/apps/red-ui/src/app/utils/functions.ts b/apps/red-ui/src/app/utils/functions.ts index 0aca86784..50492e03c 100644 --- a/apps/red-ui/src/app/utils/functions.ts +++ b/apps/red-ui/src/app/utils/functions.ts @@ -2,6 +2,8 @@ import { ITrackable } from '@iqser/common-ui'; import type { List } from '@iqser/common-ui/lib/utils'; import type { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { Dayjs } from 'dayjs'; +import { FormControl } from '@angular/forms'; +import { toSignal } from '@angular/core/rxjs-interop'; export function hexToRgb(hex: string) { const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); @@ -143,3 +145,7 @@ export function urlFileId() { const fileId = splitUrl[splitUrl.length - 1]; return fileId.split('?')[0]; } + +export function formControlToSignal(control: FormControl) { + return toSignal(control.valueChanges, { initialValue: control.value }); +} diff --git a/apps/red-ui/src/app/utils/main.guard.ts b/apps/red-ui/src/app/utils/main.guard.ts index 7c4db96bd..fc137acbb 100644 --- a/apps/red-ui/src/app/utils/main.guard.ts +++ b/apps/red-ui/src/app/utils/main.guard.ts @@ -1,6 +1,6 @@ import { inject } from '@angular/core'; import { Router, RouterStateSnapshot } from '@angular/router'; -import { AsyncGuard, IqserPermissionsService, LoadingService } from '@iqser/common-ui'; +import { AsyncGuard, IqserPermissionsService, LanguageService, LoadingService } from '@iqser/common-ui'; import { TenantsService } from '@iqser/common-ui/lib/tenants'; import { ConfigService } from '@services/config.service'; import { DossiersChangesService } from '@services/dossiers/dossier-changes.service'; @@ -38,6 +38,7 @@ export function mainGuard(): AsyncGuard { const tenantsService = inject(TenantsService); const loadingService = inject(LoadingService); const configService = inject(ConfigService); + const languageService = inject(LanguageService); const baseHref = inject(APP_BASE_HREF); const generalConfig$ = inject(GeneralSettingsService).getGeneralConfigurations(); @@ -51,6 +52,7 @@ export function mainGuard(): AsyncGuard { firstValueFrom(updatedDisplayName$), ]); + await languageService.setInitialLanguage(); const lastDossierTemplate = userPreferenceService.getLastDossierTemplate(); if (lastDossierTemplate && !isUsersAdminOnly) { diff --git a/libs/common-ui b/libs/common-ui index 3c89b8f7e..32de77585 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 3c89b8f7e71eb9253aa40f40c1598eac2c400c71 +Subproject commit 32de7758599d887c4b574d70a11b4e0382f30f0c From 16a8d91815bec54e34f79e3ffb686f13c8c1a194 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Mon, 14 Oct 2024 13:21:49 +0300 Subject: [PATCH 075/125] RED-10132: save comment value for bulkLocal as well. --- .../edit-redaction-dialog.component.ts | 16 ++++++++-------- .../rectangle-annotation-dialog.component.ts | 15 ++++++++------- .../redact-recommendation-dialog.component.ts | 8 ++++++-- .../redact-text-dialog.component.ts | 9 +++++++-- .../remove-redaction-dialog.component.ts | 4 ++-- .../services/annotation-actions.service.ts | 10 +++++++--- .../enhance-manual-redaction-request.utils.ts | 3 ++- .../lib/redaction-log/add-redaction.request.ts | 2 +- .../redaction-log/recategorization.request.ts | 1 + .../redaction-log/remove-redaction.request.ts | 1 + 10 files changed, 43 insertions(+), 26 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts index 1a4e8384e..d1658240f 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts @@ -105,14 +105,6 @@ export class EditRedactionDialogComponent super(); } - extraOptionChanged(option: DetailsRadioOption): void { - if (option.value === RectangleRedactOptions.MULTIPLE_PAGES) { - setTimeout(() => { - this.form.get('option')?.updateValueAndValidity(); - }, 0); - } - } - get displayedDictionaryLabel() { const selectedDictionaryType = this.form.controls.type.value; if (selectedDictionaryType) { @@ -164,6 +156,14 @@ export class EditRedactionDialogComponent return this.annotations.every(annotation => annotation.type === this.annotations[0].type); } + extraOptionChanged(option: DetailsRadioOption): void { + if (option.value === RectangleRedactOptions.MULTIPLE_PAGES) { + setTimeout(() => { + this.form.get('option')?.updateValueAndValidity(); + }, 0); + } + } + async ngOnInit() { this.#setTypes(); const data = await firstValueFrom(this._justificationsService.loadAll(this.#dossier.dossierTemplateId)); diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts index 7bbe89cdb..2427d4aa4 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts @@ -77,7 +77,7 @@ export class RectangleAnnotationDialog private readonly _toaster: Toaster, ) { super(); - this.#dossier = activeDossiersService.find(this.data.dossierId); + this.#dossier = this.activeDossiersService.find(this.data.dossierId); this.options = getRectangleRedactOptions(); @@ -85,6 +85,10 @@ export class RectangleAnnotationDialog this.initialFormValue = this.form.getRawValue(); } + get #isMultiplePages() { + return this.form.get('option').value.value === RectangleRedactOptions.MULTIPLE_PAGES; + } + extraOptionChanged(option: DetailsRadioOption): void { if (option.value === RectangleRedactOptions.MULTIPLE_PAGES) { setTimeout(() => { @@ -109,11 +113,8 @@ export class RectangleAnnotationDialog save() { this.#enhanceManualRedaction(this.data.manualRedactionEntryWrapper.manualRedactionEntry); try { - const annotation = ( - this.form.get('option').value.value === RectangleRedactOptions.MULTIPLE_PAGES - ? this.#multiplePagesRectangle - : this.data.manualRedactionEntryWrapper - ).manualRedactionEntry; + const annotation = (this.#isMultiplePages ? this.#multiplePagesRectangle : this.data.manualRedactionEntryWrapper) + .manualRedactionEntry; super.close({ annotation, }); @@ -143,7 +144,7 @@ export class RectangleAnnotationDialog addRedactionRequest.addToDictionary = false; const commentValue = this.form.get('comment').value; - addRedactionRequest.comment = commentValue ? { text: commentValue } : null; + addRedactionRequest.comment = commentValue ? (this.#isMultiplePages ? commentValue : { text: commentValue }) : null; addRedactionRequest.section = this.form.get('section').value; addRedactionRequest.value = this.form.get('classification').value; } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts index 1bca4ff37..45422d827 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts @@ -102,6 +102,10 @@ export class RedactRecommendationDialogComponent this.form.controls.option.setValue(this.options[0]); } + get isBulkLocal(): boolean { + return this.form.controls.option.value.value === ResizeOptions.IN_DOCUMENT; + } + get displayedDictionaryLabel() { const dictType = this.form.controls.dictionary.value; if (dictType) { @@ -153,7 +157,7 @@ export class RedactRecommendationDialogComponent this.close({ redaction, isMulti: this.isMulti, - bulkLocal: this.form.controls.option.value.value === ResizeOptions.IN_DOCUMENT, + bulkLocal: this.isBulkLocal, }); } @@ -181,7 +185,7 @@ export class RedactRecommendationDialogComponent } const commentValue = this.form.controls.comment.value; - addRedactionRequest.comment = commentValue ? { text: commentValue } : null; + addRedactionRequest.comment = commentValue ? (this.isBulkLocal ? commentValue : { text: commentValue }) : null; addRedactionRequest.addToAllDossiers = this.data.isApprover && this.dictionaryRequest && this.#applyToAllDossiers; return addRedactionRequest; } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts index 21c95b325..be81ad416 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts @@ -10,7 +10,7 @@ import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radi import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component'; import { CircleButtonComponent, HasScrollbarDirective, IconButtonComponent, IconButtonTypes, IqserDialogComponent } from '@iqser/common-ui'; import { TranslateModule } from '@ngx-translate/core'; -import { Dictionary, IAddRedactionRequest, SuperTypes } from '@red/domain'; +import { Dictionary, SuperTypes } from '@red/domain'; import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service'; import { DictionaryService } from '@services/entity-services/dictionary.service'; import { JustificationsService } from '@services/entity-services/justifications.service'; @@ -116,6 +116,10 @@ export class RedactTextDialogComponent ); } + get isBulkLocal() { + return this.form.controls.option.value.value === ResizeOptions.IN_DOCUMENT; + } + get isSystemDefault(): boolean { return this._userPreferences.getAddRedactionDefaultOption() === SystemDefaultOption.SYSTEM_DEFAULT; } @@ -182,7 +186,7 @@ export class RedactTextDialogComponent this.close({ redaction, dictionary: this.dictionaries.find(d => d.type === this.form.controls.dictionary.value), - bulkLocal: this.form.controls.option.value.value === ResizeOptions.IN_DOCUMENT, + bulkLocal: this.isBulkLocal, }); } @@ -259,6 +263,7 @@ export class RedactTextDialogComponent comment: this.form.controls.comment.value, isApprover: this.data.isApprover, applyToAllDossiers: this.#applyToAllDossiers, + bulkLocal: this.isBulkLocal, }; } } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts index a42fa6d61..7ce207c0c 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts @@ -26,7 +26,6 @@ import { } from '../../components/selected-annotations-table/selected-annotations-table.component'; import { getRectangleRedactOptions, getRemoveRedactionOptions } from '../../utils/dialog-options'; import { - EditRedactionOption, RectangleRedactOption, RectangleRedactOptions, RemoveRedactionData, @@ -35,6 +34,7 @@ import { RemoveRedactionResult, ResizeOptions, } from '../../utils/dialog-types'; +import { isJustOne } from '@common-ui/utils'; import { validatePageRange } from '../../utils/form-validators'; import { parseRectanglePosition, parseSelectedPageNumbers } from '../../utils/enhance-manual-redaction-request.utils'; @@ -157,7 +157,7 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< } get isBulk() { - return this.data.redactions.length > 1; + return !isJustOne(this.data.redactions); } get redactedTextsAreaHeight() { diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts index ecf5b5300..d0d81ee5c 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts @@ -51,7 +51,6 @@ import { FilePreviewStateService } from './file-preview-state.service'; import { ManualRedactionService } from './manual-redaction.service'; import { SkippedService } from './skipped.service'; import { NON_READABLE_CONTENT } from '../dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component'; -import { result } from 'lodash-es'; @Injectable() export class AnnotationActionsService { @@ -86,7 +85,7 @@ export class AnnotationActionsService { const { dossierId, fileId } = this._state; const data = { dossier: this._state.dossier(), annotations, hint }; this._dialogService.openDialog('forceAnnotation', data, (request: ILegalBasisChangeRequest) => { - let obs$; + let obs$: Observable; if (request.option === ForceAnnotationOptions.ONLY_HERE) { obs$ = this._manualRedactionService.bulkForce( annotations.map(a => ({ ...request, annotationId: a.id })), @@ -158,6 +157,7 @@ export class AnnotationActionsService { rectangle: annotations[0].AREA, pageNumbers: result.pageNumbers, position: result.position, + comment: result.comment, }; } @@ -487,7 +487,9 @@ export class AnnotationActionsService { for (let i = 0; i < splitNumber; i++) { splitRequests.push(requests.slice(i * maximumNumberEntries, (i + 1) * maximumNumberEntries)); } - splitRequests.push(requests.slice(splitNumber * maximumNumberEntries, splitNumber * maximumNumberEntries + remainder)); + if (remainder) { + splitRequests.push(requests.slice(splitNumber * maximumNumberEntries, splitNumber * maximumNumberEntries + remainder)); + } const promises = []; for (const split of splitRequests) { @@ -601,12 +603,14 @@ export class AnnotationActionsService { originTypes: [redaction.entry.type], pageNumbers: dialogResult.pageNumbers, position: dialogResult.position, + comment: dialogResult.comment, }; } return { value: redaction.value, rectangle: false, + comment: dialogResult.comment, }; } diff --git a/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts b/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts index 635549d37..bdf220456 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts @@ -12,6 +12,7 @@ export interface EnhanceRequestData { readonly comment: string; readonly isApprover: boolean; readonly applyToAllDossiers: boolean; + readonly bulkLocal: boolean; } interface MultiplePagesRectangleData { @@ -43,7 +44,7 @@ export const enhanceManualRedactionRequest = (addRedactionRequest: IAddRedaction addRedactionRequest.reason = 'Dictionary Request'; } const commentValue = data.comment; - addRedactionRequest.comment = commentValue ? { text: commentValue } : null; + addRedactionRequest.comment = commentValue ? (data.bulkLocal ? commentValue : { text: commentValue }) : null; addRedactionRequest.addToAllDossiers = data.isApprover && data.dictionaryRequest && data.applyToAllDossiers; }; diff --git a/libs/red-domain/src/lib/redaction-log/add-redaction.request.ts b/libs/red-domain/src/lib/redaction-log/add-redaction.request.ts index 2665fa420..b3af322c8 100644 --- a/libs/red-domain/src/lib/redaction-log/add-redaction.request.ts +++ b/libs/red-domain/src/lib/redaction-log/add-redaction.request.ts @@ -5,7 +5,7 @@ import { DictionaryEntryType } from './dictionary-entry-types'; export interface IAddRedactionRequest { addToDictionary?: boolean; dictionaryEntryType?: DictionaryEntryType; - comment?: { text: string }; + comment?: { text: string } | string; legalBasis?: string; positions?: List; reason?: string; diff --git a/libs/red-domain/src/lib/redaction-log/recategorization.request.ts b/libs/red-domain/src/lib/redaction-log/recategorization.request.ts index edf967fc8..9939b140a 100644 --- a/libs/red-domain/src/lib/redaction-log/recategorization.request.ts +++ b/libs/red-domain/src/lib/redaction-log/recategorization.request.ts @@ -19,4 +19,5 @@ export interface IBulkRecategorizationRequest { readonly rectangle: boolean; readonly position?: IEntityLogEntryPosition; readonly pageNumbers?: number[]; + readonly comment?: string; } diff --git a/libs/red-domain/src/lib/redaction-log/remove-redaction.request.ts b/libs/red-domain/src/lib/redaction-log/remove-redaction.request.ts index 364198733..df966c022 100644 --- a/libs/red-domain/src/lib/redaction-log/remove-redaction.request.ts +++ b/libs/red-domain/src/lib/redaction-log/remove-redaction.request.ts @@ -16,4 +16,5 @@ export interface IBulkLocalRemoveRequest { originTypes?: string[]; originLegalBases?: string[]; pageNumbers?: number[]; + comment?: string; } From 46202a0b649075198549baa072ef2296ff4e5154 Mon Sep 17 00:00:00 2001 From: maverickstuder Date: Mon, 14 Oct 2024 12:30:14 +0200 Subject: [PATCH 076/125] RED-10072: AI description field and toggle for entities --- .../add-edit-entity.component.html | 18 ++++++++++++++++++ .../add-edit-entity.component.ts | 8 +++++++- apps/red-ui/src/assets/i18n/redact/de.json | 6 +++--- apps/red-ui/src/assets/i18n/redact/en.json | 6 +++--- apps/red-ui/src/assets/i18n/scm/de.json | 6 +++--- apps/red-ui/src/assets/i18n/scm/en.json | 6 +++--- .../src/lib/dictionaries/dictionary.model.ts | 4 ++++ .../src/lib/dictionaries/dictionary.ts | 8 ++++++++ 8 files changed, 49 insertions(+), 13 deletions(-) diff --git a/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.html b/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.html index d5790c69f..01e6d4a67 100644 --- a/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.html +++ b/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.html @@ -78,6 +78,24 @@ >
+
+ + {{ 'add-edit-entity.form.ai-creation-enabled' | translate }} + +
+ +
+ + +
+
{{ 'add-edit-entity.form.has-dictionary' | translate }} diff --git a/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.ts b/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.ts index a45e20c63..545d63f57 100644 --- a/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.ts @@ -9,7 +9,7 @@ import { MatSelect } from '@angular/material/select'; import { MatSlideToggle } from '@angular/material/slide-toggle'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { RoundCheckboxComponent } from '@common-ui/inputs/round-checkbox/round-checkbox.component'; -import { BaseFormComponent, getConfig, HasScrollbarDirective, LoadingService, Toaster } from '@iqser/common-ui'; +import { BaseFormComponent, getConfig, isIqserDevMode, HasScrollbarDirective, LoadingService, Toaster } from '@iqser/common-ui'; import { TranslateModule } from '@ngx-translate/core'; import { Dictionary, IDictionary } from '@red/domain'; import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service'; @@ -18,6 +18,7 @@ import { toSnakeCase } from '@utils/functions'; import { ColorPickerModule } from 'ngx-color-picker'; import { Observable } from 'rxjs'; import { map, startWith } from 'rxjs/operators'; +import { log } from '@common-ui/utils'; const REDACTION_FIELDS = ['defaultReason']; @@ -62,6 +63,7 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit colors: Color[]; readonly isDocumine = getConfig().IS_DOCUMINE; + readonly isIqserDevMode = isIqserDevMode(); constructor( private readonly _dictionariesMapService: DictionariesMapService, @@ -158,6 +160,8 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit skippedHexColor: [this.entity?.skippedHexColor, [Validators.required, Validators.minLength(7)]], type: [this.entity?.type], description: [this.entity?.description], + aiCreationEnabled: [this.entity?.aiCreationEnabled], + aiDescription: [this.entity?.aiDescription], rank: [{ value: this.entity?.rank, disabled: this.#isSystemManaged }, Validators.required], hint: [{ value: !!this.entity?.hint, disabled: this.#isSystemManaged }], hasDictionary: [ @@ -250,6 +254,8 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit dossierTemplateId: this.dossierTemplateId, type: this.form.get('type').value, description: this.form.get('description').value, + aiCreationEnabled: this.form.get('aiCreationEnabled').value, + aiDescription: this.form.get('aiDescription').value, hint: this.#isHint, rank: this.form.get('rank').value, caseInsensitive: !this.form.get('caseSensitive').value, diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index fb5ee644d..df3f3f25c 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -112,9 +112,6 @@ } }, "add-edit-dossier-attribute": { - "error": { - "generic": "Speichern des Attributs fehlgeschlagen." - }, "form": { "label": "Name des Attributs", "label-placeholder": "Namen eingeben", @@ -138,6 +135,9 @@ }, "add-edit-entity": { "form": { + "ai-creation-enabled": "AI Erzeugung aktivieren", + "ai-description": "AI Beschreibung", + "ai-description-placeholder": "AI Beschreibung eingeben", "case-sensitive": "Groß-/Kleinschreibung beachten", "color": "Farbe {type, select, redaction{Schwärzung} hint{Hinweis} recommendation{Empfehlung} skipped{Ingorierte Schwärzung} ignored{Ignorierter Hinweis} other{}}", "color-placeholder": "#", diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index b4b07efe4..8c1736655 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -112,9 +112,6 @@ } }, "add-edit-dossier-attribute": { - "error": { - "generic": "Failed to save attribute." - }, "form": { "label": "Attribute name", "label-placeholder": "Enter name", @@ -138,6 +135,9 @@ }, "add-edit-entity": { "form": { + "ai-creation-enabled": "Enable AI creation", + "ai-description": "AI Description", + "ai-description-placeholder": "Enter AI description", "case-sensitive": "Case-sensitive", "color": "{type, select, redaction{Redaction} hint{Hint} recommendation{Recommendation} skipped{Skipped redaction} ignored{Ignored hint} other{}} color", "color-placeholder": "#", diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 570840332..6c31ddea3 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -112,9 +112,6 @@ } }, "add-edit-dossier-attribute": { - "error": { - "generic": "Speichern des Attributs fehlgeschlagen." - }, "form": { "label": "Name des Attributs", "label-placeholder": "Namen eingeben", @@ -138,6 +135,9 @@ }, "add-edit-entity": { "form": { + "ai-creation-enabled": "AI Erzeugung aktivieren", + "ai-description": "AI Beschreibung", + "ai-description-placeholder": "AI Beschreibung eingeben", "case-sensitive": "Groß-/Kleinschreibung beachten", "color": "Farbe {type, select, redaction{Annotation} hint{Hinweis} recommendation{Empfehlung} skipped{Übersprungene Annotation} ignored{Ignorierter Hinweis} other{}}", "color-placeholder": "#", diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index 5b74c260d..f751bf400 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -112,9 +112,6 @@ } }, "add-edit-dossier-attribute": { - "error": { - "generic": "Failed to save attribute!" - }, "form": { "label": "Attribute name", "label-placeholder": "Enter name", @@ -138,6 +135,9 @@ }, "add-edit-entity": { "form": { + "ai-creation-enabled": "Enable AI creation", + "ai-description": "AI Description", + "ai-description-placeholder": "Enter AI description", "case-sensitive": "Case-sensitive", "color": "{type, select, redaction{Annotation} hint{Hint} recommendation{Recommendation} skipped{Skipped annotation} ignored{Ignored hint} other{}} Color", "color-placeholder": "#", diff --git a/libs/red-domain/src/lib/dictionaries/dictionary.model.ts b/libs/red-domain/src/lib/dictionaries/dictionary.model.ts index 4c33e7840..86e40c4e3 100644 --- a/libs/red-domain/src/lib/dictionaries/dictionary.model.ts +++ b/libs/red-domain/src/lib/dictionaries/dictionary.model.ts @@ -7,6 +7,8 @@ export class Dictionary extends Entity implements IDictionary { readonly addToDictionaryAction: boolean; readonly caseInsensitive: boolean; readonly description: string; + readonly aiCreationEnabled: boolean; + readonly aiDescription: string; readonly dossierTemplateId?: string; readonly hexColor?: string; readonly recommendationHexColor?: string; @@ -33,6 +35,8 @@ export class Dictionary extends Entity implements IDictionary { this.addToDictionaryAction = !!entity.addToDictionaryAction; this.caseInsensitive = !!entity.caseInsensitive; this.description = entity.description ?? ''; + this.aiCreationEnabled = !!entity.aiCreationEnabled; + this.aiDescription = entity.aiDescription ?? ''; this.dossierTemplateId = entity.dossierTemplateId; this.entries = entity.entries ?? []; this.falsePositiveEntries = entity.falsePositiveEntries ?? []; diff --git a/libs/red-domain/src/lib/dictionaries/dictionary.ts b/libs/red-domain/src/lib/dictionaries/dictionary.ts index d146393bf..6f01105fc 100644 --- a/libs/red-domain/src/lib/dictionaries/dictionary.ts +++ b/libs/red-domain/src/lib/dictionaries/dictionary.ts @@ -16,6 +16,14 @@ export interface IDictionary { * The description of the dictionary type */ readonly description?: string; + /** + * True if the entries in this type should also be created via AI, default is false. + */ + readonly aiCreationEnabled?: boolean; + /** + * The AI description of the dictionary type + */ + readonly aiDescription?: string; /** * The DossierTemplate Id for this type */ From 381874145343fa7500eac7c63bc06e01952b07a0 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Mon, 14 Oct 2024 16:07:55 +0300 Subject: [PATCH 077/125] RED-10179 & RED-10177: fixed translations. --- apps/red-ui/src/assets/i18n/redact/de.json | 15 ++++++--------- apps/red-ui/src/assets/i18n/redact/en.json | 13 +++++-------- apps/red-ui/src/assets/i18n/scm/de.json | 11 ++++------- apps/red-ui/src/assets/i18n/scm/en.json | 3 --- 4 files changed, 15 insertions(+), 27 deletions(-) diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index fb5ee644d..f9a106942 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -112,9 +112,6 @@ } }, "add-edit-dossier-attribute": { - "error": { - "generic": "Speichern des Attributs fehlgeschlagen." - }, "form": { "label": "Name des Attributs", "label-placeholder": "Namen eingeben", @@ -1304,8 +1301,8 @@ "legal-basis": "Rechtsgrundlage", "options": { "in-document": { - "description": "", - "label": "" + "description": "Bearbeiten Sie die Schwärzung dieses Begriffs an allen Stellen in diesem Dokument.", + "label": "In Dokument ändern" }, "only-here": { "description": "Bearbeiten Sie die Schwärzung nur an dieser Stelle im Dokument.", @@ -2115,8 +2112,8 @@ "legal-basis": "Rechtsgrundlage", "options": { "in-document": { - "description": "", - "label": "" + "description": "Fügen Sie die Schwärzung an allen Stellen in diesem Dokument hinzu.", + "label": "Im Dokument schwärzen" }, "in-dossier": { "description": "Fügen Sie die Schwärzung zu jedem Dokument in {dossierName} hinzu.", @@ -2222,8 +2219,8 @@ "label": "In diesem Kontext aus Dossier entfernen" }, "in-document": { - "description": "", - "label": "" + "description": "{isImage, select, image{Das Bild} other{der Begriff}} wird auf keiner Seite dieses Dokuments automatisch geschwärzt.", + "label": "Aus Dokument entfernen" }, "in-dossier": { "description": "Der Begriff wird in keinem Dokument dieses Dossiers {type, select, hint{annotiert} other{automatisch geschwärzt}}.", diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index b4b07efe4..274d34e4a 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -112,9 +112,6 @@ } }, "add-edit-dossier-attribute": { - "error": { - "generic": "Failed to save attribute." - }, "form": { "label": "Attribute name", "label-placeholder": "Enter name", @@ -1278,7 +1275,7 @@ "content": { "options": { "multiple-pages": { - "description": "Edit redaction the range of pages", + "description": "Edit redaction on following range of pages", "extraOptionDescription": "Minus(-) for range and comma(,) for enumeration", "extraOptionLabel": "Range", "extraOptionPlaceholder": "e.g. 1-20,22,32", @@ -1889,14 +1886,14 @@ "legalBasis": "Legal basis", "options": { "multiple-pages": { - "description": "Edit redaction the range of pages", + "description": "Add redaction on following range of pages", "extraOptionDescription": "Minus(-) for range and comma(,) for enumeration", "extraOptionLabel": "Range", "extraOptionPlaceholder": "e.g. 1-20,22,32", "label": "Apply on multiple pages" }, "only-this-page": { - "description": "Edit redaction only at this position in this document", + "description": "Add redaction only at this position in this document", "label": "Apply only on this page" } }, @@ -2184,14 +2181,14 @@ "content": { "options": { "multiple-pages": { - "description": "Edit redaction the range of pages", + "description": "Remove redaction on following range of pages", "extraOptionDescription": "Minus(-) for range and comma(,) for enumeration", "extraOptionLabel": "Range", "extraOptionPlaceholder": "e.g. 1-20,22,32", "label": "Remove on all pages" }, "only-this-page": { - "description": "Edit redaction only at this position in this document", + "description": "Remove redaction only at this position in this document", "label": "Remove only on this page" } } diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 570840332..5dd0fb957 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -112,9 +112,6 @@ } }, "add-edit-dossier-attribute": { - "error": { - "generic": "Speichern des Attributs fehlgeschlagen." - }, "form": { "label": "Name des Attributs", "label-placeholder": "Namen eingeben", @@ -2115,8 +2112,8 @@ "legal-basis": "Legal basis", "options": { "in-document": { - "description": "", - "label": "" + "description": "Fügen Sie die Schwärzung an allen Stellen in diesem Dokument hinzu.", + "label": "Im Dokument schwärzen" }, "in-dossier": { "description": "Add redaction in every document in {dossierName}.", @@ -2222,8 +2219,8 @@ "label": "False positive" }, "in-document": { - "description": "", - "label": "" + "description": "{isImage, select, image{Das Bild} other{der Begriff}} wird auf keiner Seite dieses Dokuments automatisch geschwärzt.", + "label": "Aus Dokument entfernen" }, "in-dossier": { "description": "Do not {type} \"{value}\" in any document of the current dossier.", diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index 5b74c260d..ad40d7fbc 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -112,9 +112,6 @@ } }, "add-edit-dossier-attribute": { - "error": { - "generic": "Failed to save attribute!" - }, "form": { "label": "Attribute name", "label-placeholder": "Enter name", From ace0ecfce140007c0817401fd8df8056636015e4 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Mon, 14 Oct 2024 16:34:00 +0300 Subject: [PATCH 078/125] RED-10182: fixed scrolling to annotation in workload upon selection. --- .../components/file-workload/file-workload.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts index 89a6b6246..788204e00 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts @@ -308,7 +308,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On @Debounce() scrollToSelectedAnnotation(): void { const annotationsElement = untracked(this._annotationsElement); - if (this.listingService.selected.length === 0 || annotationsElement) { + if (this.listingService.selected.length === 0 || !annotationsElement) { return; } const elements: HTMLElement[] = annotationsElement.nativeElement.querySelectorAll( From 851b9fb3b2e06cb2741ee738a7df09299ff9ec23 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Mon, 14 Oct 2024 17:04:27 +0300 Subject: [PATCH 079/125] RED-10190: fixed notifications redirect links. --- apps/red-ui/src/app/services/notifications.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/red-ui/src/app/services/notifications.service.ts b/apps/red-ui/src/app/services/notifications.service.ts index ad596231b..47196daa5 100644 --- a/apps/red-ui/src/app/services/notifications.service.ts +++ b/apps/red-ui/src/app/services/notifications.service.ts @@ -95,7 +95,7 @@ export class NotificationsService extends EntitiesService Date: Mon, 14 Oct 2024 17:26:09 +0300 Subject: [PATCH 080/125] RED-10180: update common ui + remove unused import. --- .../components/add-edit-entity/add-edit-entity.component.ts | 1 - libs/common-ui | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.ts b/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.ts index 545d63f57..f6ab4f7a7 100644 --- a/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.ts @@ -18,7 +18,6 @@ import { toSnakeCase } from '@utils/functions'; import { ColorPickerModule } from 'ngx-color-picker'; import { Observable } from 'rxjs'; import { map, startWith } from 'rxjs/operators'; -import { log } from '@common-ui/utils'; const REDACTION_FIELDS = ['defaultReason']; diff --git a/libs/common-ui b/libs/common-ui index 32de77585..e88929f0d 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 32de7758599d887c4b574d70a11b4e0382f30f0c +Subproject commit e88929f0d48e54298d85ef05ea467980be11524b From 4593b09bf3690fd5af0125c8dc5e174404b8572a Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Tue, 15 Oct 2024 15:43:13 +0300 Subject: [PATCH 081/125] RED-7340 - Rectangle redactions: Use bulk-local redactions + New dialog design --- .../rectangle-annotation-dialog.component.ts | 4 ---- .../remove-redaction-dialog.component.ts | 5 +++-- .../services/annotation-actions.service.ts | 17 +++++------------ .../enhance-manual-redaction-request.utils.ts | 17 +++++------------ .../file-preview/utils/form-validators.ts | 7 ++++--- 5 files changed, 17 insertions(+), 33 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts index 2427d4aa4..0fd48e9db 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts @@ -170,10 +170,6 @@ export class RectangleAnnotationDialog } for (let page = startPage; page <= endPage; page++) { - if (page === wrapper.manualRedactionEntry.positions[0].page) { - continue; - } - wrapper.manualRedactionEntry.pageNumbers.push(page); } }); diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts index 7ce207c0c..b7c80d8ed 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts @@ -112,7 +112,7 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< readonly redactedTexts = this.data.redactions.map(annotation => annotation.value); form: UntypedFormGroup = this._formBuilder.group({ comment: [null], - option: [this.defaultOption, validatePageRange()], + option: [this.defaultOption, validatePageRange(true)], }); readonly selectedOption = toSignal(this.form.get('option').valueChanges.pipe(map(value => value.value))); @@ -177,6 +177,7 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< } save(): void { + const optionValue = this.form.controls.option.value.value; const pageNumbers = parseSelectedPageNumbers( this.form.get('option').value.additionalInput?.value, this.data.file, @@ -186,7 +187,7 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< this.close({ ...this.form.getRawValue(), - bulkLocal: this.form.controls.option.value.value === ResizeOptions.IN_DOCUMENT, + bulkLocal: optionValue === ResizeOptions.IN_DOCUMENT || optionValue === RectangleRedactOptions.MULTIPLE_PAGES, pageNumbers, position, }); diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts index d0d81ee5c..04bae147e 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts @@ -596,20 +596,13 @@ export class AnnotationActionsService { ): List | IBulkLocalRemoveRequest { if (dialogResult.bulkLocal || !!dialogResult.pageNumbers.length) { const redaction = redactions[0]; - if (redaction.value === NON_READABLE_CONTENT) { - return { - value: redaction.value, - rectangle: true, - originTypes: [redaction.entry.type], - pageNumbers: dialogResult.pageNumbers, - position: dialogResult.position, - comment: dialogResult.comment, - }; - } - return { value: redaction.value, - rectangle: false, + rectangle: redaction.value === NON_READABLE_CONTENT, + originTypes: [redaction.entry.type], + originLegalBases: [redaction.legalBasis], + pageNumbers: dialogResult.pageNumbers, + position: dialogResult.position, comment: dialogResult.comment, }; } diff --git a/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts b/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts index bdf220456..3a28bf209 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts @@ -65,10 +65,6 @@ export const parseSelectedPageNumbers = (inputValue: string, file: File, annotat } for (let page = startPage; page <= endPage; page++) { - if (page === annotation.positions[0].page) { - continue; - } - pageNumbers.push(page); } }); @@ -77,12 +73,9 @@ export const parseSelectedPageNumbers = (inputValue: string, file: File, annotat }; export const parseRectanglePosition = (annotation: AnnotationWrapper) => { - if (annotation.AREA) { - const position = annotation.positions[0]; - return { - rectangle: [position.topLeft.x, position.topLeft.y, position.width, position.height], - pageNumber: position.page, - } as IEntityLogEntryPosition; - } - return null; + const position = annotation.positions[0]; + return { + rectangle: [position.topLeft.x, position.topLeft.y, position.width, position.height], + pageNumber: position.page, + } as IEntityLogEntryPosition; }; diff --git a/apps/red-ui/src/app/modules/file-preview/utils/form-validators.ts b/apps/red-ui/src/app/modules/file-preview/utils/form-validators.ts index 233aed553..b66980731 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/form-validators.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/form-validators.ts @@ -1,11 +1,12 @@ import { AbstractControl, ValidatorFn } from '@angular/forms'; -export const validatePageRange = (): ValidatorFn => { +export const validatePageRange = (allowEmpty = false): ValidatorFn => { return (control: AbstractControl): { [key: string]: any } | null => { const option = control.value; if (option?.additionalInput) { - const validRange = /^(\d+(-\d+)?)(,\d+(-\d+)?)*$/.test(option.additionalInput.value); - return validRange ? null : { invalidRange: true }; + const value = option.additionalInput.value; + const validRange = /^(\d+(-\d+)?)(,\d+(-\d+)?)*$/.test(value); + return validRange || (!value.length && allowEmpty) ? null : { invalidRange: true }; } return null; }; From 20d03344894d4db46ec26289b01d06f544278eae Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Wed, 16 Oct 2024 11:56:00 +0300 Subject: [PATCH 082/125] RED-7340 - Rectangle redactions: Use bulk-local redactions + New dialog design --- .../rectangle-annotation-dialog.component.scss | 2 +- libs/common-ui | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.scss b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.scss index a60ee0967..f441afc88 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.scss @@ -3,7 +3,7 @@ } .dialog-content { - height: 650px; + height: 610px; overflow-y: auto; } diff --git a/libs/common-ui b/libs/common-ui index e88929f0d..ba85260cc 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit e88929f0d48e54298d85ef05ea467980be11524b +Subproject commit ba85260cc4a3e780a37b3f41be26b83d045a1dcb From a5e70e9def5ddb875122a40c89e636af34cb9570 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Wed, 16 Oct 2024 13:56:43 +0300 Subject: [PATCH 083/125] RED-10190: fixed notification padding. --- .../app/components/notifications/notifications.component.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/red-ui/src/app/components/notifications/notifications.component.scss b/apps/red-ui/src/app/components/notifications/notifications.component.scss index 57b77036c..1b1824665 100644 --- a/apps/red-ui/src/app/components/notifications/notifications.component.scss +++ b/apps/red-ui/src/app/components/notifications/notifications.component.scss @@ -22,7 +22,7 @@ } .mat-mdc-menu-item.notification { - padding: 8px 26px 10px 8px; + padding: 8px 26px 10px 8px !important; margin: 2px 0 0 0; height: fit-content; position: relative; From d4b419ded86b288f0a848a002ff61a14ab9ba21c Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Wed, 16 Oct 2024 14:09:58 +0300 Subject: [PATCH 084/125] RED-10180: sync localazy translation. --- apps/red-ui/src/assets/i18n/redact/de.json | 2 +- apps/red-ui/src/assets/i18n/scm/de.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index 000d06045..52216ce23 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -2134,7 +2134,7 @@ "type": "Typ", "type-placeholder": "Typ auswählen...", "unchanged": "Ungeändert", - "value": "" + "value": "Wert" }, "title": "Text schwärzen" } diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 228da81eb..08266540c 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -2134,7 +2134,7 @@ "type": "Type", "type-placeholder": "Select type...", "unchanged": "", - "value": "" + "value": "Wert" }, "title": "Redact text" } From 5dfea0175d94e8b1e77eb494df46cf0b54ffd53b Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Wed, 16 Oct 2024 14:35:48 +0300 Subject: [PATCH 085/125] WIP on master RED-7340 - prefill the range fields in the edit and remove dialogs --- .../edit-redaction-dialog.component.ts | 10 +++- .../remove-redaction-dialog.component.ts | 10 +++- .../services/annotation-actions.service.ts | 6 +- .../file-preview/utils/dialog-types.ts | 2 + .../enhance-manual-redaction-request.utils.ts | 60 ++++++++++++++++++- 5 files changed, 84 insertions(+), 4 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts index d1658240f..403a7e829 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts @@ -37,7 +37,7 @@ import { import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component'; import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option'; import { validatePageRange } from '../../utils/form-validators'; -import { parseRectanglePosition, parseSelectedPageNumbers } from '../../utils/enhance-manual-redaction-request.utils'; +import { parseRectanglePosition, parseSelectedPageNumbers, prefillPageRange } from '../../utils/enhance-manual-redaction-request.utils'; interface TypeSelectOptions { type: string; @@ -103,6 +103,14 @@ export class EditRedactionDialogComponent private readonly _dictionaryService: DictionaryService, ) { super(); + + if (this.allRectangles) { + prefillPageRange( + this.data.annotations[0], + this.data.allFileAnnotations, + this.options as DetailsRadioOption[], + ); + } } get displayedDictionaryLabel() { diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts index b7c80d8ed..b27c5dbbf 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts @@ -36,7 +36,7 @@ import { } from '../../utils/dialog-types'; import { isJustOne } from '@common-ui/utils'; import { validatePageRange } from '../../utils/form-validators'; -import { parseRectanglePosition, parseSelectedPageNumbers } from '../../utils/enhance-manual-redaction-request.utils'; +import { parseRectanglePosition, parseSelectedPageNumbers, prefillPageRange } from '../../utils/enhance-manual-redaction-request.utils'; @Component({ templateUrl: './remove-redaction-dialog.component.html', @@ -140,6 +140,14 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< private readonly _userPreferences: UserPreferenceService, ) { super(); + + if (this.#allRectangles) { + prefillPageRange( + this.data.redactions[0], + this.data.allFileRedactions, + this.options as DetailsRadioOption[], + ); + } } get hasFalsePositiveOption() { diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts index 04bae147e..c513b2089 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts @@ -95,7 +95,7 @@ export class AnnotationActionsService { ); } else { const addAnnotationRequest = annotations.map(a => ({ - comment: { text: request.comment }, + comment: request.comment, legalBasis: request.legalBasis, reason: request.reason, positions: a.positions, @@ -113,9 +113,11 @@ export class AnnotationActionsService { async editRedaction(annotations: AnnotationWrapper[]) { const { dossierId, file } = this._state; + const allFileAnnotations = this._fileDataService.annotations(); const includeUnprocessed = annotations.every(annotation => this.#includeUnprocessed(annotation, true)); const data = { annotations, + allFileAnnotations, dossierId, file: file(), }; @@ -184,9 +186,11 @@ export class AnnotationActionsService { const dossierTemplate = this._dossierTemplatesService.find(this._state.dossierTemplateId); const isApprover = this._permissionsService.isApprover(this._state.dossier()); const { file } = this._state; + const allFileRedactions = this._fileDataService.annotations(); const data = { redactions, + allFileRedactions, file: file(), dossier: this._state.dossier(), falsePositiveContext: redactions.map(r => this.#getFalsePositiveText(r)), diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts index 00131bcda..e0f84cba2 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts @@ -64,6 +64,7 @@ export interface RedactTextData { export interface EditRedactionData { annotations: AnnotationWrapper[]; + allFileAnnotations?: AnnotationWrapper[]; dossierId: string; file: File; isApprover?: boolean; @@ -135,6 +136,7 @@ export interface RemoveRedactionPermissions { export interface RemoveRedactionData { redactions: AnnotationWrapper[]; + allFileRedactions?: AnnotationWrapper[]; dossier: Dossier; file?: File; falsePositiveContext: string[]; diff --git a/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts b/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts index 3a28bf209..17e16a046 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/enhance-manual-redaction-request.utils.ts @@ -1,7 +1,8 @@ import { Dictionary, File, IAddRedactionRequest, IEntityLogEntryPosition, SuperType } from '@red/domain'; import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper'; -import { LegalBasisOption } from './dialog-types'; +import { LegalBasisOption, RectangleRedactOption, RectangleRedactOptions } from './dialog-types'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; +import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option'; export interface EnhanceRequestData { readonly type: SuperType | null; @@ -79,3 +80,60 @@ export const parseRectanglePosition = (annotation: AnnotationWrapper) => { pageNumber: position.page, } as IEntityLogEntryPosition; }; + +export const prefillPageRange = ( + annotation: AnnotationWrapper, + allFileAnnotations: AnnotationWrapper[], + options: DetailsRadioOption[], +) => { + const option = options.find(o => o.value === RectangleRedactOptions.MULTIPLE_PAGES); + const pages = extractPages(annotation, allFileAnnotations); + option.additionalInput.value = toRangeString(pages); +}; + +const extractPages = (annotation: AnnotationWrapper, allFileAnnotations: AnnotationWrapper[]): number[] => { + return allFileAnnotations.reduce((pages, a) => { + const position = a.positions[0]; + const annotationPosition = annotation.positions[0]; + if ( + position.height === annotationPosition.height && + position.width === annotationPosition.width && + position.topLeft.x === annotationPosition.topLeft.x && + position.topLeft.y === annotationPosition.topLeft.y + ) { + pages.push(position.page); + } + return pages; + }, []); +}; + +const toRangeString = (pages: number[]): string => { + if (pages.length === 0) { + return ''; + } + + let ranges = []; + let start = pages[0]; + let end = pages[0]; + + for (let i = 1; i < pages.length; i++) { + if (pages[i] === end + 1) { + end = pages[i]; + } else { + if (start === end) { + ranges.push(`${start}`); + } else { + ranges.push(`${start}-${end}`); + } + start = end = pages[i]; + } + } + + if (start === end) { + ranges.push(`${start}`); + } else { + ranges.push(`${start}-${end}`); + } + + return ranges.join(','); +}; From b85559c68661924d08fd872dba15608e4e5f24bf Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Wed, 16 Oct 2024 15:27:33 +0300 Subject: [PATCH 086/125] RED-8277: made it possible to open dossiers and files in a new tab. --- .../components/file-attribute/file-attribute.component.ts | 2 ++ libs/common-ui | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/red-ui/src/app/modules/dossier-overview/components/file-attribute/file-attribute.component.ts b/apps/red-ui/src/app/modules/dossier-overview/components/file-attribute/file-attribute.component.ts index e98c1333c..d131faa9d 100644 --- a/apps/red-ui/src/app/modules/dossier-overview/components/file-attribute/file-attribute.component.ts +++ b/apps/red-ui/src/app/modules/dossier-overview/components/file-attribute/file-attribute.component.ts @@ -147,6 +147,7 @@ export class FileAttributeComponent extends BaseFormComponent implements OnDestr handleClick($event: MouseEvent) { $event.stopPropagation(); + $event.preventDefault(); } ngOnDestroy() { @@ -154,6 +155,7 @@ export class FileAttributeComponent extends BaseFormComponent implements OnDestr } handleFieldClick($event: MouseEvent) { + $event.preventDefault(); if (!this.fileNameColumn) { this.editFileAttribute($event); } diff --git a/libs/common-ui b/libs/common-ui index ba85260cc..f36b1fa8e 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit ba85260cc4a3e780a37b3f41be26b83d045a1dcb +Subproject commit f36b1fa8e276c83fe1edaef1e453a37a41b58b79 From 767e688d3c575799987077ba4f4009288658b032 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Wed, 16 Oct 2024 17:40:45 +0300 Subject: [PATCH 087/125] RED-9944 - cancel the bulk-selection mode when a user clicks somewhere else --- .../file-workload/file-workload.component.ts | 12 ++++++++++++ .../file-preview/file-preview-screen.component.ts | 11 +++++++++++ 2 files changed, 23 insertions(+) diff --git a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts index 788204e00..ec3b87e49 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts @@ -588,4 +588,16 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On this.displayedPages.every((value, index) => value === newDisplayedPages[index]) ); } + + @HostListener('click', ['$event']) + clickInsideWorkloadView($event: MouseEvent) { + $event?.stopPropagation(); + } + + @HostListener('document: click') + clickOutsideWorkloadView() { + if (this.multiSelectService.active()) { + this.multiSelectService.deactivate(); + } + } } diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts index 512f783bd..b3c28bfaf 100644 --- a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts @@ -253,6 +253,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni ngOnDestroy() { this.pdf.instance.UI.hotkeys.off('esc'); + this.pdf.instance.UI.iframeWindow.document.removeEventListener('click', this.handleViewerClick); super.ngOnDestroy(); } @@ -277,6 +278,15 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni } } + @Bind() + handleViewerClick() { + this._ngZone.run(() => { + if (this._multiSelectService.active()) { + this._multiSelectService.deactivate(); + } + }); + } + async ngOnAttach(previousRoute: ActivatedRouteSnapshot) { if (!this.state.file().canBeOpened) { return this.#navigateToDossier(); @@ -307,6 +317,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this.#restoreOldFilters(); this.pdf.instance.UI.hotkeys.on('esc', this.handleEscInsideViewer); this._viewerHeaderService.resetLayers(); + this.pdf.instance.UI.iframeWindow.document.addEventListener('click', this.handleViewerClick); } async openRectangleAnnotationDialog(manualRedactionEntryWrapper: ManualRedactionEntryWrapper) { From 6dbe3653629dceb78a520458291fdf64b3c6b8be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Wed, 16 Oct 2024 21:37:30 +0300 Subject: [PATCH 088/125] Localazy manual sync --- apps/red-ui/src/assets/i18n/redact/de.json | 219 +++++++---------- apps/red-ui/src/assets/i18n/redact/en.json | 8 +- apps/red-ui/src/assets/i18n/scm/de.json | 273 +++++++++------------ 3 files changed, 207 insertions(+), 293 deletions(-) diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index 52216ce23..4920caf6d 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -112,6 +112,9 @@ } }, "add-edit-dossier-attribute": { + "error": { + "generic": "Speichern des Attributs fehlgeschlagen." + }, "form": { "label": "Name des Attributs", "label-placeholder": "Namen eingeben", @@ -135,9 +138,6 @@ }, "add-edit-entity": { "form": { - "ai-creation-enabled": "AI Erzeugung aktivieren", - "ai-description": "AI Beschreibung", - "ai-description-placeholder": "AI Beschreibung eingeben", "case-sensitive": "Groß-/Kleinschreibung beachten", "color": "Farbe {type, select, redaction{Schwärzung} hint{Hinweis} recommendation{Empfehlung} skipped{Ingorierte Schwärzung} ignored{Ignorierter Hinweis} other{}}", "color-placeholder": "#", @@ -244,7 +244,7 @@ }, "type": "Typ", "type-placeholder": "Typ auswählen...", - "value": "" + "value": "Wert" }, "title": "Hinweis hinzufügen" } @@ -276,6 +276,9 @@ "watermarks": "Wasserzeichen" }, "analysis-disabled": "", + "annotation": { + "pending": "(Analyse steht aus)" + }, "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" @@ -331,14 +334,14 @@ "error": "Rekategorisierung des Bilds fehlgeschlagen: {error}", "success": "Bild wurde einer neuen Kategorie zugeordnet." }, - "remove-hint": { - "error": "Entfernen des Hinweises fehlgeschlagen: {error}", - "success": "Hinweis wurde entfernt" - }, "remove": { "error": "Entfernen der Schwärzung fehlgeschlagen: {error}", "success": "Schwärzung wurde entfernt" }, + "remove-hint": { + "error": "Entfernen des Hinweises fehlgeschlagen: {error}", + "success": "Hinweis wurde entfernt" + }, "undo": { "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", "success": "Rücksetzung erfolgreich" @@ -351,15 +354,15 @@ "remove-highlights": { "label": "Ausgewählte Markierungen entfernen" }, + "resize": { + "label": "Größe ändern" + }, "resize-accept": { "label": "Neue Größe speichern" }, "resize-cancel": { "label": "Größenänderung abbrechen" }, - "resize": { - "label": "Größe ändern" - }, "see-references": { "label": "Referenzen anzeigen" }, @@ -376,7 +379,7 @@ "removed-manual": "Schwärzung/Hinweis wurde entfernt", "resized": "Schwärzungsbereich wurde geändert" }, - "annotation-content": "{hasRule, select, true {Regel {matchedRule} trifft zu auf{ruleSymbol}} other {}} {hasReason, select, true {{reason}} other {}} {hasLb, select, true {Rechstgrundlage: {legalBasis}} other {}} {hasOverride, select, true {Entfernt durch manuelles Überschreiben} other {}} {hasSection, select, true {{shouldLower, plural, =0 {I} other {i}}n Abschnitt{sectionSymbol} \"{section}\"} other {}}", + "annotation-content": "{hasRule, select, true {Rule {matchedRule} trifft zu:{ruleSymbol}} other {}} {hasReason, select, true {{reason}} other {}} {hasLb, select, true {Legal basis: {legalBasis}} other {}} {hasOverride, select, true {Removed by manual override} other {}} {hasSection, select, true {{shouldLower, plural, =0 {I} other {i}}n Abschnitt{sectionSymbol} \"{section}\"} other {}}", "annotation-engines": { "dictionary": "Basiert auf Wörterbuch", "dossier-dictionary": "Basiert auf Dossier-Wörterbuch", @@ -394,9 +397,6 @@ "skipped": "Ignorierte Schwärzung", "text-highlight": "Markierung" }, - "annotation": { - "pending": "(Analyse steht aus)" - }, "annotations": "Annotationen", "archived-dossiers-listing": { "no-data": { @@ -1020,13 +1020,13 @@ "recent": "Neu ({hours} h)", "unassigned": "Keinem Bearbeiter zugewiesen" }, + "reanalyse": { + "action": "Datei analysieren" + }, "reanalyse-dossier": { "error": "Einplanung der Dateien für die Reanalyse fehlgeschlagen. Bitte versuchen Sie es noch einmal.", "success": "Dateien für Reanalyse vorgesehen." }, - "reanalyse": { - "action": "Datei analysieren" - }, "report-download": "", "start-auto-analysis": "Auto-Analyse aktivieren", "stop-auto-analysis": "Auto-Analyse anhalten", @@ -1096,6 +1096,14 @@ "total-documents": "Dokumente", "total-people": "{count} {count, plural, one{Benutzer} other {Benutzer}}" }, + "dossier-templates": { + "label": "Dossier-Vorlagen", + "status": { + "active": "Aktiv", + "inactive": "Inaktiv", + "incomplete": "Unvollständig" + } + }, "dossier-templates-listing": { "action": { "clone": "Vorlage klonen", @@ -1130,14 +1138,6 @@ "title": "{length} {length, plural, one{Dossier-Vorlage} other{Dossier-Vorlagen}}" } }, - "dossier-templates": { - "label": "Dossier-Vorlagen", - "status": { - "active": "Aktiv", - "inactive": "Inaktiv", - "incomplete": "Unvollständig" - } - }, "dossier-watermark-selector": { "heading": "Wasserzeichen auf Dokumenten", "no-watermark": "Kein Wasserzeichen in der Dossier-Vorlage verfügbar:
Bitten Sie Ihren Admin, eines zu konfigurieren.", @@ -1235,7 +1235,7 @@ "save": "Speichern", "title": "{label} bearbeiten" }, - "entries-count": "", + "entries-count": "{count} {count, plural, one{Eintrag} other{Einträge}}", "false-positives": "Falsch-Positive", "false-recommendations": "Falsche Empfehlungen", "to-redact": "Schwärzungen" @@ -1273,25 +1273,6 @@ }, "side-nav-title": "Konfiguration" }, - "edit-rectangle": { - "dialog": { - "content": { - "options": { - "multiple-pages": { - "description": "", - "extraOptionDescription": "", - "extraOptionLabel": "", - "extraOptionPlaceholder": "", - "label": "" - }, - "only-this-page": { - "description": "", - "label": "" - } - } - } - } - }, "edit-redaction": { "dialog": { "actions": { @@ -1348,6 +1329,15 @@ "title": "{length} {length, plural, one{Wörterbuch} other{Wörterbücher}}" } }, + "entity": { + "info": { + "actions": { + "revert": "Zurücksetzen", + "save": "Änderungen speichern" + }, + "heading": "Entität bearbeiten" + } + }, "entity-rules-screen": { "error": { "generic": "Fehler: Aktualisierung der Entitätsregeln fehlgeschlagen." @@ -1361,28 +1351,19 @@ "title": "Entitätsregeln-Editor", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} in Regeln gefunden" }, - "entity": { - "info": { - "actions": { - "revert": "Zurücksetzen", - "save": "Änderungen speichern" - }, - "heading": "Entität bearbeiten" - } - }, "error": { "deleted-entity": { "dossier": { "action": "Zurück zur Übersicht", "label": "Dieses Dossier wurde gelöscht!" }, - "file-dossier": { - "action": "Zurück zur Übersicht", - "label": "Das Dossier dieser Datei wurde gelöscht!" - }, "file": { "action": "Zurück zum Dossier", "label": "Diese Datei wurde gelöscht!" + }, + "file-dossier": { + "action": "Zurück zur Übersicht", + "label": "Das Dossier dieser Datei wurde gelöscht!" } }, "file-preview": { @@ -1400,6 +1381,12 @@ }, "exact-date": "{day}. {month} {year} um {hour}:{minute} Uhr", "file": "Datei", + "file-attribute": { + "update": { + "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", + "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." + } + }, "file-attribute-encoding-types": { "ascii": "ASCII", "iso": "ISO-8859-1", @@ -1410,12 +1397,6 @@ "number": "Nummer", "text": "Freier Text" }, - "file-attribute": { - "update": { - "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", - "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." - } - }, "file-attributes-configurations": { "cancel": "Abbrechen", "form": { @@ -1633,15 +1614,6 @@ "csv": "Die Datei-Attribute wurden erfolgreich aus der hochgeladenen CSV-Datei importiert." } }, - "filter-menu": { - "filter-options": "Filteroptionen", - "filter-types": "Filter", - "label": "Filter", - "pages-without-annotations": "Nur Seiten ohne Annotationen", - "redaction-changes": "Nur Annotationen mit lokalen manuellen Änderungen", - "unseen-pages": "Nur Annotationen auf ungesehenen Seiten", - "with-comments": "Nur Annotationen mit Kommentaren" - }, "filter": { "analysis": "Analyse erforderlich", "comment": "Kommentare", @@ -1651,6 +1623,15 @@ "redaction": "Schwärzung", "updated": "Aktualisiert" }, + "filter-menu": { + "filter-options": "Filteroptionen", + "filter-types": "Filter", + "label": "Filter", + "pages-without-annotations": "Nur Seiten ohne Annotationen", + "redaction-changes": "Nur Annotationen mit lokalen manuellen Änderungen", + "unseen-pages": "Nur Annotationen auf ungesehenen Seiten", + "with-comments": "Nur Annotationen mit Kommentaren" + }, "filters": { "assigned-people": "Bearbeiter", "documents-status": "Dokumentenstatus", @@ -1884,25 +1865,20 @@ "save": "Speichern" }, "content": { + "apply-on-multiple-pages": "Auf mehreren Seiten anwenden", + "apply-on-multiple-pages-hint": "Minus (-) für Bereich und Komma (,) für Aufzählung.", + "apply-on-multiple-pages-placeholder": "z. B. 1-20,22,32", "classification": "Wert / Klassifizierung", "comment": "Kommentar", + "dictionary": "Wörterbuch", + "edit-selected-text": "Ausgewählten Text bearbeiten", "legalBasis": "Rechtsgrundlage", - "options": { - "multiple-pages": { - "description": "", - "extraOptionDescription": "", - "extraOptionLabel": "", - "extraOptionPlaceholder": "", - "label": "" - }, - "only-this-page": { - "description": "", - "label": "" - } - }, "reason": "Grund", "reason-placeholder": "Grund auswählen...", - "section": "Absatz / Textstelle" + "rectangle": "Bereich schwärzen", + "section": "Absatz / Textstelle", + "text": "Ausgewählter Text:", + "type": "Entität" }, "error": "Fehler: Ungültige Seitenauswahl", "header": { @@ -1934,6 +1910,13 @@ "user-promoted-to-approver": "{user} wurde im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} zum Genehmiger ernannt!", "user-removed-as-dossier-member": "{user} wurde als Mitglied von: {dossierHref, select, null{{dossierName}} other{{dossierName}}} entfernt!" }, + "notifications": { + "button-text": "Benachrichtigungen", + "deleted-dossier": "Gelöschtes Dossier", + "label": "Benachrichtigungen", + "mark-all-as-read": "Alle als gelesen markieren", + "mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren" + }, "notifications-screen": { "category": { "email-notifications": "E-Mail-Benachrichtigungen", @@ -1947,7 +1930,6 @@ "dossier": "Benachrichtigungen zu Dossiers", "other": "Andere Benachrichtigungen" }, - "options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten", "options": { "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen werde", "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Prüfer zugewiesen werde", @@ -1965,6 +1947,7 @@ "USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde", "USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere" }, + "options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten", "schedule": { "daily": "Tägliche Zusammenfassung", "instant": "Sofort", @@ -1972,13 +1955,6 @@ }, "title": "Benachrichtigungseinstellungen" }, - "notifications": { - "button-text": "Benachrichtigungen", - "deleted-dossier": "Gelöschtes Dossier", - "label": "Benachrichtigungen", - "mark-all-as-read": "Alle als gelesen markieren", - "mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren" - }, "ocr": { "confirmation-dialog": { "cancel": "Abbrechen", @@ -2032,19 +2008,19 @@ "left-panel-button": "Panel", "load-all-annotations": "Alle Annotationen laden", "no-outlines-text": "Keine Gliederung verfügbar", - "no-signatures-text": "In diesem Dokument gibt es keine Unterschriftenfelder", + "no-signatures-text": "Dieses Dokument enthält keine Unterschriftenfelder.", "outline-multi-select": "Bearbeiten", "outlines-panel-button": "Gliederung", "pan-tool-button": "Verschieben", - "rectangle-tool-button": "Bereichsschwärzung", + "rectangle-tool-button": "Bereich schwärzen", "rotate-left-button": "Seite nach links drehen", "rotate-right-button": "Seite nach rechts drehen", "select-tool-button": "Auswählen", "signature-panel-button": "Unterschriften", "thumbnails-panel-button": "Miniaturansicht", "toggle-layers": "Layout-Raster {active, select, true{deaktivieren} false{aktivieren} other{}}", - "toggle-readable-redactions": "Schwärzungen {active, select, true{wie im finalen Dokument} false{in Vorschau-Farbe} other{}} anzeigen", - "toggle-tooltips": "Tooltips zu Annotationen {active, select, true{deaktivieren} false{aktivieren} other{}}", + "toggle-readable-redactions": "Schwärzungen {active, select, true{wie im finalen Dokument} false{in Preview-Farbe anzeigen} other{}}", + "toggle-tooltips": "Tooltips für Annotationen {active, select, true{deaktivieren} false{aktivieren} other{}}", "zoom-in-button": "Vergrößern", "zoom-out-button": "Verkleinern" }, @@ -2090,16 +2066,16 @@ "warnings-label": "Dialoge und Meldungen", "warnings-subtitle": "„Nicht mehr anzeigen“-Optionen" }, + "processing": { + "basic": "Verarbeitung läuft", + "ocr": "OCR" + }, "processing-status": { "ocr": "OCR", "pending": "Ausstehend", "processed": "Verarbeitet", "processing": "Verarbeitung läuft" }, - "processing": { - "basic": "Verarbeitung läuft", - "ocr": "OCR" - }, "readonly": "Lesemodus", "readonly-archived": "Lesemodus (archiviert)", "redact-text": { @@ -2179,25 +2155,6 @@ "title": "{count, plural, one{Annotation} other {Annotationen}} entfernen" } }, - "remove-rectangle": { - "dialog": { - "content": { - "options": { - "multiple-pages": { - "description": "", - "extraOptionDescription": "", - "extraOptionLabel": "", - "extraOptionPlaceholder": "", - "label": "" - }, - "only-this-page": { - "description": "", - "label": "" - } - } - } - } - }, "remove-redaction": { "dialog": { "actions": { @@ -2217,7 +2174,7 @@ "false-positive": { "description": "Markieren Sie die Schwärzung als falsch-positiv. Der Begriff wird in diesem Dossier nicht geschwärzt, wenn er im gleichen Kontext vorkommt.", "description-bulk": "Markieren Sie die Schwärzungen als falsch-positiv. Die Begriffe werden in diesem Dossier nicht geschwärzt, wenn sie im gleichen Kontext vorkommen.", - "extraOptionDescription": "Um diese Aktion rückgängig machen zu können, benötigen Sie Zugriff auf die Dossier-Vorlage. Als regulärer Benutzer können sie die Aktion nur für dieses Dossier rückgängig machen.", + "extraOptionDescription": "Um diese Aktion rückgängig machen zu können, benötigen Sie Zugriff auf die Dossier-Vorlage. Als regulärer Benutzer können Sie die Aktion nur für dieses Dossier rückgängig machen.", "extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen", "label": "In diesem Kontext aus Dossier entfernen" }, @@ -2367,6 +2324,12 @@ "red-user-admin": "Benutzeradmin", "regular": "regulärer Benutzer" }, + "search": { + "active-dossiers": "Dokumente in aktiven Dossiers", + "all-dossiers": "Alle Dokumente", + "placeholder": "Dokumente durchsuchen...", + "this-dossier": "In diesem Dossier" + }, "search-screen": { "cols": { "assignee": "Bearbeiter", @@ -2390,12 +2353,6 @@ "no-match": "Der Suchbegriff wurde in keinem der Dokumente gefunden.", "table-header": "{length} {length, plural, one{Suchergebnis} other{Suchergebnisse}}" }, - "search": { - "active-dossiers": "Dokumente in aktiven Dossiers", - "all-dossiers": "Alle Dokumente", - "placeholder": "Dokumente durchsuchen...", - "this-dossier": "In diesem Dossier" - }, "seconds": "Sekunden", "size": "Größe", "smtp-auth-config": { @@ -2617,7 +2574,7 @@ }, "pagination": { "landscape": "Querformat", - "portrait": "Hoch-" + "portrait": "Hochformat" } }, "watermarks-listing": { diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index 2bb0e6013..ae574fc2d 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -1304,12 +1304,12 @@ "legal-basis": "Legal basis", "options": { "in-document": { - "description": "Edit redaction of all linked occurrences of the term in this document.", + "description": "Edit redaction of all instances of the term in this document.", "label": "Change in document" }, "only-here": { "description": "Edit redaction only at this position in this document.", - "label": "Change type only here" + "label": "Change only here" } }, "reason": "Reason", @@ -2115,7 +2115,7 @@ "legal-basis": "Legal basis", "options": { "in-document": { - "description": "Add redaction for each occurrence of the term in this document.", + "description": "Add redaction for each instance of the term in this document.", "label": "Redact in document" }, "in-dossier": { @@ -2222,7 +2222,7 @@ "label": "Remove from dossier in this context" }, "in-document": { - "description": "Do not auto-redact the selected {isImage, select, image{image} other{term}} in any pages of this document.", + "description": "Do not auto-redact the selected {isImage, select, image{image} other{term}} on any page of this document.", "label": "Remove from document" }, "in-dossier": { diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 08266540c..d6f0fb6b0 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -112,6 +112,9 @@ } }, "add-edit-dossier-attribute": { + "error": { + "generic": "Speichern des Attributs fehlgeschlagen." + }, "form": { "label": "Name des Attributs", "label-placeholder": "Namen eingeben", @@ -135,9 +138,6 @@ }, "add-edit-entity": { "form": { - "ai-creation-enabled": "AI Erzeugung aktivieren", - "ai-description": "AI Beschreibung", - "ai-description-placeholder": "AI Beschreibung eingeben", "case-sensitive": "Groß-/Kleinschreibung beachten", "color": "Farbe {type, select, redaction{Annotation} hint{Hinweis} recommendation{Empfehlung} skipped{Übersprungene Annotation} ignored{Ignorierter Hinweis} other{}}", "color-placeholder": "#", @@ -244,7 +244,7 @@ }, "type": "Typ", "type-placeholder": "Typ auswählen...", - "value": "" + "value": "Value" }, "title": "Hinweis hinzufügen" } @@ -276,6 +276,9 @@ "watermarks": "Wasserzeichen" }, "analysis-disabled": "Analyse deaktiviert", + "annotation": { + "pending": "(Analyse steht aus)" + }, "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" @@ -331,14 +334,14 @@ "error": "Rekategorisierung des Bilds fehlgeschlagen: {error}", "success": "Bild wurde einer neuen Kategorie zugeordnet." }, - "remove-hint": { - "error": "Entfernen des Hinweises fehlgeschlagen: {error}", - "success": "Hinweis wurde entfernt" - }, "remove": { "error": "Entfernen der Annotation fehlgeschlagen: {error}", "success": "Annotation wurde entfernt" }, + "remove-hint": { + "error": "Entfernen des Hinweises fehlgeschlagen: {error}", + "success": "Hinweis wurde entfernt" + }, "undo": { "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", "success": "erfolgreich Rückgängig gemacht" @@ -351,15 +354,15 @@ "remove-highlights": { "label": "Ausgewählte Markierungen entfernen" }, + "resize": { + "label": "Größe ändern" + }, "resize-accept": { "label": "Neue Größe speichern" }, "resize-cancel": { "label": "Größenänderung abbrechen" }, - "resize": { - "label": "Größe ändern" - }, "see-references": { "label": "See references" }, @@ -376,7 +379,7 @@ "removed-manual": "Schwärzung/Hinweis entfernt", "resized": "Schwärzungsbereich wurde geändert" }, - "annotation-content": "{hasRule, select, true {Regel {matchedRule} trifft zu auf{ruleSymbol}} other {}} {hasReason, select, true {{reason}} other {}} {hasLb, select, true {Rechstgrundlage: {legalBasis}} other {}} {hasOverride, select, true {Entfernt durch manuelles Überschreiben} other {}} {hasSection, select, true {{shouldLower, plural, =0 {I} other {i}}n Abschnitt{sectionSymbol} \"{section}\"} other {}}", + "annotation-content": "{hasRule, select, true {Rule {matchedRule} matched{ruleSymbol}} other {}} {hasReason, select, true {{reason}} other {}} {hasLb, select, true {Legal basis: {legalBasis}} other {}} {hasOverride, select, true {Removed by manual override} other {}} {hasSection, select, true {{shouldLower, plural, =0 {I} other {i}}n section{sectionSymbol} \"{section}\"} other {}}", "annotation-engines": { "dictionary": "{isHint, select, true{Hinweis} other{Schwärzung}} basiert auf Wörterbuch", "dossier-dictionary": "Annotation basiert auf Dossier-Wörterbuch", @@ -394,9 +397,6 @@ "skipped": "Übersprungen", "text-highlight": "Markierung" }, - "annotation": { - "pending": "(Analyse steht aus)" - }, "annotations": "Annotationen", "archived-dossiers-listing": { "no-data": { @@ -1020,13 +1020,13 @@ "recent": "Neu ({hours} h)", "unassigned": "Niemandem zugewiesen" }, + "reanalyse": { + "action": "Datei analysieren" + }, "reanalyse-dossier": { "error": "Die Dateien konnten nicht für eine Reanalyse eingeplant werden. Bitte versuchen Sie es erneut.", "success": "Dateien für Reanalyse vorgesehen." }, - "reanalyse": { - "action": "Datei analysieren" - }, "report-download": "Report download", "start-auto-analysis": "Enable auto-analysis", "stop-auto-analysis": "Stop auto-analysis", @@ -1096,6 +1096,14 @@ "total-documents": "Anzahl der Dokumente", "total-people": "{count} {count, plural, one{user} other {users}}" }, + "dossier-templates": { + "label": "Dossier-Vorlagen", + "status": { + "active": "Active", + "inactive": "Inactive", + "incomplete": "Incomplete" + } + }, "dossier-templates-listing": { "action": { "clone": "Clone template", @@ -1130,14 +1138,6 @@ "title": "{length} dossier {length, plural, one{template} other{templates}}" } }, - "dossier-templates": { - "label": "Dossier-Vorlagen", - "status": { - "active": "Active", - "inactive": "Inactive", - "incomplete": "Incomplete" - } - }, "dossier-watermark-selector": { "heading": "Watermarks on documents", "no-watermark": "There is no watermark defined for the dossier template.
Contact your app admin to define one.", @@ -1235,7 +1235,7 @@ "save": "", "title": "" }, - "entries-count": "", + "entries-count": "{count} {count, plural, one{entry} other{entries}}", "false-positives": "False positives", "false-recommendations": "False recommendations", "to-redact": "To redact" @@ -1273,25 +1273,6 @@ }, "side-nav-title": "Konfiguration" }, - "edit-rectangle": { - "dialog": { - "content": { - "options": { - "multiple-pages": { - "description": "", - "extraOptionDescription": "", - "extraOptionLabel": "", - "extraOptionPlaceholder": "", - "label": "" - }, - "only-this-page": { - "description": "", - "label": "" - } - } - } - } - }, "edit-redaction": { "dialog": { "actions": { @@ -1348,6 +1329,15 @@ "title": "{length} {length, plural, one{entity} other{entities}}" } }, + "entity": { + "info": { + "actions": { + "revert": "Revert", + "save": "Save changes" + }, + "heading": "Edit entity" + } + }, "entity-rules-screen": { "error": { "generic": "Something went wrong... Entity rules update failed!" @@ -1361,28 +1351,19 @@ "title": "Entity rule editor", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} found in rules" }, - "entity": { - "info": { - "actions": { - "revert": "Revert", - "save": "Save changes" - }, - "heading": "Edit entity" - } - }, "error": { "deleted-entity": { "dossier": { "action": "Zurück zur Übersicht", "label": "Dieses Dossier wurde gelöscht!" }, - "file-dossier": { - "action": "Zurück zur Übersicht", - "label": "Das Dossier dieser Datei wurde gelöscht!" - }, "file": { "action": "Zurück zum Dossier", "label": "Diese Datei wurde gelöscht!" + }, + "file-dossier": { + "action": "Zurück zur Übersicht", + "label": "Das Dossier dieser Datei wurde gelöscht!" } }, "file-preview": { @@ -1400,6 +1381,12 @@ }, "exact-date": "{day} {month} {year} um {hour}:{minute} Uhr", "file": "Datei", + "file-attribute": { + "update": { + "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", + "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." + } + }, "file-attribute-encoding-types": { "ascii": "ASCII", "iso": "ISO-8859-1", @@ -1410,12 +1397,6 @@ "number": "Nummer", "text": "Freier Text" }, - "file-attribute": { - "update": { - "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", - "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." - } - }, "file-attributes-configurations": { "cancel": "Abbrechen", "form": { @@ -1633,15 +1614,6 @@ "csv": "Die Datei-Attribute wurden erfolgreich aus der hochgeladenen CSV-Datei importiert." } }, - "filter-menu": { - "filter-options": "Filteroptionen", - "filter-types": "Filter", - "label": "Filter", - "pages-without-annotations": "Nur Seiten ohne Annotationen", - "redaction-changes": "Nur Annotationen mit lokalen manuellen Änderungen", - "unseen-pages": "Nur Anmerkungen auf ungesehenen Seiten", - "with-comments": "Nur Anmerkungen mit Kommentaren" - }, "filter": { "analysis": "Analyse erforderlich", "comment": "Kommentare", @@ -1651,6 +1623,15 @@ "redaction": "Annotationen", "updated": "Aktualisiert" }, + "filter-menu": { + "filter-options": "Filteroptionen", + "filter-types": "Filter", + "label": "Filter", + "pages-without-annotations": "Nur Seiten ohne Annotationen", + "redaction-changes": "Nur Annotationen mit lokalen manuellen Änderungen", + "unseen-pages": "Nur Anmerkungen auf ungesehenen Seiten", + "with-comments": "Nur Anmerkungen mit Kommentaren" + }, "filters": { "assigned-people": "Bearbeiter", "documents-status": "Dokumentenstatus", @@ -1737,16 +1718,16 @@ "cancel": "Abbrechen" }, "convert": { - "confirmation": "The {count} selected {count, plural, one{earmark} other{earmarks}} will be converted", - "details": "All earmarks from the document will be converted to Imported Annotations, using the color set up in the Default Colors section of the app.", + "confirmation": "{count} ausgewählte {count, plural, one{Markierung wird} other{Markierungen werden}} konvertiert", + "details": "Alle Markierungen im Dokument werden in importierte Schwärzungen konvertiert. Importierte Schwärzungen werden in der Farbe hervorgehoben, die der Admin im Bereich „Standardfarben“ konfiguriert hat.", "options": { "all-pages": { - "description": "The earmarks in the selected HEX color will be converted on all pages of the document.", - "label": "Convert on all pages" + "description": "Die Markierungen in der ausgewählten HEX-Farbe werden auf allen Seiten des Dokuments konvertiert.", + "label": "Auf allen Seiten konvertieren" }, "this-page": { - "description": "The earmarks in the selected HEX color will be converted only on the current page in view.", - "label": "Convert only on this page" + "description": "Die Markierungen in der ausgewählten HEX-Farbe werden nur auf der aktuell angezeigten Seite konvertiert.", + "label": "Nur auf dieser Seite konvertieren" } }, "save": "Convert earmarks", @@ -1884,25 +1865,20 @@ "save": "Speichern" }, "content": { + "apply-on-multiple-pages": "Apply on multiple pages", + "apply-on-multiple-pages-hint": "Minus(-) for range and comma(,) for enumeration.", + "apply-on-multiple-pages-placeholder": "e.g. 1-20,22,32", "classification": "Wert / Klassifizierung", "comment": "Kommentar", + "dictionary": "Wörterbuch", + "edit-selected-text": "Edit selected text", "legalBasis": "Rechtsgrundlage", - "options": { - "multiple-pages": { - "description": "", - "extraOptionDescription": "", - "extraOptionLabel": "", - "extraOptionPlaceholder": "", - "label": "" - }, - "only-this-page": { - "description": "", - "label": "" - } - }, "reason": "Begründung", "reason-placeholder": "Wählen Sie eine Begründung aus ...", - "section": "Absatz / Ort" + "rectangle": "Benutzerdefinierter Bereich", + "section": "Absatz / Ort", + "text": "Ausgewählter Text:", + "type": "Entity" }, "error": "Error! Invalid page selection", "header": { @@ -1934,6 +1910,13 @@ "user-promoted-to-approver": "{user} wurde im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} zum Genehmiger ernannt!", "user-removed-as-dossier-member": "{user} wurde als Mitglied von: {dossierHref, select, null{{dossierName}} other{{dossierName}}} entfernt!" }, + "notifications": { + "button-text": "Notifications", + "deleted-dossier": "Deleted dossier", + "label": "Benachrichtigungen", + "mark-all-as-read": "Alle als gelesen markieren", + "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}" + }, "notifications-screen": { "category": { "email-notifications": "E-Mail Benachrichtigungen", @@ -1947,7 +1930,6 @@ "dossier": "Dossierbezogene Benachrichtigungen", "other": "Andere Benachrichtigungen" }, - "options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten", "options": { "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen bin", "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Überprüfer zugewiesen bin", @@ -1965,6 +1947,7 @@ "USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde", "USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere" }, + "options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten", "schedule": { "daily": "Tägliche Zusammenfassung", "instant": "Sofortig", @@ -1972,13 +1955,6 @@ }, "title": "Benachrichtigungseinstellungen" }, - "notifications": { - "button-text": "Notifications", - "deleted-dossier": "Deleted dossier", - "label": "Benachrichtigungen", - "mark-all-as-read": "Alle als gelesen markieren", - "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}" - }, "ocr": { "confirmation-dialog": { "cancel": "Cancel", @@ -2026,27 +2002,27 @@ }, "pdf-viewer": { "header": { - "all-annotations-loaded": "Alle Annotationen geladen", - "compare-button": "Vergleichen", - "layers-panel-button": "Ebenen", + "all-annotations-loaded": "All annotations loaded", + "compare-button": "Compare", + "layers-panel-button": "Layers", "left-panel-button": "Panel", - "load-all-annotations": "Alle Annotationen laden", - "no-outlines-text": "Keine Gliederung verfügbar", - "no-signatures-text": "In diesem Dokument gibt es keine Unterschriftenfelder", - "outline-multi-select": "Bearbeiten", - "outlines-panel-button": "Gliederung", - "pan-tool-button": "Verschieben", - "rectangle-tool-button": "Bereichsschwärzung", - "rotate-left-button": "Seite nach links drehen", - "rotate-right-button": "Seite nach rechts drehen", - "select-tool-button": "Auswählen", - "signature-panel-button": "Unterschriften", - "thumbnails-panel-button": "Miniaturansicht", - "toggle-layers": "Layout-Raster {active, select, true{deaktivieren} false{aktivieren} other{}}", - "toggle-readable-redactions": "Schwärzungen {active, select, true{wie im finalen Dokument} false{in Vorschau-Farbe} other{}} anzeigen", - "toggle-tooltips": "Tooltips zu Annotationen {active, select, true{deaktivieren} false{aktivieren} other{}}", - "zoom-in-button": "Vergrößern", - "zoom-out-button": "Verkleinern" + "load-all-annotations": "Load all annotations", + "no-outlines-text": "No outlines available", + "no-signatures-text": "This document has NO signature fields", + "outline-multi-select": "Edit", + "outlines-panel-button": "Outlines", + "pan-tool-button": "Pan", + "rectangle-tool-button": "Rectangle", + "rotate-left-button": "Rotate page left", + "rotate-right-button": "Rotate page right", + "select-tool-button": "Select", + "signature-panel-button": "Signatures", + "thumbnails-panel-button": "Thumbnails", + "toggle-layers": "{active, select, true{Disable} false{Enable} other{}} layout grid", + "toggle-readable-redactions": "Show redactions {active, select, true{as in final document} false{in preview color} other{}}", + "toggle-tooltips": "{active, select, true{Disable} false{Enable} other{}} annotation tooltips", + "zoom-in-button": "Zoom In", + "zoom-out-button": "Zoom Out" }, "text-popup": { "actions": { @@ -2090,16 +2066,16 @@ "warnings-label": "Prompts and dialogs", "warnings-subtitle": "Do not show again options" }, + "processing": { + "basic": "Processing", + "ocr": "OCR" + }, "processing-status": { "ocr": "OCR", "pending": "Pending", "processed": "Processed", "processing": "Processing" }, - "processing": { - "basic": "Processing", - "ocr": "OCR" - }, "readonly": "Lesemodus", "readonly-archived": "Read only (archived)", "redact-text": { @@ -2115,8 +2091,8 @@ "legal-basis": "Legal basis", "options": { "in-document": { - "description": "Fügen Sie die Schwärzung an allen Stellen in diesem Dokument hinzu.", - "label": "Im Dokument schwärzen" + "description": "Add redaction for each occurrence of the term in this document.", + "label": "Redact in document" }, "in-dossier": { "description": "Add redaction in every document in {dossierName}.", @@ -2134,7 +2110,7 @@ "type": "Type", "type-placeholder": "Select type...", "unchanged": "", - "value": "Wert" + "value": "Value" }, "title": "Redact text" } @@ -2179,25 +2155,6 @@ "title": "Remove {count, plural, one{annotation} other {annotations}}" } }, - "remove-rectangle": { - "dialog": { - "content": { - "options": { - "multiple-pages": { - "description": "", - "extraOptionDescription": "", - "extraOptionLabel": "", - "extraOptionPlaceholder": "", - "label": "" - }, - "only-this-page": { - "description": "", - "label": "" - } - } - } - } - }, "remove-redaction": { "dialog": { "actions": { @@ -2222,8 +2179,8 @@ "label": "False positive" }, "in-document": { - "description": "{isImage, select, image{Das Bild} other{der Begriff}} wird auf keiner Seite dieses Dokuments automatisch geschwärzt.", - "label": "Aus Dokument entfernen" + "description": "", + "label": "" }, "in-dossier": { "description": "Do not {type} \"{value}\" in any document of the current dossier.", @@ -2367,6 +2324,12 @@ "red-user-admin": "Benutzer-Admin", "regular": "Regulär" }, + "search": { + "active-dossiers": "ganze Plattform", + "all-dossiers": "all documents", + "placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen", + "this-dossier": "in diesem Dossier" + }, "search-screen": { "cols": { "assignee": "Bevollmächtigter", @@ -2390,12 +2353,6 @@ "no-match": "Keine Dokumente entsprechen Ihren aktuellen Filtern.", "table-header": "{length} search {length, plural, one{result} other{results}}" }, - "search": { - "active-dossiers": "ganze Plattform", - "all-dossiers": "all documents", - "placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen", - "this-dossier": "in diesem Dossier" - }, "seconds": "seconds", "size": "Size", "smtp-auth-config": { @@ -2616,8 +2573,8 @@ "text-placeholder": "Text eingeben" }, "pagination": { - "landscape": "Querformat", - "portrait": "Hoch-" + "landscape": "", + "portrait": "" } }, "watermarks-listing": { From 68bfcf67001b45aa4a0a56148a447933ab4c7ea1 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Thu, 17 Oct 2024 12:02:23 +0300 Subject: [PATCH 089/125] RED-8277: fix redirect when intending to open primary file attribute. --- .../components/file-attribute/file-attribute.component.ts | 1 + libs/common-ui | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/red-ui/src/app/modules/dossier-overview/components/file-attribute/file-attribute.component.ts b/apps/red-ui/src/app/modules/dossier-overview/components/file-attribute/file-attribute.component.ts index d131faa9d..4ba803cf1 100644 --- a/apps/red-ui/src/app/modules/dossier-overview/components/file-attribute/file-attribute.component.ts +++ b/apps/red-ui/src/app/modules/dossier-overview/components/file-attribute/file-attribute.component.ts @@ -162,6 +162,7 @@ export class FileAttributeComponent extends BaseFormComponent implements OnDestr } editFileAttribute($event: MouseEvent) { + $event.preventDefault(); if ( !this.file.isInitialProcessing && this.permissionsService.canEditFileAttributes(this.file, this.dossier) && diff --git a/libs/common-ui b/libs/common-ui index f36b1fa8e..e92bd55cf 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit f36b1fa8e276c83fe1edaef1e453a37a41b58b79 +Subproject commit e92bd55cfc37342fec5a246d5cc5226b95fc427e From 876127d1fbe0723241e03b16af08d17f77521f92 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Thu, 17 Oct 2024 14:45:27 +0300 Subject: [PATCH 090/125] RED-9585 - Incorrect capitalization in German translation + missing singular/plural distinction --- .../components/users-stats/users-stats.component.html | 2 +- .../components/users-stats/users-stats.component.ts | 6 +++--- .../red-ui/src/app/services/translate-chart.service.ts | 2 +- apps/red-ui/src/assets/i18n/redact/de.json | 8 ++++---- apps/red-ui/src/assets/i18n/redact/en.json | 10 +++++----- apps/red-ui/src/assets/i18n/scm/de.json | 8 ++++---- apps/red-ui/src/assets/i18n/scm/en.json | 10 +++++----- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/components/users-stats/users-stats.component.html b/apps/red-ui/src/app/modules/admin/components/users-stats/users-stats.component.html index e71a59228..8de639b0a 100644 --- a/apps/red-ui/src/app/modules/admin/components/users-stats/users-stats.component.html +++ b/apps/red-ui/src/app/modules/admin/components/users-stats/users-stats.component.html @@ -23,7 +23,7 @@
(); + readonly toggleCollapse = output(); } diff --git a/apps/red-ui/src/app/services/translate-chart.service.ts b/apps/red-ui/src/app/services/translate-chart.service.ts index 4303c7f26..e55304910 100644 --- a/apps/red-ui/src/app/services/translate-chart.service.ts +++ b/apps/red-ui/src/app/services/translate-chart.service.ts @@ -57,7 +57,7 @@ export class TranslateChartService { translateRoles(config: DonutChartConfig[]): DonutChartConfig[] { return config.map(val => ({ ...val, - label: this._translateService.instant(rolesTranslations[val.label]).toLowerCase(), + label: this._translateService.instant(rolesTranslations[val.label], { length: val.value }), })); } } diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index 4920caf6d..9bbd4fe51 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -2316,13 +2316,13 @@ }, "roles": { "inactive": "Inaktiv", - "manager-admin": "Manager & Admin", + "manager-admin": "Manager & {length, plural, one{Admin} other{Admins}}", "no-role": "Keine Rolle definiert", - "red-admin": "Anwendungsadmin", + "red-admin": "{length, plural, one{Anwendungsadmin} other{Anwendungsadmins}}", "red-manager": "Manager", "red-user": "Benutzer", - "red-user-admin": "Benutzeradmin", - "regular": "regulärer Benutzer" + "red-user-admin": "{length, plural, one{Benutzeradmin} other{Benutzeradmins}}", + "regular": "{length, plural, one{regulärer} other{reguläre}} Benutzer" }, "search": { "active-dossiers": "Dokumente in aktiven Dossiers", diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index ae574fc2d..6588d18b8 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -2359,12 +2359,12 @@ }, "roles": { "inactive": "Inactive", - "manager-admin": "Manager & admin", + "manager-admin": "Manager & {length, plural, one{Admin} other{Admins}}", "no-role": "No role defined", - "red-admin": "Application admin", - "red-manager": "Manager", - "red-user": "User", - "red-user-admin": "Users admin", + "red-admin": "Application {length, plural, one{admin} other{admins}}", + "red-manager": "{length, plural, one{Manager} other{Managers}}", + "red-user": "{length, plural, one{User} other{Users}}", + "red-user-admin": "{length, plural, one{User} other{Users}} admin", "regular": "Regular" }, "search-screen": { diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index d6f0fb6b0..b9a1f8a3b 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -2316,13 +2316,13 @@ }, "roles": { "inactive": "Inaktiv", - "manager-admin": "Manager & admin", + "manager-admin": "Manager & {length, plural, one{Admin} other{Admins}}", "no-role": "Keine Rolle definiert", - "red-admin": "Anwendungsadministrator", + "red-admin": "{length, plural, one{Anwendungsadmin} other{Anwendungsadmins}}", "red-manager": "Manager", "red-user": "Benutzer", - "red-user-admin": "Benutzer-Admin", - "regular": "Regulär" + "red-user-admin": "{length, plural, one{Benutzeradmin} other{Benutzeradmins}}", + "regular": "{length, plural, one{regulärer} other{reguläre}} Benutzer" }, "search": { "active-dossiers": "ganze Plattform", diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index f751bf400..4904c2b96 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -2359,12 +2359,12 @@ }, "roles": { "inactive": "Inactive", - "manager-admin": "Manager & admin", + "manager-admin": "Manager & {length, plural, one{Admin} other{Admins}}", "no-role": "No role defined", - "red-admin": "Application admin", - "red-manager": "Manager", - "red-user": "User", - "red-user-admin": "Users admin", + "red-admin": "Application {length, plural, one{admin} other{admins}}", + "red-manager": "{length, plural, one{Manager} other{Managers}}", + "red-user": "{length, plural, one{User} other{Users}}", + "red-user-admin": "{length, plural, one{User} other{Users}} admin", "regular": "Regular" }, "search-screen": { From 224dafcae63784bed7b91eb7e0f9dcecb677d94f Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Fri, 18 Oct 2024 14:32:06 +0300 Subject: [PATCH 091/125] RED-9944 - Action Items don't appear in document area in webviewer when bulk-select is still unintenionally active --- .../file-preview/file-preview-screen.component.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts index b3c28bfaf..ad3c9c902 100644 --- a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts @@ -279,10 +279,17 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni } @Bind() - handleViewerClick() { + handleViewerClick(event: MouseEvent) { this._ngZone.run(() => { if (this._multiSelectService.active()) { - this._multiSelectService.deactivate(); + const clickedElement = event.target as HTMLElement; + if (clickedElement.querySelector('#selectionrect')) { + if (!this._annotationManager.selected.length) { + this._multiSelectService.deactivate(); + } + } else { + this._multiSelectService.deactivate(); + } } }); } From 7e429320281723220cf8c304f574b2fbd4938a08 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Fri, 18 Oct 2024 17:23:12 +0300 Subject: [PATCH 092/125] RED-3800: manual localazy sync. --- apps/red-ui/src/assets/i18n/redact/de.json | 93 ++-- apps/red-ui/src/assets/i18n/redact/en.json | 10 +- apps/red-ui/src/assets/i18n/scm/de.json | 475 +++++++++++---------- apps/red-ui/src/assets/i18n/scm/en.json | 58 +-- 4 files changed, 361 insertions(+), 275 deletions(-) diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index 9bbd4fe51..87cb57ac4 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -112,9 +112,6 @@ } }, "add-edit-dossier-attribute": { - "error": { - "generic": "Speichern des Attributs fehlgeschlagen." - }, "form": { "label": "Name des Attributs", "label-placeholder": "Namen eingeben", @@ -138,6 +135,9 @@ }, "add-edit-entity": { "form": { + "ai-creation-enabled": "KI-Erstellung aktivieren", + "ai-description": "KI-Beschreibung", + "ai-description-placeholder": "KI-Beschreibung eingeben", "case-sensitive": "Groß-/Kleinschreibung beachten", "color": "Farbe {type, select, redaction{Schwärzung} hint{Hinweis} recommendation{Empfehlung} skipped{Ingorierte Schwärzung} ignored{Ignorierter Hinweis} other{}}", "color-placeholder": "#", @@ -1165,15 +1165,15 @@ "queued": "Ihr Download wurde zur Warteschlange hinzugefügt.

Hier finden Sie Ihre generierten Downloads: Meine Downloads." }, "download-type": { - "annotated": "Annotierte PDF", + "annotated": "Annotiertes PDF", "delta-preview": "Delta-PDF", - "flatten": "Verflachte PDF", + "flatten": "Verflachtes PDF", "label": "{length} Dokumenten{length, plural, one{typ} other{typen}}", - "optimized-preview": "Optimierte Vorschau-PDF", - "original": "Optimierte PDF", + "optimized-preview": "Optimiertes Vorschau-PDF", + "original": "Optimiertes PDF", "preview": "Vorschau-PDF", - "redacted": "Geschwärzte PDF", - "redacted-only": "Geschwärzte PDF (nur freigegebene Dateien)" + "redacted": "Geschwärztes PDF", + "redacted-only": "Geschwärztes PDF (nur freigegebene Dateien)" }, "downloads-list": { "actions": { @@ -1273,6 +1273,25 @@ }, "side-nav-title": "Konfiguration" }, + "edit-rectangle": { + "dialog": { + "content": { + "options": { + "multiple-pages": { + "description": "Schwärzung auf folgenden Seiten bearbeiten", + "extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.", + "extraOptionLabel": "Seitenbereich", + "extraOptionPlaceholder": "z. B. 1-20,22,32", + "label": "Auf allen Seiten ändern" + }, + "only-this-page": { + "description": "Schwärzung nur an dieser Position in diesem Dokument bearbeiten", + "label": "Nur auf dieser Seite ändern" + } + } + } + } + }, "edit-redaction": { "dialog": { "actions": { @@ -1290,7 +1309,7 @@ }, "only-here": { "description": "Bearbeiten Sie die Schwärzung nur an dieser Stelle im Dokument.", - "label": "Typ nur hier ändern" + "label": "Nur hier ändern" } }, "reason": "Grund", @@ -1775,8 +1794,8 @@ }, "import-only-for-pages": "Nur für diese Seiten importieren", "range": { - "label": "Minus (-) für Spanne und Komma (,) für Aufzählung.", - "placeholder": "Beispiel: 1-20,22,32" + "label": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.", + "placeholder": "z. B. 1-20,22,32" }, "title": "Dokument mit Schwärzungen importieren" }, @@ -1865,20 +1884,25 @@ "save": "Speichern" }, "content": { - "apply-on-multiple-pages": "Auf mehreren Seiten anwenden", - "apply-on-multiple-pages-hint": "Minus (-) für Bereich und Komma (,) für Aufzählung.", - "apply-on-multiple-pages-placeholder": "z. B. 1-20,22,32", "classification": "Wert / Klassifizierung", "comment": "Kommentar", - "dictionary": "Wörterbuch", - "edit-selected-text": "Ausgewählten Text bearbeiten", "legalBasis": "Rechtsgrundlage", + "options": { + "multiple-pages": { + "description": "Schwärzung auf folgenden Seiten hinzufügen", + "extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.", + "extraOptionLabel": "Seitenbereich", + "extraOptionPlaceholder": "z. B. 1-20,22,32", + "label": "Auf mehreren Seiten anwenden" + }, + "only-this-page": { + "description": "Schwärzung nur an dieser Position in diesem Dokument hinzufügen", + "label": "Auf dieser Seite anwenden" + } + }, "reason": "Grund", "reason-placeholder": "Grund auswählen...", - "rectangle": "Bereich schwärzen", - "section": "Absatz / Textstelle", - "text": "Ausgewählter Text:", - "type": "Entität" + "section": "Absatz / Textstelle" }, "error": "Fehler: Ungültige Seitenauswahl", "header": { @@ -2155,6 +2179,25 @@ "title": "{count, plural, one{Annotation} other {Annotationen}} entfernen" } }, + "remove-rectangle": { + "dialog": { + "content": { + "options": { + "multiple-pages": { + "description": "Schwärzung auf folgenden Seiten entfernen", + "extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.", + "extraOptionLabel": "Seitenbereich", + "extraOptionPlaceholder": "z. B. 1-20,22,32", + "label": "Auf allen Seiten entfernen" + }, + "only-this-page": { + "description": "Schwärzung nur an dieser Stelle in diesem Dokument entfernen", + "label": "Nur auf dieser Seite entfernen" + } + } + } + } + }, "remove-redaction": { "dialog": { "actions": { @@ -2316,13 +2359,13 @@ }, "roles": { "inactive": "Inaktiv", - "manager-admin": "Manager & {length, plural, one{Admin} other{Admins}}", + "manager-admin": "Manager & Admin", "no-role": "Keine Rolle definiert", - "red-admin": "{length, plural, one{Anwendungsadmin} other{Anwendungsadmins}}", + "red-admin": "Anwendungsadmin", "red-manager": "Manager", "red-user": "Benutzer", - "red-user-admin": "{length, plural, one{Benutzeradmin} other{Benutzeradmins}}", - "regular": "{length, plural, one{regulärer} other{reguläre}} Benutzer" + "red-user-admin": "Benutzeradmin", + "regular": "regulärer Benutzer" }, "search": { "active-dossiers": "Dokumente in aktiven Dossiers", diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index 6588d18b8..ae574fc2d 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -2359,12 +2359,12 @@ }, "roles": { "inactive": "Inactive", - "manager-admin": "Manager & {length, plural, one{Admin} other{Admins}}", + "manager-admin": "Manager & admin", "no-role": "No role defined", - "red-admin": "Application {length, plural, one{admin} other{admins}}", - "red-manager": "{length, plural, one{Manager} other{Managers}}", - "red-user": "{length, plural, one{User} other{Users}}", - "red-user-admin": "{length, plural, one{User} other{Users}} admin", + "red-admin": "Application admin", + "red-manager": "Manager", + "red-user": "User", + "red-user-admin": "Users admin", "regular": "Regular" }, "search-screen": { diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index b9a1f8a3b..d71a1ea28 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -112,9 +112,6 @@ } }, "add-edit-dossier-attribute": { - "error": { - "generic": "Speichern des Attributs fehlgeschlagen." - }, "form": { "label": "Name des Attributs", "label-placeholder": "Namen eingeben", @@ -138,6 +135,9 @@ }, "add-edit-entity": { "form": { + "ai-creation-enabled": "Enable AI creation", + "ai-description": "AI Description", + "ai-description-placeholder": "Enter AI description", "case-sensitive": "Groß-/Kleinschreibung beachten", "color": "Farbe {type, select, redaction{Annotation} hint{Hinweis} recommendation{Empfehlung} skipped{Übersprungene Annotation} ignored{Ignorierter Hinweis} other{}}", "color-placeholder": "#", @@ -1273,6 +1273,25 @@ }, "side-nav-title": "Konfiguration" }, + "edit-rectangle": { + "dialog": { + "content": { + "options": { + "multiple-pages": { + "description": "", + "extraOptionDescription": "", + "extraOptionLabel": "", + "extraOptionPlaceholder": "", + "label": "" + }, + "only-this-page": { + "description": "", + "label": "" + } + } + } + } + }, "edit-redaction": { "dialog": { "actions": { @@ -1286,7 +1305,7 @@ "options": { "in-document": { "description": "", - "label": "" + "label": "In Dokument ändern" }, "only-here": { "description": "", @@ -1730,21 +1749,21 @@ "label": "Nur auf dieser Seite konvertieren" } }, - "save": "Convert earmarks", - "title": "Convert earmarks to imported annotations" + "save": "Markierungen konvertieren", + "title": "Markierungen in importierte Annotationen konvertieren" }, "form": { "color": { - "label": "Earmark HEX color" + "label": "HEX-Code der Markierung" } }, "remove": { - "confirmation": "The {count} selected {count, plural, one{earmark} other{earmarks}} will be removed from the document", - "details": "Removing earmarks from the document will delete all the rectangles and leave a white background behind the highlighted text.", + "confirmation": "{count} ausgewählte {count, plural, one{Markierung wird} other{Markierungen werden}} aus dem Dokument entfernt", + "details": "Beim Entfernen von Markierungen werden die entsprechenden farbigen Kästen gelöscht. An die Stelle der Hervorhebung tritt ein weißer Hintergrund.", "options": { "all-pages": { - "description": "The earmarks in the selected HEX color will be removed on all pages of the document.", - "label": "Remove on all pages" + "description": "Die Markierungen in der ausgewählten HEX-Farbe werden auf allen Seiten des Dokuments entfernt.", + "label": "Auf allen Seiten entfernen" }, "this-page": { "description": "The earmarks in the selected HEX color will be removed only on the current page in view.", @@ -1765,23 +1784,23 @@ }, "import-redactions-dialog": { "actions": { - "cancel": "Cancel", - "import": "Import" + "cancel": "Abbrechen\n", + "import": "Importieren" }, - "details": "To apply annotations from another document, you first need to upload it.", + "details": "Um Schwärzungen aus einem anderen Dokument zu importieren, müssen Sie dieses zunächst hochladen.", "http": { - "error": "Failed to import components! {error}", - "success": "Annotations have been imported!" + "error": "Import der Schwärzungen fehlgeschlagen: {error}", + "success": "Annotationen wurden importiert." }, - "import-only-for-pages": "Import only for pages", + "import-only-for-pages": "Nur für diese Seiten importieren", "range": { - "label": "Minus(-) for range and comma(,) for enumeration.", - "placeholder": "e.g. 1-20,22,32" + "label": "Minus (-) für Spanne und Komma (,) für Aufzählung.", + "placeholder": "Beispiel: 1-20,22,32" }, - "title": "Import document with annotations" + "title": "Dokument mit Annotationen importieren" }, "initials-avatar": { - "unassigned": "Unbekannt", + "unassigned": "Nicht zugewiesen", "you": "Sie" }, "justifications-listing": { @@ -1789,7 +1808,7 @@ "delete": "Begründung löschen", "edit": "Begründung bearbeiten" }, - "add-new": "Neue Begründung hinzufügen", + "add-new": "Neue Begründung erstellen", "bulk": { "delete": "Ausgewählte Begründungen löschen" }, @@ -1799,123 +1818,128 @@ "table-col-names": { "description": "Beschreibung", "name": "Name", - "reason": "Rechtliche Grundlage" + "reason": "Rechtlichsgrundlage" }, - "table-header": "{length} {length, plural, one{justification} other{justifications}}" + "table-header": "{length} {length, plural, one{Begründung} other{Begründung}}" }, "license-info-screen": { "analysis-capacity-usage": { - "analyzed-cumulative": "Cumulative analyzed data volume", - "analyzed-per-month": "Analyzed data volume per month", - "licensed": "Licensed capacity", - "section-title": "Analysis capacity details", - "total-analyzed-data": "Total analyzed data", - "used-in-period": "Analysis capacity used in licensing period", - "used-in-total": "Total analysis capacity used" + "analyzed-cumulative": "Kumuliertes analysiertes Datenvolumen", + "analyzed-per-month": "Analysiertes Datenvolumen pro Monat\n", + "licensed": "Lizenzierte Kapazität", + "section-title": "Angaben zur Analysekapazität", + "total-analyzed-data": "Analysiertes Datenvolumen (Gesamt)", + "used-in-period": "Genutzte Analysekapazität
(Lizenzzeitraum)", + "used-in-total": "Insgesamt genutzte Analysekapazität" }, "backend-version": "Backend-Version der Anwendung", "copyright-claim-text": "Copyright © 2020 - {currentYear} knecon AG (powered by IQSER)", "copyright-claim-title": "Copyright", "custom-app-title": "Name der Anwendung", - "end-user-license-text": "Die Nutzung dieses Produkts unterliegt den Bedingungen der Endbenutzer-Lizenzvereinbarung für den RedactManager, sofern darin nichts anderweitig festgelegt.", + "end-user-license-text": "Die Nutzung dieses Produkts unterliegt den Bedingungen der Endbenutzer-Lizenzvereinbarung für RedactManager, sofern darin nichts Anderweitiges festgelegt ist.", "end-user-license-title": "Endbenutzer-Lizenzvereinbarung", "licensing-details": { - "license-title": "License title", - "licensed-analysis-capacity": "Licensed analysis capacity", - "licensed-page-count": "Licensed pages", - "licensed-retention-capacity": "Licensed retention capacity", - "licensed-to": "Licensed to", - "licensing-period": "Licensing period", - "section-title": "Licensing details" + "license-title": "Titel der Lizenz", + "licensed-analysis-capacity": "Lizenzierte Analysekapazität", + "licensed-page-count": "Lizenzierte Seiten", + "licensed-retention-capacity": "Lizenzierte Speicherkapazität", + "licensed-to": "Lizenziert für", + "licensing-period": "Lizenzzeitraum", + "section-title": "Lizenzdetails" }, "page-usage": { - "cumulative-pages": "Cumulative pages", - "current-analyzed-pages": "Analyzed pages in licensing period", - "ocr-analyzed-pages": "OCR-processed pages in licensing period", - "pages-per-month": "Pages per month", - "section-title": "Page usage details", - "total-analyzed": "Total analyzed pages", - "total-ocr-analyzed": "Total OCR-processed pages", - "total-pages": "Total pages", - "unlicensed-analyzed": "Unlicensed analyzed pages" + "cumulative-pages": "Kumulierte Seiten", + "current-analyzed-pages": "Analysierte Seiten (Lizenzzeitraum)", + "ocr-analyzed-pages": "OCR-verarbeitete Seiten (Lizenzzeitraum)", + "pages-per-month": "Seiten pro Monat", + "section-title": "Details zur Seitenanzahl", + "total-analyzed": "Analysierte Seiten
(Gesamt)", + "total-ocr-analyzed": "OCR-verarbeitete Seiten (Gesamt)", + "total-pages": "Lizenzierte Seiten", + "unlicensed-analyzed": "Ohne Lizenz analysierte Seiten" }, "retention-capacity-usage": { - "active-documents": "Active documents", - "archived-documents": "Archived documents", - "exceeded-capacity": "Exceeded capacity", - "section-title": "Retention capacity details", - "storage-capacity": "Capacity", - "trash-documents": "Documents in trash", - "unused": "Unused retention capacity", - "used-capacity": "Retention capacity used" + "active-documents": "Aktive Dokumente", + "archived-documents": "Archivierte Dokumente", + "exceeded-capacity": "Kapazitätsüberschreitung", + "section-title": "Details zur Speicherkapazität", + "storage-capacity": "Kapazität", + "trash-documents": "Dokumente im Papierkorb", + "unused": "Ungenutzte Speicherkapazität", + "used-capacity": "Genutzte Speicherkapazität" }, "status": { "active": "Aktiv", - "inactive": "Inactive" + "inactive": "Inaktiv" } }, "license-information": "Lizenzinformationen", - "load-all-annotations-success": "All annotations were loaded and are now visible in the document thumbnails", - "load-all-annotations-threshold-exceeded": "Caution, document contains more than {threshold} annotations. Drawing all annotations will affect the performance of the app and could even block it. Do you want to proceed?", - "load-all-annotations-threshold-exceeded-checkbox": "Do not show this warning again", - "loading": "Loading", + "load-all-annotations-success": "Alle Anmerkungen wurden geladen und sind jetzt in der Miniaturansicht des Dokuments sichtbar.", + "load-all-annotations-threshold-exceeded": "Achtung: Das Dokument enthält mehr als {threshold} Annotationen. Das Zeichnen aller Annotationen kann dazu führen, dass die App langsamer reagiert oder einfriert. Möchten Sie dennoch fortfahren?", + "load-all-annotations-threshold-exceeded-checkbox": "Diese Warnung nicht mehr anzeigen", + "loading": "Wird geladen...", "manual-annotation": { "dialog": { "actions": { "save": "Speichern" }, "content": { - "apply-on-multiple-pages": "Apply on multiple pages", - "apply-on-multiple-pages-hint": "Minus(-) for range and comma(,) for enumeration.", - "apply-on-multiple-pages-placeholder": "e.g. 1-20,22,32", "classification": "Wert / Klassifizierung", "comment": "Kommentar", - "dictionary": "Wörterbuch", - "edit-selected-text": "Edit selected text", "legalBasis": "Rechtsgrundlage", - "reason": "Begründung", - "reason-placeholder": "Wählen Sie eine Begründung aus ...", - "rectangle": "Benutzerdefinierter Bereich", - "section": "Absatz / Ort", - "text": "Ausgewählter Text:", - "type": "Entity" + "options": { + "multiple-pages": { + "description": "Annotation auf folgenden Seiten bearbeiten", + "extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.", + "extraOptionLabel": "Seitenbereich", + "extraOptionPlaceholder": "z. B. 1-20,22,32", + "label": "Auf mehreren Seiten anwenden" + }, + "only-this-page": { + "description": "Annotation nur an dieser Position im Dokument bearbeiten", + "label": "Auf dieser Seite anwenden" + } + }, + "reason": "Grund", + "reason-placeholder": "Grund auswählen ...", + "section": "Absatz / Textstelle" }, - "error": "Error! Invalid page selection", + "error": "Fehler: Ungültige Seitenauswahl", "header": { - "false-positive": "Set false positive", + "false-positive": "Als falsch-positiv markieren", "force-hint": "Hinweis erzwingen", - "force-redaction": "Schwärzung erzwingen", - "force-redaction-image-hint": "Redact image", - "hint": "Add hint", + "force-redaction": "Annotation erzwingen", + "force-redaction-image-hint": "Bild schwärzen", + "hint": "HInweis hinzufügen", "redact": "Annotation", - "redaction": "Redaction" + "redaction": "Schwärzung" } } }, - "minutes": "minutes", - "no-active-license": "Invalid or corrupt license – Please contact your administrator", + "minutes": "Minuten", + "no-active-license": "Ungültige oder beschädigte Lizenz — Bitte wenden Sie sich an Ihren Administrator", "notification": { - "assign-approver": "Sie wurden dem Dokument {fileHref, select, null{{fileName}} other{
{fileName}}} im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} als Genehmiger zugewiesen!", - "assign-reviewer": "Sie wurden dem Dokument {fileHref, select, null{{fileName}} other{{fileName}}} im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} als Reviewer zugewiesen!", + "assign-approver": "Sie wurden einem Dokument als Genehmiger zugewiesen.
Dokument: {fileHref, select, null{{fileName}} other{{fileName}}}
Dossier: {dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{{dossierName}}}}}", + "assign-reviewer": "Sie wurden einem Dokument als Prüfer zugewiesen.
Dokument: {fileHref, select, null{{fileName}} other{{fileName}}}
Dossier: {dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{{dossierName}}}}}", "document-approved": "{fileHref, select, null{{fileName}} other{{fileName}}} wurde genehmigt!", "dossier-deleted": "Dossier: {dossierName} wurde gelöscht!", - "dossier-owner-deleted": "The owner of dossier: {dossierName} has been deleted!", + "dossier-owner-deleted": "Der Besitzer des Dossiers wurde gelöscht: {dossierName}", "dossier-owner-removed": "Der Dossier-Owner von {dossierHref, select, null{{dossierName}} other{{dossierName}}} wurde entfernt!", - "dossier-owner-set": "Eigentümer von {dossierHref, select, null{{dossierName}} other{{dossierName}}} geändert zu {user}!", - "download-ready": "Ihr Download ist fertig!", + "dossier-owner-set": "Sie sind jetzt Besitzer des Dossiers {dossierHref, select, null{{dossierName}} other{{dossierName}}}.", + "download-ready": "Ihr Download steht bereit.", "no-data": "Du hast aktuell keine Benachrichtigungen", - "unassigned-from-file": "Sie wurden vom Dokument {fileHref, select, null{{fileName}} other{{fileName}}} im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} entfernt!", + "unassigned-from-file": "Sie wurden von einem Dokument entfernt.
Dokument: {fileHref, select, null{{fileName}} other{{fileName}}}
Dossier: {dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{{dossierName}}}}}", "user-becomes-dossier-member": "{user} ist jetzt Mitglied des Dossiers {dossierHref, select, null{{dossierName}} other{{dossierName}}}!", "user-demoted-to-reviewer": "{user} wurde im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} auf die Reviewer-Berechtigung heruntergestuft!", "user-promoted-to-approver": "{user} wurde im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} zum Genehmiger ernannt!", "user-removed-as-dossier-member": "{user} wurde als Mitglied von: {dossierHref, select, null{{dossierName}} other{{dossierName}}} entfernt!" }, "notifications": { - "button-text": "Notifications", - "deleted-dossier": "Deleted dossier", + "button-text": "Benachrichtigungen", + "deleted-dossier": "Gelöschtes Dossier", "label": "Benachrichtigungen", "mark-all-as-read": "Alle als gelesen markieren", - "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}" + "mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren" }, "notifications-screen": { "category": { @@ -1923,31 +1947,31 @@ "in-app-notifications": "In-App-Benachrichtigungen" }, "error": { - "generic": "Ein Fehler ist aufgetreten... Aktualisierung der Einstellungen fehlgeschlagen!" + "generic": "Fehler: Aktualisierung der Präferenzen fehlgeschlagen." }, "groups": { - "document": "Dokumentbezogene Benachrichtigungen", - "dossier": "Dossierbezogene Benachrichtigungen", + "document": "Benachrichtigungen zu Dokumenten", + "dossier": "Benachrichtigungen zu Dossiers", "other": "Andere Benachrichtigungen" }, "options": { "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen bin", - "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Überprüfer zugewiesen bin", - "DOCUMENT_APPROVED": "Wenn sich der Dokumentstatus in Genehmigt ändert", - "DOCUMENT_UNDER_APPROVAL": "Wenn sich der Dokumentstatus in „In Genehmigung“ ändert", - "DOCUMENT_UNDER_REVIEW": "Wenn sich der Dokumentstatus in Wird überprüft ändert", + "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Prüfer zugewiesen werde", + "DOCUMENT_APPROVED": "Wenn sich der Dokumentstatus zu \"Freigegeben\" ändert (Nur für Dossier-Besitzer verfügbar)", + "DOCUMENT_UNDER_APPROVAL": "Wenn sich der Dokumentstatus zu „In Genehmigung“ ändert", + "DOCUMENT_UNDER_REVIEW": "Wenn sich der Dokumentstatus zu \"In Bearbeitung\" ändert", "DOSSIER_DELETED": "Wenn ein Dossier gelöscht wurde", - "DOSSIER_OWNER_DELETED": "Wenn der Eigentümer eines Dossiers gelöscht wurde", + "DOSSIER_OWNER_DELETED": "Wenn der Besitzer eines Dossiers gelöscht wurde", "DOSSIER_OWNER_REMOVED": "Wenn ich den Besitz des Dossiers verliere", - "DOSSIER_OWNER_SET": "Wenn ich der Besitzer des Dossiers werde", + "DOSSIER_OWNER_SET": "Wenn ich der Besitzer des Dossiers werde\n", "DOWNLOAD_READY": "Wenn ein Download bereit ist", - "UNASSIGNED_FROM_FILE": "Wenn die Zuweisung zu einem Dokument aufgehoben wird", - "USER_BECOMES_DOSSIER_MEMBER": "Wenn ein Benutzer zu meinem Dossier hinzugefügt wurde", - "USER_DEGRADED_TO_REVIEWER": "Wenn ich Gutachter in einem Dossier werde", + "UNASSIGNED_FROM_FILE": "Wenn ich als Bearbeiter von einem Dokument entfernt werde", + "USER_BECOMES_DOSSIER_MEMBER": "Wenn ich zu einem Dossier hinzugefügt wurde", + "USER_DEGRADED_TO_REVIEWER": "Wenn ich in einem Dossier zum Prüfer herabgestuft werde", "USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde", "USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere" }, - "options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten", + "options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten", "schedule": { "daily": "Tägliche Zusammenfassung", "instant": "Sofortig", @@ -1957,44 +1981,44 @@ }, "ocr": { "confirmation-dialog": { - "cancel": "Cancel", - "question": "Manual changes could get lost if OCR makes changes at those positions. Are you sure you want to proceed?", - "title": "Warning: the file has manual adjustments!" + "cancel": "Abbrechen", + "question": "Manuelle Änderungen können überschrieben werden, wenn die OCR an den jeweiligen Stellen Änderungen vornimmt. Möchten Sie dennoch fortfahren?", + "title": "Warnung: Die Datei enthält manuelle Änderungen!" } }, "overwrite-files-dialog": { - "archive-question": "Dossier is not empty, so files might overlap with the contents of the archive you are uploading. Choose how to proceed in case of duplicates:", - "archive-title": "Uploading a ZIP archive", - "file-question": "{filename} ist bereits vorhanden. Wie möchten Sie fortfahren?", - "file-title": "Das Dokument existiert bereits!", + "archive-question": "Das Dossier enthält bereits Dateien. Es könnte zu Überschneidungen mit dem Inhalt des neuen Uploads kommen. Wählen Sie aus, wie mit Duplikaten umgegangen werden soll:", + "archive-title": "ZIP-Archiv hochladen", + "file-question": "{filename} ist bereits vorhanden. Wie möchten Sie vorgehen?", + "file-title": "Datei existiert bereits.", "options": { - "all-files": "Apply to all files of current upload", + "all-files": "Auf alle Dateien des Uploads anwenden", "cancel": "Alle Uploads abbrechen", - "current-files": "Apply to current file", + "current-files": "Auf aktuelle Datei anwenden", "full-overwrite": { - "description": "Manual changes done to the existing file will be removed and you are able to start over.", - "label": "Overwrite and start over" + "description": "Verwerfen Sie alle manuellen Änderungen und beginnen Sie mit der frisch verarbeiteten Datei.", + "label": "Überschreiben und manuelle Änderungen beibehalten" }, "partial-overwrite": { - "description": "Manual changes are kept only if the affected annotations are still at the same position in the file. Some annotations could be misplaced if the content of the file changed.", - "label": "Overwrite and keep manual changes" + "description": "Behalten Sie manuelle Änderungen, sofern die Schwärzungen an der ursprünglichen Positionen bleiben.
Bei geändertem Inhalt könnten Schwärzungen sonst falsch platziert werden.", + "label": "Überschreiben und manuelle Änderungen beibehalten" }, - "proceed": "Proceed", + "proceed": "Fortfahren", "skip": { - "description": "The upload will be skipped and the existing file will not be replaced.", - "label": "Keep the existing file and do not overwrite" + "description": "Behalten Sie die vorhandene Datei und überspringen Sie den Upload.", + "label": "Vorhandene Datei beibehalten und nicht überschreiben" } }, - "remember": "Remember choice and don't ask me again" + "remember": "Auswahl speichern und nicht noch einmal fragen" }, - "page": "Page {page} - {count} {count, plural, one{annotation} other{annotations}}", + "page": "Seite {page} - {count} {count, plural, one{Annotation} other{Annotationen}}", "page-rotation": { - "apply": "APPLY", + "apply": "BESTÄTIGEN", "confirmation-dialog": { - "question": "You have unapplied page rotations. Choose how to proceed:", - "title": "Pending page rotations" + "question": "Sie haben eine unbestätigte Seitendrehung. Wie möchten Sie vorgehen?", + "title": "Drehung der Seite steht aus" }, - "discard": "DISCARD" + "discard": "VERWERFEN" }, "pagination": { "next": "Nächste", @@ -2002,167 +2026,186 @@ }, "pdf-viewer": { "header": { - "all-annotations-loaded": "All annotations loaded", - "compare-button": "Compare", - "layers-panel-button": "Layers", + "all-annotations-loaded": "Alle Annotationen geladen", + "compare-button": "Vergleichen", + "layers-panel-button": "Ebenen", "left-panel-button": "Panel", - "load-all-annotations": "Load all annotations", - "no-outlines-text": "No outlines available", - "no-signatures-text": "This document has NO signature fields", - "outline-multi-select": "Edit", - "outlines-panel-button": "Outlines", - "pan-tool-button": "Pan", - "rectangle-tool-button": "Rectangle", - "rotate-left-button": "Rotate page left", - "rotate-right-button": "Rotate page right", - "select-tool-button": "Select", - "signature-panel-button": "Signatures", - "thumbnails-panel-button": "Thumbnails", - "toggle-layers": "{active, select, true{Disable} false{Enable} other{}} layout grid", - "toggle-readable-redactions": "Show redactions {active, select, true{as in final document} false{in preview color} other{}}", - "toggle-tooltips": "{active, select, true{Disable} false{Enable} other{}} annotation tooltips", - "zoom-in-button": "Zoom In", - "zoom-out-button": "Zoom Out" + "load-all-annotations": "Alle Annotationen geladen", + "no-outlines-text": "Keine Gliederung verfügbar", + "no-signatures-text": "Dieses Dokument enthält keine Unterschriftenfelder.", + "outline-multi-select": "Bearbeiten", + "outlines-panel-button": "Gliederung", + "pan-tool-button": "Verschieben", + "rectangle-tool-button": "Bereich schwärzen", + "rotate-left-button": "Seite nach links drehen", + "rotate-right-button": "Seite nach rechts drehen", + "select-tool-button": "Auswählen", + "signature-panel-button": "Unterschriften", + "thumbnails-panel-button": "Miniaturansicht", + "toggle-layers": "Layout-Raster {active, select, true{deaktivieren} false{aktivieren} other{}}", + "toggle-readable-redactions": "Schwärzungen {active, select, true{wie im finalen Dokument} false{in Preview-Farbe anzeigen} other{}}", + "toggle-tooltips": "Tooltips für Annotationen {active, select, true{deaktivieren} false{aktivieren} other{}}", + "zoom-in-button": "Vergrößern", + "zoom-out-button": "Verkleinern" }, "text-popup": { "actions": { - "search": "Search for selected text" + "search": "Ausgewählten Text suchen" } } }, "permissions-screen": { "dossier": { - "access": "Access dossier", - "view": "View dossier" + "access": "Dossier öffnen", + "view": "Dossiers sehen" }, - "label": "{targetObject, select, Dossier{Dossier} other{}} permissions", + "label": "{targetObject, select, Dossier{Dossier} other{}}-Berechtigungen", "mapped": { - "approve": "Dossier members", - "everyone-else": "Everyone else", - "owner": "Owner", + "approve": "Dossier-Mitglieder", + "everyone-else": "Sonstige", + "owner": "Besitzer", "review": "" }, "table-col-names": { - "permission": "Permission" + "permission": "Berechtigung" }, "table-header": { - "title": "{length} {length, plural, one{permission} other{permissions}}" + "title": "{length} {length, plural, one{Berechtigung} other{Berechtigungen}}" } }, "preferences-screen": { "actions": { - "save": "Save changes" + "save": "Änderungen speichern" }, "form": { - "auto-expand-filters-on-action": "Auto expand filters on my actions", - "help-mode-dialog": "Help Mode Dialog", - "load-all-annotations-warning": "Warning regarding loading all annotations at once in file preview", - "overwrite-file-option": "Preferred action when re-uploading an already existing file", - "table-extraction-type": "Table extraction type" + "auto-expand-filters-on-action": "Filter ausgehend von meinen Aktionen automatisch anpassen", + "help-mode-dialog": "Dialog zur Aktivierung des Hilfemodus", + "load-all-annotations-warning": "Warnung bei gleichzeitigem Laden aller Annotationen in der Miniaturansicht", + "overwrite-file-option": "Bevorzugte Aktion beim erneuten Hochladen einer bereits vorhandenen Datei", + "table-extraction-type": "Art der Tabellenextraktion" }, - "label": "Preferences", - "title": "Edit preferences", - "warnings-description": "Selecting the 'Do not show this message again' checkbox will skip the warning dialog the next time you trigger it.", - "warnings-label": "Prompts and dialogs", - "warnings-subtitle": "Do not show again options" + "label": "Präferenzen", + "title": "Präferenzen bearbeiten", + "warnings-description": "Wenn Sie das Kontrollkästchen „Diese Nachricht nicht mehr anzeigen“ aktivieren, wird dieser Dialog beim nächsten Mal übersprungen.", + "warnings-label": "Dialoge und Meldungen", + "warnings-subtitle": "„Nicht mehr anzeigen“-Optionen" }, "processing": { - "basic": "Processing", + "basic": "Verarbeitung läuft", "ocr": "OCR" }, "processing-status": { "ocr": "OCR", - "pending": "Pending", - "processed": "Processed", - "processing": "Processing" + "pending": "Ausstehend", + "processed": "Verarbeitet", + "processing": "Verarbeitung läuft" }, "readonly": "Lesemodus", - "readonly-archived": "Read only (archived)", + "readonly-archived": "Lesemodus (archiviert)", "redact-text": { "dialog": { "actions": { - "cancel": "Cancel", - "save": "Save" + "cancel": "Abbrechen", + "save": "Speichern" }, "content": { - "comment": "Comment", - "comment-placeholder": "Add remarks or mentions...", + "comment": "Kommentar", + "comment-placeholder": "Bemerkungen oder Notizen hinzufügen...", "edit-text": "", - "legal-basis": "Legal basis", + "legal-basis": "Rechtsgrundlage", "options": { "in-document": { - "description": "Add redaction for each occurrence of the term in this document.", - "label": "Redact in document" + "description": "Fügen Sie die Schwärzung an allen Stellen in diesem Dokument hinzu.", + "label": "Im Dokument schwärzen" }, "in-dossier": { - "description": "Add redaction in every document in {dossierName}.", - "extraOptionLabel": "Apply to all dossiers", - "label": "Redact in dossier" + "description": "Fügen Sie die Schwärzung zu jedem Dokument in {dossierName} hinzu.", + "extraOptionLabel": "In alle Dossiers übernehmen", + "label": "Im Dossier schwärzen" }, "only-here": { - "description": "Add redaction only at this position in this document.", - "label": "Redact only here" + "description": "Fügen Sie die Schwärzung zu jedem Dokument in {dossierName} hinzu.", + "label": "Nur hier schwärzen" } }, - "reason": "Reason", - "reason-placeholder": "Select a reasons...", + "reason": "Grund", + "reason-placeholder": "Grund auswählen...", "revert-text": "", - "type": "Type", - "type-placeholder": "Select type...", + "type": "Typ", + "type-placeholder": "Typ auswählen...", "unchanged": "", - "value": "Value" + "value": "Wert" }, - "title": "Redact text" + "title": "Text schwärzen" } }, - "redaction-abbreviation": "C", - "references": "{count} {count, plural, one{reference} other{references}}", + "redaction-abbreviation": "A", + "references": "{count} {count, plural, one{Verweis} other{Verweise}}", "remove-annotation": { "dialog": { "actions": { - "cancel": "Cancel", - "save": "Save" + "cancel": "Abbrechen", + "save": "Speichern" }, "content": { - "comment": "Comment", - "comment-placeholder": "Add remarks or mentions...", + "comment": "Kommentar", + "comment-placeholder": "Bemerkungen oder Notizen hinzufügen...", "list-item": "{text}", - "list-item-false-positive": "''{text}'' in the context: ''{context}''", + "list-item-false-positive": "\"{text} im Kontext: \"{context}\"", "options": { "false-positive": { - "description": "''{value}'' is not a ''{type}'' in this context: ''{context}''.", - "description-bulk": "The selected items should not be annotated in their respective contexts.", - "label": "False positive" + "description": "''{value}''ist kein ''{type}'' in diesem Kontext: ''{context}''.", + "description-bulk": "Markieren Sie die Schwärzung als falsch-positiv. Der Begriff wird in diesem Dossier nicht geschwärzt, wenn er im gleichen Kontext vorkommt.", + "label": "Falsch-Positiv" }, "in-document": { "description": "", - "label": "" + "label": "Aus Dokument entfernen" }, "in-dossier": { - "description": "Do not annotate ''{value}'' as ''{type}'' in any dossier.", - "description-bulk": "Do not annotate the selected terms as their respective types in any dossier.", - "label": "No longer annotate as ''{type}''", - "label-bulk": "No longer annotate in any dossier" + "description": "Der Begriff wird in keinem Dossier annotiert.", + "description-bulk": "Der Begriff wird in keinem Dossiers mit dem entsprechenden Typ annotiert.", + "label": "Aus Dossier entfernen", + "label-bulk": "Aus Dossier entfernen" }, "only-here": { - "description": "Do not annotate ''{value}'' at this position in the current document.", - "description-bulk": "Do not annotate the selected terms at this position in the current document.", - "label": "Remove here" + "description": "Annotieren Sie den Begriff an dieser Stelle im Dokument nicht.", + "description-bulk": "Annotieren Sie den Begriff an dieser Stelle im Dokument nicht.", + "label": "Hier entfernen" } }, - "redacted-text": "Selected annotations" + "redacted-text": "Ausgewählte Annotationen" }, - "title": "Remove {count, plural, one{annotation} other {annotations}}" + "title": "{count, plural, one{Annotation} other {Annotationen}} entfernen" + } + }, + "remove-rectangle": { + "dialog": { + "content": { + "options": { + "multiple-pages": { + "description": "", + "extraOptionDescription": "", + "extraOptionLabel": "", + "extraOptionPlaceholder": "", + "label": "" + }, + "only-this-page": { + "description": "", + "label": "" + } + } + } } }, "remove-redaction": { "dialog": { "actions": { - "cancel": "Cancel", - "save": "Save" + "cancel": "Abbrechen", + "save": "Speichern" }, "content": { - "comment": "Comment", + "comment": "Kommentar", "comment-placeholder": "Add remarks or mentions...", "options": { "do-not-recommend": { @@ -2180,10 +2223,10 @@ }, "in-document": { "description": "", - "label": "" + "label": "Aus Dokument entfernen" }, "in-dossier": { - "description": "Do not {type} \"{value}\" in any document of the current dossier.", + "description": "Do not annotate the term in this dossier.", "description-bulk": "", "extraOptionLabel": "Apply to all dossiers", "label": "Remove from dossier", @@ -2316,13 +2359,13 @@ }, "roles": { "inactive": "Inaktiv", - "manager-admin": "Manager & {length, plural, one{Admin} other{Admins}}", + "manager-admin": "Manager & admin", "no-role": "Keine Rolle definiert", - "red-admin": "{length, plural, one{Anwendungsadmin} other{Anwendungsadmins}}", + "red-admin": "Anwendungsadministrator", "red-manager": "Manager", "red-user": "Benutzer", - "red-user-admin": "{length, plural, one{Benutzeradmin} other{Benutzeradmins}}", - "regular": "{length, plural, one{regulärer} other{reguläre}} Benutzer" + "red-user-admin": "Benutzer-Admin", + "regular": "Regulär" }, "search": { "active-dossiers": "ganze Plattform", diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index 4904c2b96..532ceadec 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -1305,7 +1305,7 @@ "options": { "in-document": { "description": "", - "label": "" + "label": "In Dokument ändern" }, "only-here": { "description": "", @@ -1874,8 +1874,8 @@ } }, "license-information": "License Information", - "load-all-annotations-success": "All annotations were loaded and are now visible in the document thumbnails", - "load-all-annotations-threshold-exceeded": "Caution, document contains more than {threshold} annotations. Drawing all annotations will affect the performance of the app and could even block it. Do you want to proceed?", + "load-all-annotations-success": "All annotations were loaded and are now visible in the document thumbnails.", + "load-all-annotations-threshold-exceeded": "Alert: Document contains more than {threshold} annotations. Drawing all annotations may cause the app to slow down or freeze. Do you still want to continue?", "load-all-annotations-threshold-exceeded-checkbox": "Do not show this warning again", "loading": "Loading", "manual-annotation": { @@ -1889,14 +1889,14 @@ "legalBasis": "Legal Basis", "options": { "multiple-pages": { - "description": "Edit redaction the range of pages", + "description": "Edit annotation the range of pages", "extraOptionDescription": "Minus(-) for range and comma(,) for enumeration", "extraOptionLabel": "Range", "extraOptionPlaceholder": "e.g. 1-20,22,32", "label": "Apply on multiple pages" }, "only-this-page": { - "description": "Edit redaction only at this position in this document", + "description": "Edit annotation only at this position in this document", "label": "Apply only on this page" } }, @@ -1919,16 +1919,16 @@ "minutes": "minutes", "no-active-license": "Invalid or corrupt license – Please contact your administrator", "notification": { - "assign-approver": "You have been assigned to {fileHref, select, null{{fileName}} other{{fileName}}} in dossier: {dossierHref, select, null{{dossierName}} other{{dossierName}}}!", - "assign-reviewer": "You have been assigned to {fileHref, select, null{{fileName}} other{{fileName}}} in dossier: {dossierHref, select, null{{dossierName}} other{{dossierName}}}!", + "assign-approver": "You have been assigned as approver for a document.
Document: {fileHref, select, null{{fileName}} other{{fileName}}}
Dossier: {dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{{dossierName}}}}}", + "assign-reviewer": "You have been assigned as reviewer for a document.
Document: {fileHref, select, null{{fileName}} other{{fileName}}}
\nDossier: {dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{{dossierName}}}}}", "document-approved": " {fileHref, select, null{{fileName}} other{{fileName}}} has been moved to Done!", "dossier-deleted": "Dossier: {dossierName} has been deleted!", "dossier-owner-deleted": "The owner of dossier: {dossierName} has been deleted!", "dossier-owner-removed": "You have been removed as dossier owner from {dossierHref, select, null{{dossierName}} other{{dossierName}}}!", - "dossier-owner-set": "You are now the dossier owner of {dossierHref, select, null{{dossierName}} other{{dossierName}}}!", + "dossier-owner-set": "You are now the dossier owner of {dossierHref, select, null{{dossierName}} other\n{{dossierName}}}!", "download-ready": "Your download is ready!", "no-data": "You currently have no notifications", - "unassigned-from-file": "You have been unassigned from {fileHref, select, null{{fileName}} other{{fileName}}} in dossier: {dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{{dossierName}}}}}!", + "unassigned-from-file": "You have been unassigned from a document.
Document: {fileHref, select, null{{fileName}} other{{fileName}}}
Dossier: {dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{{dossierName}\n}}}}", "user-becomes-dossier-member": "You have been added to dossier: {dossierHref, select, null{{dossierName}} other{{dossierName}}}!", "user-demoted-to-reviewer": "You have been demoted to reviewer in dossier: {dossierHref, select, null{{dossierName}} other{{dossierName}}}!", "user-promoted-to-approver": "You have been promoted to approver in dossier: {dossierHref, select, null{{dossierName}} other{{dossierName}}}!", @@ -1982,12 +1982,12 @@ "ocr": { "confirmation-dialog": { "cancel": "Cancel", - "question": "Manual changes could get lost if OCR makes changes at those positions. Are you sure you want to proceed?", + "question": "Manual changes may be overwritten if the OCR makes changes at the respective positions. Do you still want to proceed?", "title": "Warning: the file has manual adjustments!" } }, "overwrite-files-dialog": { - "archive-question": "Dossier is not empty, so files might overlap with the contents of the archive you are uploading. Choose how to proceed in case of duplicates:", + "archive-question": "Dossier already contains files. Files might overlap with the contents of the folder you are uploading. Select how to handle duplicates:", "archive-title": "Uploading a ZIP archive", "file-question": "{filename} already exists. Choose how to proceed:", "file-title": "File already exists!", @@ -1996,16 +1996,16 @@ "cancel": "Cancel upload", "current-files": "Apply to current file", "full-overwrite": { - "description": "Manual changes done to the existing file will be removed and you are able to start over.", + "description": "Remove all manual changes made to the file, and start reviewing a freshly processed file.", "label": "Overwrite and start over" }, "partial-overwrite": { - "description": "Manual changes are kept only if the affected annotations are still at the same position in the file. Some annotations could be misplaced if the content of the file changed.", + "description": "Keep manual changes if the affected redactions remain in their original positions. Some redactions could be misplaced if the content has changed.", "label": "Overwrite and keep manual changes" }, "proceed": "Proceed", "skip": { - "description": "The upload will be skipped and the existing file will not be replaced.", + "description": "Skip the file upload and do not replace the existing file.", "label": "Keep the existing file and do not overwrite" } }, @@ -2079,14 +2079,14 @@ }, "form": { "auto-expand-filters-on-action": "Auto expand filters on my actions", - "help-mode-dialog": "Help Mode Dialog", - "load-all-annotations-warning": "Warning regarding loading all annotations at once in file preview", + "help-mode-dialog": "Help mode activation dialog", + "load-all-annotations-warning": "Warning regarding simultaneous loading of all annotations in thumbnails", "overwrite-file-option": "Preferred action when re-uploading an already existing file", "table-extraction-type": "Table extraction type" }, "label": "Preferences", "title": "Edit preferences", - "warnings-description": "Selecting the 'Do not show this message again' checkbox will skip the warning dialog the next time you trigger it.", + "warnings-description": "Selecting the 'Do not show this message again' checkbox will skip the dialog the next time you trigger it.", "warnings-label": "Prompts and dialogs", "warnings-subtitle": "Do not show again options" }, @@ -2155,21 +2155,21 @@ "options": { "false-positive": { "description": "''{value}'' is not a ''{type}'' in this context: ''{context}''.", - "description-bulk": "The selected items should not be annotated in their respective contexts.", + "description-bulk": "Mark this redaction as a false-positive. The term will not be redacted in this dossier if it occurs in the same context.", "label": "False positive" }, "in-document": { "description": "", - "label": "" + "label": "Aus Dokument entfernen" }, "in-dossier": { - "description": "Do not annotate ''{value}'' as ''{type}'' in any dossier.", + "description": "Do not annotate the term in any dossier.", "description-bulk": "Do not annotate the selected terms as their respective types in any dossier.", "label": "No longer annotate as ''{type}''", - "label-bulk": "No longer annotate in any dossier" + "label-bulk": "Do not annotate as {type}" }, "only-here": { - "description": "Do not annotate ''{value}'' at this position in the current document.", + "description": "Do not annotate the term at this position in this document.", "description-bulk": "Do not annotate the selected terms at this position in the current document.", "label": "Remove here" } @@ -2223,10 +2223,10 @@ }, "in-document": { "description": "", - "label": "" + "label": "Aus Dokument entfernen" }, "in-dossier": { - "description": "Do not {type} \"{value}\" in any document of the current dossier.", + "description": "Do not annotate the term in this dossier.", "description-bulk": "", "extraOptionLabel": "Apply to all dossiers", "label": "Remove from dossier", @@ -2359,12 +2359,12 @@ }, "roles": { "inactive": "Inactive", - "manager-admin": "Manager & {length, plural, one{Admin} other{Admins}}", + "manager-admin": "Manager & admin", "no-role": "No role defined", - "red-admin": "Application {length, plural, one{admin} other{admins}}", - "red-manager": "{length, plural, one{Manager} other{Managers}}", - "red-user": "{length, plural, one{User} other{Users}}", - "red-user-admin": "{length, plural, one{User} other{Users}} admin", + "red-admin": "Application admin", + "red-manager": "Manager", + "red-user": "User", + "red-user-admin": "Users admin", "regular": "Regular" }, "search-screen": { From 965166a349cf90156554e9724f93d84eb7f2eff2 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Mon, 21 Oct 2024 18:06:01 +0300 Subject: [PATCH 093/125] RED-7340 - When a user has entered an invalid page range string, display a read border around the input field --- .../edit-redaction-dialog.component.html | 4 ++-- .../edit-redaction-dialog.component.scss | 12 ++++++++++-- .../edit-redaction-dialog.component.ts | 5 ++++- .../rectangle-annotation-dialog.component.ts | 2 +- .../remove-redaction-dialog.component.ts | 2 +- .../file-preview/utils/dialog-options.ts | 1 + .../file-preview/utils/form-validators.ts | 18 ++++++++++++++++-- libs/common-ui | 2 +- 8 files changed, 36 insertions(+), 10 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html index 55bfda05b..dd1e2fbb3 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html @@ -6,7 +6,7 @@ class="dialog-header heading-l" >
-
+
diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.scss b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.scss index 112313d42..b767dc8db 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.scss @@ -1,8 +1,16 @@ .dialog-content { padding-top: 8px; - &.fixed-height { - height: 386px; + &.rectangle-dialog { + height: 600px; + } + + &.image-dialog { + height: 346px; + } + + .rectangle-dialog, + .image-dialog { overflow-y: auto; } } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts index 403a7e829..03753ad6a 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts @@ -263,7 +263,10 @@ export class EditRedactionDialogComponent disabled: this.isImported, }), section: new FormControl({ value: sameSection ? this.annotations[0].section : null, disabled: this.isImported }), - option: new FormControl>(this.options[0], validatePageRange()), + option: new FormControl>( + this.options[0], + validatePageRange(this.data.file.numberOfPages), + ), value: new FormControl(this.allRectangles ? this.annotations[0].value : null), }); } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts index 0fd48e9db..fdbc7c7ed 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts @@ -130,7 +130,7 @@ export class RectangleAnnotationDialog reason: [null, Validators.required], comment: [null], classification: [NON_READABLE_CONTENT], - option: [this.#getOption(SystemDefaults.RECTANGLE_REDACT_DEFAULT), validatePageRange()], + option: [this.#getOption(SystemDefaults.RECTANGLE_REDACT_DEFAULT), validatePageRange(this.data.file.numberOfPages)], }); } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts index b27c5dbbf..25a3a3865 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts @@ -112,7 +112,7 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< readonly redactedTexts = this.data.redactions.map(annotation => annotation.value); form: UntypedFormGroup = this._formBuilder.group({ comment: [null], - option: [this.defaultOption, validatePageRange(true)], + option: [this.defaultOption, validatePageRange(this.data.file.numberOfPages, true)], }); readonly selectedOption = toSignal(this.form.get('option').valueChanges.pipe(map(value => value.value))); diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts index 5b4288ccd..a0a680575 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts @@ -118,6 +118,7 @@ export const getRectangleRedactOptions = (action: 'add' | 'edit' | 'remove' = 'a description: translations.multiplePages.extraOptionDescription, placeholder: translations.multiplePages.extraOptionPlaceholder, value: '', + errorCode: 'invalidRange', }, }, ]; diff --git a/apps/red-ui/src/app/modules/file-preview/utils/form-validators.ts b/apps/red-ui/src/app/modules/file-preview/utils/form-validators.ts index b66980731..eb01f1e31 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/form-validators.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/form-validators.ts @@ -1,12 +1,26 @@ import { AbstractControl, ValidatorFn } from '@angular/forms'; -export const validatePageRange = (allowEmpty = false): ValidatorFn => { +export const validatePageRange = (numberOfPages: number, allowEmpty = false): ValidatorFn => { return (control: AbstractControl): { [key: string]: any } | null => { const option = control.value; if (option?.additionalInput) { const value = option.additionalInput.value; const validRange = /^(\d+(-\d+)?)(,\d+(-\d+)?)*$/.test(value); - return validRange || (!value.length && allowEmpty) ? null : { invalidRange: true }; + + if (!validRange && !(value.length === 0 && allowEmpty)) { + return { invalidRange: true }; + } + + const ranges = value.split(','); + const isWithinRange = ranges.every(range => { + const [start, end] = range.split('-').map(Number); + if (end) { + return start >= 1 && end <= numberOfPages && start < end; + } + return start >= 1 && start <= numberOfPages; + }); + + return isWithinRange || (value.length === 0 && allowEmpty) ? null : { invalidRange: true }; } return null; }; diff --git a/libs/common-ui b/libs/common-ui index e92bd55cf..a5d10ad14 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit e92bd55cfc37342fec5a246d5cc5226b95fc427e +Subproject commit a5d10ad1482a69f100f659bcf2b7f2072a6241c9 From a7b652c1371f8430bc4840d9f7d80b1d280f8801 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Tue, 22 Oct 2024 12:45:34 +0300 Subject: [PATCH 094/125] RED-10220: added support for justification technical name. --- ...d-edit-justification-dialog.component.html | 9 +++++ ...add-edit-justification-dialog.component.ts | 35 +++++++++++++++---- apps/red-ui/src/app/utils/functions.ts | 4 +-- .../lib/legal-basis/justification.model.ts | 12 +++++++ .../src/lib/legal-basis/legal-basis.ts | 1 + 5 files changed, 53 insertions(+), 8 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/screens/justifications/add-edit-justification-dialog/add-edit-justification-dialog.component.html b/apps/red-ui/src/app/modules/admin/screens/justifications/add-edit-justification-dialog/add-edit-justification-dialog.component.html index 7e58ccc7e..a8aedc290 100644 --- a/apps/red-ui/src/app/modules/admin/screens/justifications/add-edit-justification-dialog/add-edit-justification-dialog.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/justifications/add-edit-justification-dialog/add-edit-justification-dialog.component.html @@ -17,6 +17,15 @@ type="text" />
+
+ +
{{ this.technicalName() || '-' }}
+ +
diff --git a/apps/red-ui/src/app/modules/admin/screens/justifications/add-edit-justification-dialog/add-edit-justification-dialog.component.ts b/apps/red-ui/src/app/modules/admin/screens/justifications/add-edit-justification-dialog/add-edit-justification-dialog.component.ts index fb62106b4..699935349 100644 --- a/apps/red-ui/src/app/modules/admin/screens/justifications/add-edit-justification-dialog/add-edit-justification-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/justifications/add-edit-justification-dialog/add-edit-justification-dialog.component.ts @@ -1,11 +1,13 @@ -import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, computed, Inject, untracked } from '@angular/core'; import { ReactiveFormsModule, UntypedFormGroup, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Justification } from '@red/domain'; import { JustificationsService } from '@services/entity-services/justifications.service'; -import { BaseDialogComponent, CircleButtonComponent, IconButtonComponent } from '@iqser/common-ui'; +import { BaseDialogComponent, CircleButtonComponent, HasScrollbarDirective, IconButtonComponent } from '@iqser/common-ui'; import { firstValueFrom } from 'rxjs'; import { TranslateModule } from '@ngx-translate/core'; +import { formControlToSignal } from '@utils/functions'; +import { toSignal } from '@angular/core/rxjs-interop'; interface DialogData { justification?: Justification; @@ -16,9 +18,29 @@ interface DialogData { templateUrl: './add-edit-justification-dialog.component.html', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, - imports: [TranslateModule, ReactiveFormsModule, IconButtonComponent, CircleButtonComponent], + imports: [TranslateModule, ReactiveFormsModule, IconButtonComponent, CircleButtonComponent, HasScrollbarDirective], }) export class AddEditJustificationDialogComponent extends BaseDialogComponent { + readonly form = this.#getForm(); + readonly name = formControlToSignal(this.form.controls['name']); + readonly allJustifications = toSignal(this._justificationService.all$); + readonly technicalName = computed(() => { + if (this.data.justification) { + return this.data.justification.technicalName; + } + if (!this.name()) { + return null; + } + let currentTechnicalName = Justification.toTechnicalName(this.name()); + const existingTechnicalNames = untracked(this.allJustifications).map(justification => justification.technicalName); + let suffix = 1; + while (existingTechnicalNames.includes(currentTechnicalName)) { + currentTechnicalName = + currentTechnicalName === '_' ? `${currentTechnicalName}${suffix++}` : [currentTechnicalName, suffix++].join('_'); + } + return currentTechnicalName; + }); + constructor( private readonly _justificationService: JustificationsService, protected readonly _dialogRef: MatDialogRef, @@ -26,7 +48,6 @@ export class AddEditJustificationDialogComponent extends BaseDialogComponent { ) { super(_dialogRef, !!data.justification); - this.form = this._getForm(); this.initialFormValue = this.form.getRawValue(); } @@ -34,7 +55,8 @@ export class AddEditJustificationDialogComponent extends BaseDialogComponent { const dossierTemplateId = this.data.dossierTemplateId; this._loadingService.start(); try { - await firstValueFrom(this._justificationService.createOrUpdate(this.form.getRawValue() as Justification, dossierTemplateId)); + const formValue = { ...this.form.getRawValue(), technicalName: this.technicalName() }; + await firstValueFrom(this._justificationService.createOrUpdate(formValue as Justification, dossierTemplateId)); await firstValueFrom(this._justificationService.loadAll(dossierTemplateId)); this._dialogRef.close(true); } catch (error) { @@ -43,11 +65,12 @@ export class AddEditJustificationDialogComponent extends BaseDialogComponent { this._loadingService.stop(); } - private _getForm(): UntypedFormGroup { + #getForm(): UntypedFormGroup { return this._formBuilder.group({ name: [{ value: this.data.justification?.name, disabled: !!this.data.justification }, Validators.required], reason: [this.data.justification?.reason, Validators.required], description: [this.data.justification?.description, Validators.required], + technicalName: [this.data.justification?.technicalName ?? null], }); } } diff --git a/apps/red-ui/src/app/utils/functions.ts b/apps/red-ui/src/app/utils/functions.ts index 50492e03c..ea763c79a 100644 --- a/apps/red-ui/src/app/utils/functions.ts +++ b/apps/red-ui/src/app/utils/functions.ts @@ -2,7 +2,7 @@ import { ITrackable } from '@iqser/common-ui'; import type { List } from '@iqser/common-ui/lib/utils'; import type { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { Dayjs } from 'dayjs'; -import { FormControl } from '@angular/forms'; +import { AbstractControl } from '@angular/forms'; import { toSignal } from '@angular/core/rxjs-interop'; export function hexToRgb(hex: string) { @@ -146,6 +146,6 @@ export function urlFileId() { return fileId.split('?')[0]; } -export function formControlToSignal(control: FormControl) { +export function formControlToSignal(control: AbstractControl) { return toSignal(control.valueChanges, { initialValue: control.value }); } diff --git a/libs/red-domain/src/lib/legal-basis/justification.model.ts b/libs/red-domain/src/lib/legal-basis/justification.model.ts index 50fcfa71c..9b4d4c7aa 100644 --- a/libs/red-domain/src/lib/legal-basis/justification.model.ts +++ b/libs/red-domain/src/lib/legal-basis/justification.model.ts @@ -1,15 +1,18 @@ import { IListable } from '@iqser/common-ui'; import { ILegalBasis } from './legal-basis'; +import { toSnakeCase } from '@utils/functions'; export class Justification implements ILegalBasis, IListable { readonly description?: string; readonly name: string; readonly reason?: string; + readonly technicalName?: string; constructor(justification: ILegalBasis) { this.description = justification.description; this.name = justification.name; this.reason = justification.reason; + this.technicalName = justification.technicalName; } get id(): string { @@ -19,4 +22,13 @@ export class Justification implements ILegalBasis, IListable { get searchKey(): string { return this.name; } + + static toTechnicalName(value: string) { + const baseTechnicalName = toSnakeCase(value.trim()); + let technicalName = baseTechnicalName.replaceAll(/[^A-Za-z0-9_-]/g, ''); + if (!technicalName.length && baseTechnicalName.length) { + technicalName = '_'; + } + return technicalName; + } } diff --git a/libs/red-domain/src/lib/legal-basis/legal-basis.ts b/libs/red-domain/src/lib/legal-basis/legal-basis.ts index 2e750f84d..d76cb86a5 100644 --- a/libs/red-domain/src/lib/legal-basis/legal-basis.ts +++ b/libs/red-domain/src/lib/legal-basis/legal-basis.ts @@ -2,4 +2,5 @@ export interface ILegalBasis { readonly name: string; readonly description?: string; readonly reason?: string; + readonly technicalName?: string; } From b244d1e4b457a7d4515a59f7f424cb22863b0870 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Tue, 22 Oct 2024 16:33:40 +0300 Subject: [PATCH 095/125] WIP on master RED-9944 - Action Items don't appear in document area in webviewer when bulk-select is still unintenionally active --- .../modules/file-preview/file-preview-screen.component.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts index ad3c9c902..86c838768 100644 --- a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts @@ -248,6 +248,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this._viewerHeaderService.enableLoadAllAnnotations(); // Reset the button state (since the viewer is reused between files) super.ngOnDetach(); this.pdf.instance.UI.hotkeys.off('esc'); + this.pdf.instance.UI.iframeWindow.document.removeEventListener('click', this.handleViewerClick); this._changeRef.markForCheck(); } @@ -283,7 +284,10 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this._ngZone.run(() => { if (this._multiSelectService.active()) { const clickedElement = event.target as HTMLElement; - if (clickedElement.querySelector('#selectionrect')) { + if ( + clickedElement.querySelector('#selectionrect') || + clickedElement.id === `pageWidgetContainer${this.pdf.currentPage()}` + ) { if (!this._annotationManager.selected.length) { this._multiSelectService.deactivate(); } @@ -324,6 +328,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this.#restoreOldFilters(); this.pdf.instance.UI.hotkeys.on('esc', this.handleEscInsideViewer); this._viewerHeaderService.resetLayers(); + this.pdf.instance.UI.iframeWindow.document.removeEventListener('click', this.handleViewerClick); this.pdf.instance.UI.iframeWindow.document.addEventListener('click', this.handleViewerClick); } From 3515b9a94237e5aa7019d6b0132cd65242e67d0c Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Tue, 22 Oct 2024 17:20:37 +0300 Subject: [PATCH 096/125] RED-7340 - red border around the page input field should only appear after the user has finished entering the page range --- libs/common-ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/common-ui b/libs/common-ui index a5d10ad14..d7ad450ca 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit a5d10ad1482a69f100f659bcf2b7f2072a6241c9 +Subproject commit d7ad450ca17a814f63adb631016a034a3a4f4552 From 5dd75f836cb927ecb63c34a67b650f81001e6f3b Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Tue, 22 Oct 2024 17:40:37 +0300 Subject: [PATCH 097/125] RED-10220: description and legalBasis fields are no longer required. --- .../add-edit-justification-dialog.component.html | 4 ++-- .../add-edit-justification-dialog.component.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/screens/justifications/add-edit-justification-dialog/add-edit-justification-dialog.component.html b/apps/red-ui/src/app/modules/admin/screens/justifications/add-edit-justification-dialog/add-edit-justification-dialog.component.html index a8aedc290..a24acc61c 100644 --- a/apps/red-ui/src/app/modules/admin/screens/justifications/add-edit-justification-dialog/add-edit-justification-dialog.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/justifications/add-edit-justification-dialog/add-edit-justification-dialog.component.html @@ -27,7 +27,7 @@ >
-
+
-
+
diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.html index deeeb9113..64523c836 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.html +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.html @@ -2,7 +2,7 @@
-
+
- +
diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.scss b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.scss index f441afc88..c383543e9 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.scss +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.scss @@ -3,8 +3,8 @@ } .dialog-content { - height: 610px; - overflow-y: auto; + height: 600px; + padding-top: 8px; } .apply-on-multiple-pages { From 61e9df1844e8d9a0df1e9155d5f55accbc6561b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kilian=20Sch=C3=BCttler?= Date: Thu, 24 Oct 2024 09:59:21 +0200 Subject: [PATCH 103/125] feature/RED-10260: add quoteChar to componentMapping --- ...add-edit-component-mapping-dialog.component.html | 9 +++++++++ .../add-edit-component-mapping-dialog.component.ts | 13 +++++++++---- .../component-mappings-screen.component.ts | 4 ++-- .../entity-services/component-mappings.service.ts | 1 + apps/red-ui/src/assets/i18n/redact/de.json | 8 +++++--- apps/red-ui/src/assets/i18n/redact/en.json | 8 +++++--- .../src/lib/component-mappings/component-mapping.ts | 3 +++ 7 files changed, 34 insertions(+), 12 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.html b/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.html index 8283e05a8..5fc1dd487 100644 --- a/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.html @@ -42,6 +42,15 @@ type="text" />
+
+ + +
diff --git a/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.ts b/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.ts index e8a628491..65ee0ac16 100644 --- a/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.ts @@ -17,12 +17,14 @@ interface DialogData { dossierTemplateId: string; mapping: IComponentMapping; } + interface DialogResult { id: string; name: string; file: Blob; encoding: string; delimiter: string; + quoteChar: string; fileName?: string; } @@ -72,14 +74,14 @@ export class AddEditComponentMappingDialogComponent const file = new Blob([fileContent.body as Blob], { type: 'text/csv' }); this.form.get('file').setValue(file); this.initialFormValue = this.form.getRawValue(); - this.#disableEncodingAndDelimiter(); + this.#disableEncodingAndQuoteCharAndDelimiter(); } } changeFile(file: File) { this.form.get('file').setValue(file); this.form.get('fileName').setValue(file?.name); - this.#enableEncodingAndDelimiter(); + this.#enableEncodingAndQuoteCharAndDelimiter(); } save() { @@ -93,16 +95,19 @@ export class AddEditComponentMappingDialogComponent fileName: [this.data?.mapping?.fileName, Validators.required], encoding: this.encodingTypeOptions.find(e => e === this.data?.mapping?.encoding) ?? this.encodingTypeOptions[0], delimiter: [this.data?.mapping?.delimiter ?? ',', Validators.required], + quoteChar: [this.data?.mapping?.quoteChar ?? '"', Validators.required], }); } - #disableEncodingAndDelimiter() { + #disableEncodingAndQuoteCharAndDelimiter() { this.form.get('encoding').disable(); this.form.get('delimiter').disable(); + this.form.get('quoteChar').disable(); } - #enableEncodingAndDelimiter() { + #enableEncodingAndQuoteCharAndDelimiter() { this.form.get('encoding').enable(); this.form.get('delimiter').enable(); + this.form.get('quoteChar').enable(); } } diff --git a/apps/red-ui/src/app/modules/admin/screens/component-mappings/component-mappings-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/component-mappings/component-mappings-screen.component.ts index b451d54b3..997aefcc2 100644 --- a/apps/red-ui/src/app/modules/admin/screens/component-mappings/component-mappings-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/component-mappings/component-mappings-screen.component.ts @@ -99,8 +99,8 @@ export default class ComponentMappingsScreenComponent extends ListingComponent Date: Fri, 25 Oct 2024 12:31:51 +0200 Subject: [PATCH 104/125] RED-9447 && RED-10244 --- .../edit-dossier-general-info.component.html | 18 +- .../edit-dossier-general-info.component.ts | 242 +++++++++++++----- .../dossier-templates.service.ts | 7 + 3 files changed, 191 insertions(+), 76 deletions(-) diff --git a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.html b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.html index bbd9d8aa2..86a398e69 100644 --- a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.html +++ b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.html @@ -44,11 +44,15 @@
- - -
- -
{{ getStateName(stateId) }}
+ + +
+ +
{{ stateNameAndColor()[stateId]?.name }}
@@ -80,7 +84,7 @@
(); hasDueDate: boolean; dossierTemplates: IDossierTemplate[]; - states: string[]; + form: FormGroup> = this._formBuilder.group({ + dossierName: [null, Validators.required], + dossierTemplateId: [null, Validators.required], + dossierStatusId: [null], + description: [null], + dueDate: [null], + }); + initialFormValue: GeneralInfoForm; + readonly dossierStatusIdControl = formControlToSignal(this.form.controls.dossierStatusId); + readonly dossierTemplateIdControl = formControlToSignal(this.form.controls.dossierTemplateId); + readonly states = signal([null]); + readonly stateNameAndColor = computed(() => { + const nameAndColor = {}; + this.states().forEach(stateId => { + nameAndColor[stateId] = { + name: this.#getStateName(stateId, untracked(this.dossierTemplateIdControl)), + color: this.#getStateColor(stateId, untracked(this.dossierTemplateIdControl)), + }; + }); + return nameAndColor; + }); + readonly statePlaceholder = computed(() => this.#statePlaceholder); constructor( readonly permissionsService: PermissionsService, @@ -87,18 +115,36 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti private readonly _loadingService: LoadingService, private readonly _translateService: TranslateService, private readonly _archivedDossiersService: ArchivedDossiersService, - ) {} + private readonly _changeDetectorRef: ChangeDetectorRef, + private readonly _dossierStatesService: DossierStatesService, + ) { + effect(() => { + if (this.dossierStatusIdControl() !== this.initialFormValue.dossierStatusId && this.dossierStatusIdControl()) { + this.form.controls.dossierTemplateId.disable(); + } else { + this.form.controls.dossierTemplateId.enable(); + } + }); + + effect( + () => { + this.states.set(this.#statesForDossierTemplate); + this.#onDossierTemplateChange(); + }, + { allowSignalWrites: true }, + ); + } get changed(): boolean { for (const key of Object.keys(this.form.getRawValue())) { if (key === 'dueDate') { - if (this.hasDueDate !== !!this.dossier.dueDate) { + if (this.hasDueDate !== !!this.dossier().dueDate) { return true; } - if (this.hasDueDate && !dayjs(this.dossier.dueDate).isSame(dayjs(this.form.get(key).value), 'day')) { + if (this.hasDueDate && !dayjs(this.dossier().dueDate).isSame(dayjs(this.form.get(key).value), 'day')) { return true; } - } else if (this.dossier[key] !== this.form.get(key).value) { + } else if (this.dossier()[key] !== this.form.get(key).value) { return true; } } @@ -114,40 +160,89 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti return this.hasDueDate && this.form.get('dueDate').value === null; } - get #statusPlaceholder(): string { + get #statePlaceholder(): string { return this._translateService.instant( - this.states.length === 1 + isJustOne(this.states()) ? 'edit-dossier-dialog.general-info.form.dossier-state.no-state-placeholder' : 'dossier-state.placeholder', ) as string; } + get #statesForDossierTemplate() { + return [ + null, + ...this._dossierStatesMapService + .get(this.dossierTemplateIdControl() ?? untracked(this.dossier).dossierTemplateId) + .map(s => s.id), + ]; + } + + get #formValue(): { key: string; value: string; disabled: boolean }[] { + const dossier = untracked(this.dossier); + const formFieldWithArchivedCheck = value => ({ value, disabled: !dossier.isActive }); + const dossierStateId = untracked(this.dossierStatusIdControl); + const states = untracked(this.states); + return [ + { + key: 'dossierName', + ...formFieldWithArchivedCheck(dossier.dossierName), + }, + { + key: 'dossierTemplateId', + value: dossier.dossierTemplateId, + disabled: this._dossierStatsService.get(dossier.id).hasFiles || !dossier.isActive || !!dossierStateId, + }, + { + key: 'dossierStatusId', + value: dossier.dossierStatusId, + disabled: isJustOne(states) || !dossier.isActive, + }, + { + key: 'description', + ...formFieldWithArchivedCheck(dossier.description), + }, + { + key: 'dueDate', + ...formFieldWithArchivedCheck(dossier.dueDate), + }, + ]; + } + ngOnInit() { - this.states = [null, ...this._dossierStatesMapService.get(this.dossier.dossierTemplateId).map(s => s.id)]; - this.statusPlaceholder = this.#statusPlaceholder; - this.#filterInvalidDossierTemplates(); - this.form = this.#getForm(); - if (!this.permissionsService.canEditDossier(this.dossier)) { + this.#patchFormValue(); + if (isJustOne(this._dossierTemplatesService.all)) { + this._loadingService.loadWhile( + firstValueFrom(this._dossierTemplatesService.loadOnlyDossierTemplates()).then(async () => { + await firstValueFrom(this._dossierStatesService.loadAllForAllTemplates()); + this.#filterInvalidDossierTemplates(); + }), + ); + } else { + this.#filterInvalidDossierTemplates(); + } + + if (!this.permissionsService.canEditDossier(this.dossier())) { this.form.disable(); } - this.hasDueDate = !!this.dossier.dueDate; + this.hasDueDate = !!this.dossier().dueDate; } revert() { this.form.reset({ - dossierName: this.dossier.dossierName, - dossierTemplateId: this.dossier.dossierTemplateId, - dossierStatusId: this.dossier.dossierStatusId, - description: this.dossier.description, - dueDate: this.dossier.dueDate, + dossierName: this.dossier().dossierName, + dossierTemplateId: this.dossier().dossierTemplateId, + dossierStatusId: this.dossier().dossierStatusId, + description: this.dossier().description, + dueDate: this.dossier().dueDate, }); - this.hasDueDate = !!this.dossier.dueDate; + this.hasDueDate = !!this.dossier().dueDate; + this.initialFormValue = this.form.getRawValue(); } async save(): EditDossierSaveResult { const dueDate = dateWithoutTime(dayjs(this.form.get('dueDate').value)); const dossier = { - ...this.dossier, + ...this.dossier(), dossierName: this.form.get('dossierName').value, description: this.form.get('description').value, dueDate: dueDate.isValid() ? dueDate.toISOString() : undefined, @@ -156,9 +251,10 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti } as IDossierRequest; const updatedDossier = await firstValueFrom(this._dossiersService.createOrUpdate(dossier)); - if (updatedDossier && updatedDossier.dossierTemplateId !== this.dossier.dossierTemplateId) { + if (updatedDossier && updatedDossier.dossierTemplateId !== this.dossier().dossierTemplateId) { await this._router.navigate([updatedDossier.routerLink]); } + this.initialFormValue = this.form.getRawValue(); return { success: !!updatedDossier }; } @@ -171,14 +267,14 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti requireInput: true, denyText: _('confirmation-dialog.delete-dossier.deny-text'), translateParams: { - dossierName: this.dossier.dossierName, + dossierName: this.dossier().dossierName, dossiersCount: 1, }, }; this._dialogService.openDialog('confirm', data, async () => { this._loadingService.start(); - const successful = await this._trashService.deleteDossier(this.dossier); + const successful = await this._trashService.deleteDossier(this.dossier()); if (successful) { await this.#closeDialogAndRedirectToDossier(); } @@ -194,7 +290,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti confirmationText: _('confirm-archive-dossier.archive'), denyText: _('confirm-archive-dossier.cancel'), titleColor: TitleColors.WARN, - translateParams: { ...this.dossier }, + translateParams: { ...this.dossier() }, checkboxes: [{ value: false, label: _('confirm-archive-dossier.checkbox.documents') }], toastMessage: _('confirm-archive-dossier.toast-error'), }; @@ -202,10 +298,10 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti this._dialogService.openDialog('confirm', data, async result => { if (result === ConfirmOptions.CONFIRM) { this._loadingService.start(); - await firstValueFrom(this._archivedDossiersService.archive([this.dossier])); + await firstValueFrom(this._archivedDossiersService.archive([this.dossier()])); this._toaster.success(_('dossier-listing.archive.archive-succeeded'), { params: { - dossierName: this.dossier.dossierName, + dossierName: this.dossier().dossierName, }, }); this._editDossierDialogRef.close(); @@ -214,15 +310,6 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti }); } - getStateName(stateId: string): string { - return (this._dossierStatesMapService.get(this.dossier.dossierTemplateId, stateId)?.name || - this._translateService.instant('dossier-state.placeholder')) as string; - } - - getStateColor(stateId: string): string { - return this._dossierStatesMapService.get(this.dossier.dossierTemplateId, stateId).color; - } - toggleDueDateField() { this.hasDueDate = !this.hasDueDate; if (!this.hasDueDate) { @@ -230,46 +317,63 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti } } + #getStateName(stateId: string, templateId: string): string { + return (this._dossierStatesMapService.get(templateId, stateId)?.name || + this._translateService.instant('dossier-state.placeholder')) as string; + } + + #getStateColor(stateId: string, templateId: string): string { + return this._dossierStatesMapService.get(templateId, stateId)?.color; + } + + #patchFormValue() { + this.#formValue.forEach(formValue => { + this.form.patchValue({ [formValue.key]: formValue.value }); + if (formValue.disabled) this.form.get(formValue.key).disable(); + }); + this.initialFormValue = this.form.getRawValue(); + } + async #closeDialogAndRedirectToDossier() { this._editDossierDialogRef.close(); - await this._router.navigate([this.dossier.dossiersListRouterLink]); + await this._router.navigate([this.dossier().dossiersListRouterLink]); this._toaster.success(_('edit-dossier-dialog.delete-successful'), { params: { - dossierName: this.dossier.dossierName, + dossierName: this.dossier().dossierName, }, }); } - #getForm(): UntypedFormGroup { - const formFieldWithArchivedCheck = value => ({ value, disabled: !this.dossier.isActive }); - return this._formBuilder.group({ - dossierName: [formFieldWithArchivedCheck(this.dossier.dossierName), Validators.required], - dossierTemplateId: [ - { - value: this.dossier.dossierTemplateId, - disabled: this._dossierStatsService.get(this.dossier.id).hasFiles || !this.dossier.isActive, - }, - Validators.required, - ], - dossierStatusId: [ - { - value: this.dossier.dossierStatusId, - disabled: this.states.length === 1 || !this.dossier.isActive, - }, - ], - description: [formFieldWithArchivedCheck(this.dossier.description)], - dueDate: [formFieldWithArchivedCheck(this.dossier.dueDate)], - }); - } - #filterInvalidDossierTemplates() { + const dossier = untracked(this.dossier); this.dossierTemplates = this._dossierTemplatesService.all.filter(r => { - if (this.dossier?.dossierTemplateId === r.dossierTemplateId) { + if (dossier.dossierTemplateId === r.dossierTemplateId) { return true; } const notYetValid = !!r.validFrom && dayjs(r.validFrom).isAfter(dayjs()); const notValidAnymore = !!r.validTo && dayjs(r.validTo).add(1, 'd').isBefore(dayjs()); + this._changeDetectorRef.markForCheck(); return !(notYetValid || notValidAnymore) && r.isActive; }); } + + #onDossierTemplateChange() { + const dossierStateId = untracked(this.dossierStatusIdControl); + const dossierTemplateId = untracked(this.dossierTemplateIdControl); + if (!!dossierStateId && dossierTemplateId !== this.initialFormValue.dossierTemplateId) { + this.form.controls.dossierStatusId.setValue(null); + } + const dossier = untracked(this.dossier); + if (dossierTemplateId === this.initialFormValue.dossierTemplateId) { + this.form.controls.dossierStatusId.setValue(dossier.dossierStatusId); + } + const states = untracked(this.states); + if (isJustOne(states) || !dossier.isActive) { + this.form.controls.dossierStatusId.disable(); + } else { + this.form.controls.dossierStatusId.enable(); + } + + this._changeDetectorRef.markForCheck(); + } } diff --git a/apps/red-ui/src/app/services/dossier-templates/dossier-templates.service.ts b/apps/red-ui/src/app/services/dossier-templates/dossier-templates.service.ts index fa79a0d16..2283d410b 100644 --- a/apps/red-ui/src/app/services/dossier-templates/dossier-templates.service.ts +++ b/apps/red-ui/src/app/services/dossier-templates/dossier-templates.service.ts @@ -45,6 +45,13 @@ export class DossierTemplatesService extends EntitiesService { + return this.getAll().pipe( + mapEach(entity => new DossierTemplate(entity)), + tap(templates => this.setEntities(templates)), + ); + } + loadDossierTemplate(dossierTemplateId: string) { return this._getOne([dossierTemplateId], this._defaultModelPath).pipe( map(entity => new DossierTemplate(entity)), From 3a5a91f1e12e3bae202bb7a258699ff6729eafef Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Fri, 25 Oct 2024 14:34:26 +0300 Subject: [PATCH 105/125] RED-3800: manual localazy sync. --- apps/red-ui/src/assets/i18n/redact/de.json | 36 +- apps/red-ui/src/assets/i18n/redact/en.json | 30 +- apps/red-ui/src/assets/i18n/scm/de.json | 402 ++++++++++----------- apps/red-ui/src/assets/i18n/scm/en.json | 74 ++-- 4 files changed, 271 insertions(+), 271 deletions(-) diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index 4713bb576..7f446c353 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -102,14 +102,14 @@ }, "disabled-file-options": "", "form": { - "quote-char": "Zitatzeichen", - "quote-char-placeholder": "\"", - "delimiter": "Trennzeichen", - "delimiter-placeholder": ",", - "encoding-type": "Codierung", + "delimiter": "", + "delimiter-placeholder": "", + "encoding-type": "", "file": "Mapping-Datei", "name": "Mapping-Name", "name-placeholder": "Mapping-Name", + "quote-char": "Quotation marker", + "quote-char-placeholder": "\"", "version": "Version" } }, @@ -1238,9 +1238,9 @@ "title": "{label} bearbeiten" }, "entries-count": "{count} {count, plural, one{Eintrag} other{Einträge}}", - "false-positives": "Falsch-Positive", - "false-recommendations": "Falsche Empfehlungen", - "to-redact": "Schwärzungen" + "false-positives": "Falsch-Positive ({count})", + "false-recommendations": "Falsche Empfehlungen ({count})", + "to-redact": "Schwärzungen ({count})" }, "general-info": { "form": { @@ -1280,11 +1280,11 @@ "content": { "options": { "multiple-pages": { - "description": "Schwärzung auf folgenden Seiten bearbeiten", + "description": "Bearbeiten Sie die Schwärzung auf einer Reihe von Seiten", "extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.", - "extraOptionLabel": "Seitenbereich", + "extraOptionLabel": "Seiten", "extraOptionPlaceholder": "z. B. 1-20,22,32", - "label": "Auf allen Seiten ändern" + "label": "Auf mehreren Seiten ändern" }, "only-this-page": { "description": "Schwärzung nur an dieser Position in diesem Dokument bearbeiten", @@ -1891,9 +1891,9 @@ "legalBasis": "Rechtsgrundlage", "options": { "multiple-pages": { - "description": "Schwärzung auf folgenden Seiten hinzufügen", + "description": "Fügen Sie die Schwärzung auf einer Reihe von Seiten hinzu", "extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.", - "extraOptionLabel": "Seitenbereich", + "extraOptionLabel": "Seiten", "extraOptionPlaceholder": "z. B. 1-20,22,32", "label": "Auf mehreren Seiten anwenden" }, @@ -2186,11 +2186,11 @@ "content": { "options": { "multiple-pages": { - "description": "Schwärzung auf folgenden Seiten entfernen", + "description": "Entfernen Sie die Schwärzung auf einer Reihe von Seiten", "extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.", - "extraOptionLabel": "Seitenbereich", + "extraOptionLabel": "Seiten", "extraOptionPlaceholder": "z. B. 1-20,22,32", - "label": "Auf allen Seiten entfernen" + "label": "Auf mehreren Seiten entfernen" }, "only-this-page": { "description": "Schwärzung nur an dieser Stelle in diesem Dokument entfernen", @@ -2224,7 +2224,7 @@ "label": "In diesem Kontext aus Dossier entfernen" }, "in-document": { - "description": "{isImage, select, image{Das Bild} other{der Begriff}} wird auf keiner Seite dieses Dokuments automatisch geschwärzt.", + "description": "{isImage, select, image{Das Bild} other{Der Begriff}} wird auf keiner Seite dieses Dokuments automatisch geschwärzt.", "label": "Aus Dokument entfernen" }, "in-dossier": { @@ -2642,7 +2642,7 @@ "table-header": { "title": "Wasserzeichen" }, - "watermark-is-used": "Dieses Wasserzeichen wird bereits verwendet. Möchten Sie es dennocht löschen?" + "watermark-is-used": "Dieses Wasserzeichen wird bereits verwendet. Möchten Sie es dennoch löschen?" }, "workflow": { "selection": { diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index 8c9615cb3..a63802082 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -104,9 +104,9 @@ "form": { "quote-char": "Quotation marker", "quote-char-placeholder": "\"", - "delimiter": "Delimiter", - "delimiter-placeholder": ",", - "encoding-type": "Encoding", + "delimiter": "", + "delimiter-placeholder": "", + "encoding-type": "", "file": "Mapping file", "name": "Mapping name", "name-placeholder": "Mapping name", @@ -1062,7 +1062,7 @@ "dossier-states": "{count, plural, one{Dossier state} other{Dossier states}}" }, "error": { - "conflict": "Dossier state with this name already exists" + "conflict": "Dossier state with this name already exists." }, "no-data": { "title": "There are no dossier states." @@ -1238,9 +1238,9 @@ "title": "Edit {label}" }, "entries-count": "{count} {count, plural, one{entry} other{entries}}", - "false-positives": "False positives", - "false-recommendations": "False recommendations", - "to-redact": "To redact" + "false-positives": "False positives ({count})", + "false-recommendations": "False recommendations ({count})", + "to-redact": "To redact ({count})" }, "general-info": { "form": { @@ -1280,11 +1280,11 @@ "content": { "options": { "multiple-pages": { - "description": "Edit redaction on following range of pages", + "description": "Edit redaction on a range of pages", "extraOptionDescription": "Minus(-) for range and comma(,) for enumeration", - "extraOptionLabel": "Range", + "extraOptionLabel": "Pages", "extraOptionPlaceholder": "e.g. 1-20,22,32", - "label": "Change on all pages" + "label": "Change on multiple pages" }, "only-this-page": { "description": "Edit redaction only at this position in this document", @@ -1891,9 +1891,9 @@ "legalBasis": "Legal basis", "options": { "multiple-pages": { - "description": "Add redaction on following range of pages", + "description": "Add redaction on a range of pages", "extraOptionDescription": "Minus(-) for range and comma(,) for enumeration", - "extraOptionLabel": "Range", + "extraOptionLabel": "Pages", "extraOptionPlaceholder": "e.g. 1-20,22,32", "label": "Apply on multiple pages" }, @@ -2186,11 +2186,11 @@ "content": { "options": { "multiple-pages": { - "description": "Remove redaction on following range of pages", + "description": "Remove redaction on a range of pages", "extraOptionDescription": "Minus(-) for range and comma(,) for enumeration", - "extraOptionLabel": "Range", + "extraOptionLabel": "Pages", "extraOptionPlaceholder": "e.g. 1-20,22,32", - "label": "Remove on all pages" + "label": "Remove on multiple pages" }, "only-this-page": { "description": "Remove redaction only at this position in this document", diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index d71a1ea28..bdcc10b71 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -100,7 +100,7 @@ "dialog": { "title": "{type, select, add{Neues Komponenten-Mapping erstellen} edit{Komponenten-Mapping bearbeiten} other{}}" }, - "disabled-file-options": "Re-upload mapping file to change", + "disabled-file-options": "Aktualisierte Mapping-Datei hochladen", "form": { "delimiter": "CSV-Trennzeichen", "delimiter-placeholder": "CSV-Trennzeichen", @@ -135,9 +135,9 @@ }, "add-edit-entity": { "form": { - "ai-creation-enabled": "Enable AI creation", - "ai-description": "AI Description", - "ai-description-placeholder": "Enter AI description", + "ai-creation-enabled": "KI-Erstellung aktivieren", + "ai-description": "KI-Beschreibung", + "ai-description-placeholder": "KI-Beschreibung eingeben", "case-sensitive": "Groß-/Kleinschreibung beachten", "color": "Farbe {type, select, redaction{Annotation} hint{Hinweis} recommendation{Empfehlung} skipped{Übersprungene Annotation} ignored{Ignorierter Hinweis} other{}}", "color-placeholder": "#", @@ -244,7 +244,7 @@ }, "type": "Typ", "type-placeholder": "Typ auswählen...", - "value": "Value" + "value": "Wert\n" }, "title": "Hinweis hinzufügen" } @@ -287,14 +287,14 @@ "label": "Ausgewählte Markierungen konvertieren" }, "edit-redaction": { - "label": "Edit" + "label": "Bearbeiten" }, "force-hint": { "label": "Hinweis erzwingen" }, "force-redaction": { "label": "Schwärzung erzwingen", - "label-image-hint": "Redact" + "label-image-hint": "Schwärzen" }, "hide": "Ausblenden", "message": { @@ -364,7 +364,7 @@ "label": "Größenänderung abbrechen" }, "see-references": { - "label": "See references" + "label": "Referenzen anzeigen" }, "show": "Zeigen", "undo": "Rückgängig" @@ -379,7 +379,7 @@ "removed-manual": "Schwärzung/Hinweis entfernt", "resized": "Schwärzungsbereich wurde geändert" }, - "annotation-content": "{hasRule, select, true {Rule {matchedRule} matched{ruleSymbol}} other {}} {hasReason, select, true {{reason}} other {}} {hasLb, select, true {Legal basis: {legalBasis}} other {}} {hasOverride, select, true {Removed by manual override} other {}} {hasSection, select, true {{shouldLower, plural, =0 {I} other {i}}n section{sectionSymbol} \"{section}\"} other {}}", + "annotation-content": "{hasRule, select, true {Rule {matchedRule} trifft zu:{ruleSymbol}} other {}} {hasReason, select, true {{reason}} other {}} {hasLb, select, true {Legal basis: {legalBasis}} other {}} {hasOverride, select, true {Removed by manual override} other {}} {hasSection, select, true {{shouldLower, plural, =0 {I} other {i}}n Abschnitt{sectionSymbol} \"{section}\"} other {}}", "annotation-engines": { "dictionary": "{isHint, select, true{Hinweis} other{Schwärzung}} basiert auf Wörterbuch", "dossier-dictionary": "Annotation basiert auf Dossier-Wörterbuch", @@ -933,7 +933,7 @@ "total-people": "Anzahl der Benutzer" }, "table-col-names": { - "documents-status": "Documents state", + "documents-status": "Dokumentenstatus", "dossier-state": "Dossier-Status", "last-modified": "Letzte Änderung", "name": "Name", @@ -950,7 +950,7 @@ "assign-approver": "Genehmiger zuordnen", "assign-me": "Mir zuweisen", "assign-reviewer": "Benutzer zuweisen", - "back-to-new": "Move to 'New'", + "back-to-new": "Nach \"Neu\" verschieben", "bulk": { "delete": "Dokumente löschen", "reanalyse": "Dokumente analysieren" @@ -966,22 +966,22 @@ }, "charts": { "documents-in-dossier": "Dokumente", - "pages-in-dossier": "Pages" + "pages-in-dossier": "Seiten" }, "description": "Beschreibung", "dictionary": "Dossier-Wörterbuch", "stats": { - "analysed-pages": "{count} {count, plural, one{page} other{pages}}", + "analysed-pages": "{count} {count, plural, one{Seite} other{Seiten}}", "created-on": "Erstellt am {date}", "deleted": "{count} gelöschte Dateien", - "documents": "{count} {count, plural, one{document} other{documents}}", + "documents": "{count} {count, plural, one{Seite} other{Seiten}}", "due-date": "Fällig am {date}", - "people": "{count} {count, plural, one{user} other{users}}", - "processing-documents": "{count} processing {count, plural, one{document} other{documents}}" + "people": "{count} {count, plural, one{Benutzer} other{Benutzer}}", + "processing-documents": "{count} {count, plural, one{Dokument} other{Dokumente}} in Verarbeitung" } }, "download-file": "Herunterladen", - "download-file-disabled": "You need to be approver in the dossier and the {count, plural, one{file needs} other{files need}} to be initially processed in order to download.", + "download-file-disabled": "Download: Sie müssen Genehmiger im Dossier sein und die initiale Verarbeitung {count, plural, one{der Datei} other{der Dateien}} muss abgeschlossen sein.", "file-listing": { "file-entry": { "file-error": "Reanalyse erforderlich", @@ -997,7 +997,7 @@ "edit": "Dossier bearbeiten", "upload-document": "Dokument hochgeladen" }, - "import-redactions": "Import annotations", + "import-redactions": "Annotationen importieren", "new-rule": { "toast": { "actions": { @@ -1027,71 +1027,71 @@ "error": "Die Dateien konnten nicht für eine Reanalyse eingeplant werden. Bitte versuchen Sie es erneut.", "success": "Dateien für Reanalyse vorgesehen." }, - "report-download": "Report download", - "start-auto-analysis": "Enable auto-analysis", - "stop-auto-analysis": "Stop auto-analysis", + "report-download": "Bericht herunterladen", + "start-auto-analysis": "Auto-Analyse aktivieren", + "stop-auto-analysis": "Auto-Analyse anhalten", "table-col-names": { "added-on": "Hinzugefügt", "assigned-to": "Zugewiesen an", - "last-modified": "Last modified", + "last-modified": "Letzte Änderung", "name": "Name", "needs-work": "Arbeitsvorrat", "pages": "Seiten", "status": "Status" }, "table-header": { - "title": "{length} {length, plural, one{document} other{documents}}" + "title": "{length} {length, plural, one{Dokument} other{Dokumente}}" }, "under-approval": "Zur Genehmigung", "under-review": "In Review", "upload-files": "Sie können Dateien überall per Drag and Drop platzieren..." }, - "dossier-permissions": "Dossier permissions", + "dossier-permissions": "Dossier-Rechte", "dossier-state": { - "placeholder": "Undefined" + "placeholder": "NIcht definiert" }, "dossier-states-listing": { "action": { - "delete": "Delete state", - "edit": "Edit state" + "delete": "Status löschen", + "edit": "Status bearbeiten" }, - "add-new": "New state", + "add-new": "Neuer Status", "chart": { - "dossier-states": "{count, plural, one{Dossier state} other{Dossier states}}" + "dossier-states": "{count, plural, one{Dossier-Status} other{Dossier-Status}}" }, "error": { - "conflict": "Dossier state with this name already exists!" + "conflict": "Es gibt bereits einen Dossier-Status mit diesem Namen." }, "no-data": { - "title": "There are no dossier states." + "title": "Es wurde noch kein Dossier-Status angelegt." }, "no-match": { - "title": "No dossier states match your current filters." + "title": "Kein Dossier-Status entspricht den aktuell ausgewählten Filtern." }, - "search": "Search...", + "search": "Suche...", "table-col-names": { - "dossiers-count": "Dossiers count", + "dossiers-count": "Anzahl der Dossiers", "name": "Name", - "rank": "Rank" + "rank": "Rang" }, "table-header": { - "title": "{length} dossier {length, plural, one{state} other{states}}" + "title": "{length} {length, plural, one{Dossierstatus} other{Dossierstatus}}" } }, "dossier-template-info-screen": { - "created-by": "Created by", - "created-on": "Created on: {date}", - "entities": "{count} {count, plural, one{entity} other{entities}}", - "entries": "{count} {count, plural, one{entry} other{entries}}", - "modified-on": "Modified on: {date}", - "title": "Edit dossier template", - "valid-from": "Valid from: {date}", - "valid-to": "Valid to: {date}" + "created-by": "Ersteller", + "created-on": "Erstellt am {date}", + "entities": "{count} {count, plural, one{Entität} other{Entitäten}}", + "entries": "{count} {count, plural, one{Eintrag} other{Einträge}}", + "modified-on": "Geändert am {date}", + "title": "Dossier-Vorlage bearbeiten", + "valid-from": "Gültig ab: {date}", + "valid-to": "Gültig bis: {date}" }, "dossier-template-stats": { - "active-dossiers": "Active {count, plural, one{dossier} other{dossiers}}", - "analyzed-pages": "{count} {count, plural, one{page} other {pages}} analyzed", - "archived-dossiers": "{count} {count, plural, one{dossier} other {dossiers}} in archive", + "active-dossiers": "{count, plural, one{Aktives Dossier} other{Aktive Dossiers}}", + "analyzed-pages": "{count} {count, plural, one{Seite} other {Seiten}} analysiert", + "archived-dossiers": "{count} {count, plural, one{Dossier} other {Dossiers}} im Archiv", "deleted-dossiers": "{count} {count, plural, one{dossier} other {dossiers}} in trash", "total-documents": "Anzahl der Dokumente", "total-people": "{count} {count, plural, one{user} other {users}}" @@ -1153,11 +1153,11 @@ "save": "Download" }, "form": { - "redaction-preview-color": "Redaction preview color", + "redaction-preview-color": "Vorschau-Farbe", "redaction-preview-color-placeholder": "#000000" }, - "header": "Download options", - "unapproved-files-warning": "This download contains unapproved file(s)." + "header": "Download-Optionen", + "unapproved-files-warning": "Dieser Download enthält Dateien, die noch nicht freigegeben sind." }, "download-includes": "Wählen Sie die Dokumente für Ihr Download-Paket aus", "download-status": { @@ -1235,10 +1235,10 @@ "save": "", "title": "" }, - "entries-count": "{count} {count, plural, one{entry} other{entries}}", - "false-positives": "False positives", - "false-recommendations": "False recommendations", - "to-redact": "To redact" + "entries-count": "{count} {count, plural, one{Eintrag} other{Einträge}}", + "false-positives": "Falsch-Positive ({count})", + "false-recommendations": "Falsche Empfehlungen ({count})", + "to-redact": "Schwärzungen ({count})" }, "general-info": { "form": { @@ -1247,8 +1247,8 @@ "placeholder": "Beschreibung eingeben" }, "dossier-state": { - "label": "Dossier state", - "no-state-placeholder": "This dossier template has no states" + "label": "Dossier-Status", + "no-state-placeholder": "Für dieses Dossier ist noch kein Status festgelegt" }, "due-date": "Termin", "name": { @@ -1259,7 +1259,7 @@ } }, "header": "{dossierName} bearbeiten", - "missing-owner": "You cannot edit the dossier because the owner is missing!", + "missing-owner": "Bearbeiten des Dossiers nicht möglich: Kein Besitzer zugewiesen.", "nav-items": { "choose-download": "Wählen Sie die Dokumente für Ihr Download-Paket aus:", "dictionary": "Wörterbuch", @@ -1295,12 +1295,12 @@ "edit-redaction": { "dialog": { "actions": { - "cancel": "Cancel", - "save": "Save changes" + "cancel": "Abbrechen", + "save": "Änderungen speichern" }, "content": { - "comment": "Comment", - "comment-placeholder": "Add remarks or mentions...", + "comment": "Kommentar", + "comment-placeholder": "Bemerkungen oder Notizen hinzufügen...", "legal-basis": "", "options": { "in-document": { @@ -1766,14 +1766,14 @@ "label": "Auf allen Seiten entfernen" }, "this-page": { - "description": "The earmarks in the selected HEX color will be removed only on the current page in view.", - "label": "Remove only on this page" + "description": "Die Markierungen in der ausgewählten HEX-Farbe werden nur auf der aktuell angezeigten Seite konvertiert.", + "label": "Nur auf dieser Seite entfernen" } }, - "save": "Remove earmarks", - "title": "Remove earmarks" + "save": "Markierungen entfernen", + "title": "Markierungen entfernen" }, - "success": "{operation, select, convert{Converting earmarks in progress...} delete{Successfully removed earmarks!} other{}} " + "success": "{operation, select, convert{Markierungen werden konvertiert...} delete{Markierungen erfolgreich entfernt.} other{}} " }, "highlights": "{color} - {length} {length, plural, one{earmark} other{earmarks}}", "image-category": { @@ -2206,48 +2206,48 @@ }, "content": { "comment": "Kommentar", - "comment-placeholder": "Add remarks or mentions...", + "comment-placeholder": "Bemerkungen oder Notizen hinzufügen...", "options": { "do-not-recommend": { - "description": "Do not recommend ''{value}'' as {type} in any document of the current dossier.", - "description-bulk": "Do not recommend the selected values as their respective types in any document of the current dossier.", - "extraOptionLabel": "Apply to all dossiers", - "label": "Remove from dossier" + "description": "Der Begriff soll in Dokumenten dieses Dossiers nicht zur Annotation empfohlen werden.", + "description-bulk": "Der Begriff soll in Dokumenten dieses Dossiers nicht zur Annotation empfohlen werden.", + "extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen", + "label": "Aus Dossier entfernen" }, "false-positive": { - "description": "''{value}'' is not a {type} in this context: ''{context}''.", + "description": "Markieren Sie die Annotation als falsch-positiv. Der Begriff wird in diesem Dossier nicht geschwärzt, wenn er im gleichen Kontext vorkommt.", "description-bulk": "", "extraOptionDescription": "", - "extraOptionLabel": "Apply to all dossiers", - "label": "False positive" + "extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen", + "label": "In diesem Kontext aus Dossier entfernen" }, "in-document": { "description": "", "label": "Aus Dokument entfernen" }, "in-dossier": { - "description": "Do not annotate the term in this dossier.", + "description": "Der Begriff wird in diesem Dossier nicht geschwärzt.", "description-bulk": "", - "extraOptionLabel": "Apply to all dossiers", - "label": "Remove from dossier", + "extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen", + "label": "Aus Dossier entfernen", "label-bulk": "" }, "only-here": { - "description": "Do not {type} ''{value}'' at this position in the current document.", - "description-bulk": "", - "label": "Remove here" + "description": "{type} '{value}'' wird an dieser Stelle nicht annotiert.", + "description-bulk": "Do not{type} ''{value}'' at this position in the current document.", + "label": "Hier entfernen" } } }, - "title": "Remove {type}", + "title": "Entferne {type}", "title-bulk": "" } }, "report-type": { - "label": "{length} report {length, plural, one{type} other{types}}" + "label": "{length} {length, plural, one{Berichtstyp} other{Berichtstypen}}" }, "reports-screen": { - "description": "Below, you will find a list of placeholders for dossier- and document-specific information. You can include these placeholders in your report templates.", + "description": "Die Liste unten enthält Platzhalter, die für dossier- und dokumentenspezifische Informationen stehen. Sie können diese in die Vorlagen für Ihre Berichte einbauen.", "descriptions": { "dossier-attributes": "Dieser Platzhalter wird durch den Wert des Dossier-Attributs {attribute} ersetzt.", "file-attributes": "Dieser Platzhalter wird durch den Wert des Dateiattributs {attribute} ersetzt.", @@ -2265,17 +2265,17 @@ }, "redaction": { "entity": { - "display-name": "This placeholder is replaced by the name of the entity the component is based on." + "display-name": "Dieser Platzhalter wird durch den Entitätsnamen ersetzt, auf der die Komponente basiert." }, "excerpt": "Dieser Platzhalter wird durch einen Textausschnitt ersetzt, der die Schwärzung enthält.", - "is-skipped": "The skipped redaction placeholder indicates whether a redaction is skipped or not. It can be included in a separate column of a template that also contains the '{{redaction.value'}} placeholder. The placeholder is replaced by “true” if the respective redaction is skipped, and by “false” if it is redacted (i. e., not skipped).", + "is-skipped": "Dieser Platzhalter gibt an, ob eine Schwärzung ignoriert wird oder nicht. Er kann in eine separate Spalte einer Vorlage eingebaut werden, die auch den Platzhalter '{{'redaction.value'}}' enthält. Der Platzhalter wird durch „true“ (wahr) ersetzt, wenn die entsprechende Schwärzung ignoriert ist, und durch „false“ (falsch), wenn sie nicht ignoriert (d. h. geschwärzt) ist.", "justification": "Dieser Platzhalter wird durch die Begründung der Schwärzung ersetzt. Es ist eine Kombination aus dem Rechtsverweis (justificationParagraph) und dem Begründungstext (justificationReason).", - "justification-legal-basis": "This placeholder is replaced by the legal basis for the component.", - "justification-paragraph": "Dieser Platzhalter wird durch den Rechtshinweis der Begründung der Redaktion ersetzt.", - "justification-reason": "Dieser Platzhalter wird durch den Begründungstext der Schwärzung ersetzt.", - "justification-text": "This placeholder is replaced by the justification text.", - "page": "Dieser Platzhalter wird durch die Seitenzahl der Redaktion ersetzt.", - "paragraph": "Dieser Platzhalter wird durch den Absatz ersetzt, der die Schwärzung enthält.", + "justification-legal-basis": "Dieser Platzhalter wird durch die Rechtsgrundlage der Komponente ersetzt.", + "justification-paragraph": "Dieser Platzhalter wird durch den Rechtshinweis der Begründung der Komponente ersetzt.", + "justification-reason": "Dieser Platzhalter wird durch den Begründungstext der Komponente ersetzt.", + "justification-text": "Dieser Platzhalter wird durch die Schwärzungsbegründung (Text) ersetzt.", + "page": "Dieser Platzhalter wird durch die Seitenzahl der Komponente ersetzt.", + "paragraph": "Dieser Platzhalter wird durch den Absatz ersetzt, der die Komponente enthält.", "paragraph-idx": "The placeholder is replaced by the number of the paragraph containing the redaction. Paragraphs are numbered on a per-page basis.", "value": "This placeholder is replaced by the value that was extracted." }, @@ -2287,7 +2287,7 @@ "invalid-upload": "Ungültiges Upload-Format ausgewählt! Unterstützt werden Dokumente im .xlsx- und im .docx-Format", "multi-file-report": "(Mehrere Dateien)", "report-documents": "Dokumente für den Bericht", - "setup": "Click the upload button on the right to upload your component report templates.", + "setup": "Dieser Platzhalter wird durch die Nummer der Seite ersetzt, auf der sich die Schwärzung befindet.", "table-header": { "description": "Beschreibung", "placeholders": "Platzhalter" @@ -2309,95 +2309,95 @@ "resize-annotation": { "dialog": { "actions": { - "cancel": "Cancel", - "save": "Save changes" + "cancel": "Abbrechen", + "save": "Änderungen speichern" }, "content": { - "comment": "Comment", - "original-text": "Original annotation:", - "resized-text": "Resized annotation:" + "comment": "Kommentar", + "original-text": "Originale Annotation:", + "resized-text": "Geändert zu: " }, - "header": "Resize annotation" + "header": "Größe der Annotation ändern" } }, "resize-redaction": { "dialog": { "actions": { - "cancel": "Cancel", - "save": "Save changes" + "cancel": "Abbrechen", + "save": "Änderungen speichern" }, "content": { - "comment": "Comment", + "comment": "Kommentar", "options": { "in-dossier": { - "description": "Resize in every document in {dossierName}.", - "extraOptionLabel": "Apply to all dossiers", - "label": "Resize in dossier", - "tooltip": "Only available for dictionary-based types" + "description": "Ändern Sie die Größe in jedem Dokument in {dossierName}.", + "extraOptionLabel": "In alle Dossiers übernehmen", + "label": "Größe im Dossier ändern", + "tooltip": "Nur bei wörterbuchbasierten Typen verfügbar" }, "only-here": { - "description": "Resize only at this position in this document.", - "label": "Resize only here" + "description": "Ändern Sie die Größe nur an dieser Stelle im Dokument.", + "label": "Größe nur hier ändern" } }, - "original-text": "Original text:", - "resized-text": "Resized text:", - "type": "Type" + "original-text": "Originaltext:", + "resized-text": "Geändert zu:", + "type": "Typ" }, - "header": "Resize {type}" + "header": "Größe von {type} ändern" } }, "revert-value-dialog": { "actions": { - "cancel": "Cancel", - "revert": "Revert to original values" + "cancel": "Abbrechen", + "revert": "Auf ursprüngliche Werte zurücksetzen" }, - "component-rule": "Component rule: ", - "current-values": "Current values", - "original-values": "Original values", - "title": "Revert to the original values?" + "component-rule": "Komponentenregel:", + "current-values": "Aktuelle Werte", + "original-values": "Ursprüngliche Werte", + "title": "Auf ursprüngliche Werte zurücksetzen?" }, "roles": { "inactive": "Inaktiv", - "manager-admin": "Manager & admin", + "manager-admin": "Manager & Admin", "no-role": "Keine Rolle definiert", - "red-admin": "Anwendungsadministrator", + "red-admin": "Anwendungsadmin", "red-manager": "Manager", "red-user": "Benutzer", - "red-user-admin": "Benutzer-Admin", - "regular": "Regulär" + "red-user-admin": "Benutzeradmin", + "regular": "regulärer Benutzer" }, "search": { - "active-dossiers": "ganze Plattform", - "all-dossiers": "all documents", - "placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen", - "this-dossier": "in diesem Dossier" + "active-dossiers": "Dokumente in aktiven Dossiers", + "all-dossiers": "Alle Dokumente", + "placeholder": "Dokumente durchsuchen...", + "this-dossier": "In diesem Dossier" }, "search-screen": { "cols": { - "assignee": "Bevollmächtigter", + "assignee": "Bearbeiter", "document": "Dokument", "dossier": "Dossier", "pages": "Seiten", "status": "Status" }, "filters": { - "assignee": "Assignee", - "by-dossier": "Nach Dossier filtern", - "by-template": "Dossier template", - "only-active": "Active dossiers only", - "search-by-template-placeholder": "Dossier template name...", + "assignee": "Bearbeiter", + "by-dossier": "Dossier", + "by-template": "Dossier-Vorlage", + "only-active": "Nur aktive Dossiers", + "search-by-template-placeholder": "Dossiernamen eingeben...", "search-placeholder": "Dossiername...", "status": "Status" }, "missing": "Fehlt", "must-contain": "Muss enthalten", - "no-data": "Geben Sie einen Suchbegriff in die Suchleiste, um nach Dokumenten oder Inhalten von Dokumenten zu suchen.", - "no-match": "Keine Dokumente entsprechen Ihren aktuellen Filtern.", - "table-header": "{length} search {length, plural, one{result} other{results}}" + "no-data": "Geben Sie einen Suchbegriff in die Suchleiste ein,
um Dokumente oder Inhalte zu suchen.", + "no-match": "Der Suchbegriff wurde in keinem der Dokumente gefunden.", + "table-header": "{length} {length, plural, one{Suchergebnis} other{Suchergebnisse}}" }, - "seconds": "seconds", - "size": "Size", + "seconds": "Sekunden", + "size": "Größe", "smtp-auth-config": { "actions": { "cancel": "Abbrechen", @@ -2411,48 +2411,48 @@ "title": "Authentifizierung aktivieren" }, "table-header": { - "selected-count": "{count} selected" + "selected-count": "{count} ausgewählt" }, "tenant-resolve": { - "contact-administrator": "Cannot remember the workspace? Please contact your administrator.", + "contact-administrator": "Workspace vergessen? Bitte wenden Sie sich an Ihren Administrator.", "header": { - "first-time": "Sign in for the first time to a workspace", - "join-another-domain": "Or join another workspace", - "no-role-log-out": "User role missing. Please ask your administrator to assign roles before logging in again.", - "sign-in-previous-domain": "Sign in to a previously used workspace", - "youre-logged-out": "You have successfully been logged out." + "first-time": "Melden Sie sich zum ersten Mal bei einem Workspace an", + "join-another-domain": "Oder treten Sie einem andren Workspace bei", + "no-role-log-out": "Keine Benutzerrolle zugewiesen. Bitten Sie Ihren Admin, Ihnen eine Rolle zuzuweisen, und versuchen Sie es dann noch einmal.", + "sign-in-previous-domain": "Melden Sie sich bei einem bereits verwendeten Workspace an", + "youre-logged-out": "Sie wurden erfolgreich abgemeldet." }, - "input-placeholder": "your workspace" + "input-placeholder": "Ihr Workspace" }, "time": { - "days": "{days} {days, plural, one{day} other{days}}", - "hours": "{hours} {hours, plural, one{hour} other{hours}}", + "days": "{days} {days, plural, one{Tag} other{Tage}}", + "hours": "{hours} {hours, plural, one{Stunde} other{Stunden}}", "less-than-an-hour": "< 1 Stunde", "no-time-left": "Frist für Wiederherstellung verstrichen" }, - "today": "Today", + "today": "Heute", "toggle-auto-analysis-message": { - "error": "Something went wrong.", - "success": "{toggleOperation} automatic processing." + "error": "Es ist ein Fehler aufgetreten.", + "success": "{toggleOperation} automatische Verarbeitung." }, "top-bar": { "navigation-items": { "back": "Zurück", - "back-to-dashboard": "Back to home", - "dashboard": "Home", + "back-to-dashboard": "Zurück zu Start", + "dashboard": "Start", "my-account": { "children": { "account": "Konto", "admin": "Einstellungen", "downloads": "Meine Downloads", - "join-another-tenant": "Join another workspace", + "join-another-tenant": "Anderem Workspace beitreten", "language": { "de": "Deutsch", "en": "Englisch", "label": "Sprache" }, "logout": "Abmelden", - "select-tenant": "Select Tenant", + "select-tenant": "Workspace wechseln", "trash": "Papierkorb" } } @@ -2469,7 +2469,7 @@ }, "label": "Papierkorb", "no-data": { - "title": "Es wurde noch kein Dossier angelegt." + "title": "Im Papierkorb befinden sich keine gelöschten Elemente." }, "no-match": { "title": "Die ausgewählten Filter treffen auf kein Dossier zu." @@ -2478,19 +2478,19 @@ "deleted-on": "Gelöscht am", "dossier": "Dossier", "name": "Name", - "owner": "Eigentümer", + "owner": "Besitzer/Bearbeiter", "time-to-restore": "Verbleibende Zeit für Wiederherstellung" }, "table-header": { - "title": "{length} deleted {length, plural, one{item} other{items}}" + "title": "{length} {length, plural, one{gelöschtes Dossier} other{gelöschte Dossiers}}" } }, "type": "Typ", "unknown": "Unbekannt", "update-profile": { "errors": { - "bad-request": "Error: {message}.", - "generic": "An error has occurred while updating the profile." + "bad-request": "Fehler: {message}.", + "generic": "Bei der Aktualisierung des Profils ist ein Fehler aufgetreten." } }, "upload-dictionary-dialog": { @@ -2499,11 +2499,11 @@ "merge": "Einträge zusammenführen", "overwrite": "Überschreiben" }, - "question": "Wählen Sie, wie Sie fortfahren möchten:", + "question": "Wie möchten Sie vorgehen?", "title": "Das Wörterbuch hat bereits Einträge!" }, "upload-file": { - "upload-area-text": "Click or drag & drop anywhere on this area..." + "upload-area-text": "Klicken Sie hier oder ziehen Sie die Datei in diesen Bereich..." }, "upload-status": { "dialog": { @@ -2515,8 +2515,8 @@ }, "error": { "file-size": "Datei zu groß. Die maximal zulässige Größe beträgt {size} MB.", - "file-type": "This file type is not accepted.", - "generic": "Fehler beim Hochladen des Dokuments. {error}" + "file-type": "Dateityp wird nicht unterstützt.", + "generic": "Aktualisierung der Datei fehlgeschlagen: {error}" } }, "user-listing": { @@ -2530,22 +2530,22 @@ "delete-disabled": "Sie können Ihr eigenes Konto nicht löschen." }, "no-match": { - "title": "Die ausgewählten Filter treffen auf keinen Benutzer zu." + "title": "Ausgewählte Filter treffen auf keinen Benutzer zu." }, "search": "Suche ...", "table-col-names": { "active": "Aktiv", "email": "E-Mail-Adresse", - "name": "Name", + "name": "Name\n", "roles": "Rollen" }, "table-header": { - "title": "{length} {length, plural, one{user} other{users}}" + "title": "{length} {length, plural, one{Benutzer} other{Benutzer}}" } }, "user-management": "Benutzerverwaltung", "user-menu": { - "button-text": "User menu" + "button-text": "Benutzermenü" }, "user-profile": "Mein Profil", "user-profile-screen": { @@ -2556,63 +2556,63 @@ "confirm-password": { "form": { "password": { - "label": "Password" + "label": "Passwort" } }, - "header": "Confirm your password", - "save": "Submit" + "header": "Passwort bestätigen", + "save": "Absenden" }, "form": { - "dark-theme": "Dark theme", - "email": "E-mail", + "dark-theme": "Nachtmodus", + "email": "E-Mail", "first-name": "Vorname", "last-name": "Nachname" }, "title": "Profil bearbeiten", "update": { - "success": "Successfully updated profile!" + "success": "Das Profil wurde erfolgreich aktualisiert." } }, "user-stats": { "chart": { - "users": "Benutzer im Arbeitsbereich" + "users": "Benutzer im Workspace" }, "collapse": "Details ausblenden", "expand": "Details anzeigen", "title": "Benutzer" }, "view-mode": { - "list": "Liste", + "list": "Dokumentenliste", "view-as": "Ansicht als:", - "workflow": "Arbeitsablauf" + "workflow": "Workflow-Spalten" }, "watermark-screen": { "action": { - "change-success": "Das Wasserzeichen wurde aktualisiert!", - "created-success": "Watermark has been created!", - "error": "Fehler beim Aktualisieren des Wasserzeichens", - "revert": "Rückgängig machen", + "change-success": "Wasserzeichen wurde aktualisiert.", + "created-success": "Wasserzeichen wurde erstellt.", + "error": "Aktualisierung des Wasserzeichens fehlgeschlagen.", + "revert": "Zurücksetzen", "save": "Änderungen speichern" }, "alignment": { - "align-bottom": "Align bottom", - "align-horizontal-centers": "Align horizontal centers", - "align-left": "Align left", - "align-right": "Align right", - "align-top": "Align top", - "align-vertical-centers": "Align vertical centers" + "align-bottom": "Unten", + "align-horizontal-centers": "Horizontal mittig", + "align-left": "Linksbündig", + "align-right": "Rechtsbündig", + "align-top": "Oben", + "align-vertical-centers": "Vertikal mittig" }, "form": { - "alignment": "Alignment", + "alignment": "Position", "color": "Farbe", "color-placeholder": "#", "font-size": "Schriftgröße", "font-type": "Schriftart", - "name-label": "Watermark name", - "name-placeholder": "Choose a name to identify the watermark", + "name-label": "Name des Wsserzeichens", + "name-placeholder": "Namen für Wasserzeichen eingeben", "opacity": "Deckkraft", - "orientation": "Ausrichtung", - "text-label": "Watermark text", + "orientation": "Textrichtung", + "text-label": "Text für Wasserzeichen", "text-placeholder": "Text eingeben" }, "pagination": { @@ -2622,32 +2622,32 @@ }, "watermarks-listing": { "action": { - "delete": "Delete", - "delete-success": "Watermark has been deleted!", - "edit": "Edit" + "delete": "Löschen", + "delete-success": "Das Wasserzeichen wurde gelöscht.", + "edit": "Bearbeiten" }, - "add-new": "New watermark", + "add-new": "Neues Wasserzeichen", "no-data": { - "title": "There are no watermarks yet." + "title": "Es wurde noch kein Wasserzeichen erstellt." }, "table-col-names": { - "created-by": "Created by", - "created-on": "Created on", - "modified-on": "Modified on", + "created-by": "Ersteller", + "created-on": "Erstellt am", + "modified-on": "Geändert am", "name": "Name", "status": "Status" }, "table-header": { - "title": "Watermarks" + "title": "Wasserzeichen" }, - "watermark-is-used": "This watermark is already in use, are you sure you want to delete it?" + "watermark-is-used": "Dieses Wasserzeichen wird bereits verwendet. Möchten Sie es dennoch löschen?" }, "workflow": { "selection": { "all": "Alle", "count": "{count} ausgewählt", "none": "Keiner", - "select": "Wählen" + "select": "Auswählen" } }, "yesterday": "Gestern" diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index 532ceadec..44997e9ca 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -18,7 +18,7 @@ }, "content": { "comment": "Comment", - "comment-placeholder": "Add remarks or mentions...", + "comment-placeholder": "Add remarks or notes...", "selected-text": "Selected text:", "type": "Type", "type-placeholder": "Select type..." @@ -100,7 +100,7 @@ "dialog": { "title": "{type, select, add{Add new} edit{Edit} other{}} component mapping" }, - "disabled-file-options": "Re-upload mapping file to change", + "disabled-file-options": "Upload updated mapping file", "form": { "delimiter": "CSV delimiter", "delimiter-placeholder": "CSV delimiter", @@ -230,11 +230,11 @@ }, "content": { "comment": "Comment", - "comment-placeholder": "Add remarks or mentions...", + "comment-placeholder": "Add remarks or notes...", "options": { "in-dossier": { "description": "Add hint in every document in {dossierName}.", - "extraOptionLabel": "Apply to all dossiers", + "extraOptionLabel": "Apply to all active and future dossiers", "label": "Add hint in dossier" }, "only-here": { @@ -981,7 +981,7 @@ } }, "download-file": "Download", - "download-file-disabled": "You need to be approver in the dossier and the {count, plural, one{file needs} other{files need}} to be initially processed in order to download.", + "download-file-disabled": "To download, ensure you are an approver in the dossier, and the {count, plural, one{file has undergone} other{files have undergone}} initial processing.", "file-listing": { "file-entry": { "file-error": "Re-processing required", @@ -1060,13 +1060,13 @@ "dossier-states": "{count, plural, one{Dossier state} other{Dossier states}}" }, "error": { - "conflict": "Dossier state with this name already exists!" + "conflict": "Dossier state with this name already exists." }, "no-data": { "title": "There are no dossier states." }, "no-match": { - "title": "No dossier states match your current filters." + "title": "No dossier state matches the currently selected filters." }, "search": "Search...", "table-col-names": { @@ -1153,7 +1153,7 @@ "save": "Download" }, "form": { - "redaction-preview-color": "Redaction preview color", + "redaction-preview-color": "Preview color", "redaction-preview-color-placeholder": "#000000" }, "header": "Download options", @@ -1236,9 +1236,9 @@ "title": "" }, "entries-count": "{count} {count, plural, one{entry} other{entries}}", - "false-positives": "False positives", - "false-recommendations": "False recommendations", - "to-redact": "To redact" + "false-positives": "False positives ({count})", + "false-recommendations": "False recommendations ({count})", + "to-redact": "To redact ({count})" }, "general-info": { "form": { @@ -1259,7 +1259,7 @@ } }, "header": "Edit {dossierName}", - "missing-owner": "You cannot edit the dossier because the owner is missing!", + "missing-owner": "Editing the dossier not possible: No owner assigned.", "nav-items": { "choose-download": "Choose what is included at download:", "dictionary": "Dictionary", @@ -1300,7 +1300,7 @@ }, "content": { "comment": "Comment", - "comment-placeholder": "Add remarks or mentions...", + "comment-placeholder": "Add remarks or notes...", "legal-basis": "", "options": { "in-document": { @@ -1745,7 +1745,7 @@ "label": "Convert on all pages" }, "this-page": { - "description": "The earmarks in the selected HEX color will be converted only on the current page in view.", + "description": "The earmarks in the selected HEX color will be converted only on the currently viewed page.", "label": "Convert only on this page" } }, @@ -2110,7 +2110,7 @@ }, "content": { "comment": "Comment", - "comment-placeholder": "Add remarks or mentions...", + "comment-placeholder": "Add remarks or notes...", "edit-text": "", "legal-basis": "Legal basis", "options": { @@ -2120,7 +2120,7 @@ }, "in-dossier": { "description": "Add redaction in every document in {dossierName}.", - "extraOptionLabel": "Apply to all dossiers", + "extraOptionLabel": "Apply to all active and future dossiers", "label": "Redact in dossier" }, "only-here": { @@ -2149,14 +2149,14 @@ }, "content": { "comment": "Comment", - "comment-placeholder": "Add remarks or mentions...", + "comment-placeholder": "Add remarks or notes...", "list-item": "{text}", "list-item-false-positive": "''{text}'' in the context: ''{context}''", "options": { "false-positive": { - "description": "''{value}'' is not a ''{type}'' in this context: ''{context}''.", + "description": "Mark this redaction as a false-positive. The term will not be redacted in this dossier if it occurs in the same context.", "description-bulk": "Mark this redaction as a false-positive. The term will not be redacted in this dossier if it occurs in the same context.", - "label": "False positive" + "label": "Remove from dossier in this context" }, "in-document": { "description": "", @@ -2206,20 +2206,20 @@ }, "content": { "comment": "Comment", - "comment-placeholder": "Add remarks or mentions...", + "comment-placeholder": "Add remarks or notes...", "options": { "do-not-recommend": { - "description": "Do not recommend ''{value}'' as {type} in any document of the current dossier.", + "description": "Do not recommend the selected term in any document of this dossier.", "description-bulk": "Do not recommend the selected values as their respective types in any document of the current dossier.", - "extraOptionLabel": "Apply to all dossiers", + "extraOptionLabel": "Apply to all active and future dossiers", "label": "Remove from dossier" }, "false-positive": { - "description": "''{value}'' is not a {type} in this context: ''{context}''.", + "description": "Mark this redaction as a false-positive. The term will not be redacted in this dossier if it occurs in the same context.", "description-bulk": "", "extraOptionDescription": "", - "extraOptionLabel": "Apply to all dossiers", - "label": "False positive" + "extraOptionLabel": "Apply to all active and future dossiers", + "label": "Remove from dossier in this context" }, "in-document": { "description": "", @@ -2228,13 +2228,13 @@ "in-dossier": { "description": "Do not annotate the term in this dossier.", "description-bulk": "", - "extraOptionLabel": "Apply to all dossiers", + "extraOptionLabel": "Apply to all active and future dossiers", "label": "Remove from dossier", "label-bulk": "" }, "only-here": { - "description": "Do not {type} ''{value}'' at this position in the current document.", - "description-bulk": "", + "description": "Do not{type} '{value}'' at this position in the current document.", + "description-bulk": "Do not{type} ''{value}'' at this position in the current document.", "label": "Remove here" } } @@ -2268,7 +2268,7 @@ "display-name": "This placeholder is replaced by the name of the entity the component is based on." }, "excerpt": "This placeholder is replaced by a text snippet that contains the component.", - "is-skipped": "The skipped redaction placeholder indicates whether a redaction is skipped or not. It can be included in a separate column of a template that also contains the '{{redaction.value'}} placeholder. The placeholder is replaced by “true” if the respective redaction is skipped, and by “false” if it is redacted (i. e., not skipped).", + "is-skipped": "The skipped redaction placeholder indicates whether a redaction is skipped or not. It can be included in a separate column of a template that also contains the '\n{{'redaction.value'}}' placeholder. The placeholder is replaced by “true” if the respective redaction is skipped, and by “false” if it is redacted (i. e., not skipped).", "justification": "This placeholder is replaced by the justification of the component. It is a combination of the legal reference (justificationParagraph) and the justification text (justificationReason).", "justification-legal-basis": "This placeholder is replaced by the legal basis for the component.", "justification-paragraph": "This placeholder is replaced by the legal reference of the justification of the component.", @@ -2331,7 +2331,7 @@ "options": { "in-dossier": { "description": "Resize in every document in {dossierName}.", - "extraOptionLabel": "Apply to all dossiers", + "extraOptionLabel": "Apply to all active and future dossiers", "label": "Resize in dossier", "tooltip": "Only available for dictionary-based types" }, @@ -2386,7 +2386,7 @@ }, "missing": "Missing", "must-contain": "Must contain", - "no-data": "Please enter a keyword into the search bar to look for documents or document content.", + "no-data": "Enter a keyword into the search bar
to look for documents or document content.", "no-match": "The specified search term was not found in any of the documents.", "table-header": "{length} search {length, plural, one{result} other{results}}" }, @@ -2422,7 +2422,7 @@ "sign-in-previous-domain": "Sign in to a previously used workspace", "youre-logged-out": "You have successfully been logged out." }, - "input-placeholder": "your workspace" + "input-placeholder": "Your workspace" }, "time": { "days": "{days} {days, plural, one{day} other{days}}", @@ -2515,7 +2515,7 @@ }, "error": { "file-size": "File too large. Limit is {size}MB.", - "file-type": "This file type is not accepted.", + "file-type": "This file type is not supported.", "generic": "Failed to upload file. {error}" } }, @@ -2570,7 +2570,7 @@ }, "title": "Edit profile", "update": { - "success": "Successfully updated profile!" + "success": "Successfully updated profile." } }, "user-stats": { @@ -2588,9 +2588,9 @@ }, "watermark-screen": { "action": { - "change-success": "Watermark has been updated!", - "created-success": "Watermark has been created!", - "error": "Failed to update watermark", + "change-success": "Watermark has been updated.", + "created-success": "Watermark has been created.", + "error": "Failed to update watermark.", "revert": "Revert", "save": "Save changes" }, From 51e46f20f4f66a0be16714cca3c56d15d1039c25 Mon Sep 17 00:00:00 2001 From: Kilian Schuettler Date: Fri, 25 Oct 2024 13:50:27 +0200 Subject: [PATCH 106/125] RED-10264: remove includeUnprocessed from all manual change calls --- .../services/annotation-actions.service.ts | 22 +------------ .../services/manual-redaction.service.ts | 33 +++++-------------- 2 files changed, 9 insertions(+), 46 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts index 852c3b9e3..fc703931a 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts @@ -114,7 +114,6 @@ export class AnnotationActionsService { async editRedaction(annotations: AnnotationWrapper[]) { const { dossierId, file } = this._state; const allFileAnnotations = this._fileDataService.annotations(); - const includeUnprocessed = annotations.every(annotation => this.#includeUnprocessed(annotation, true)); const data = { annotations, allFileAnnotations, @@ -170,7 +169,6 @@ export class AnnotationActionsService { dossierId, file().id, this.#getChangedFields(annotations, result), - includeUnprocessed, result.option === RedactOrHintOptions.IN_DOCUMENT || !!result.pageNumbers.length, ) .pipe(log()), @@ -269,7 +267,6 @@ export class AnnotationActionsService { async acceptResize(annotation: AnnotationWrapper, permissions: AnnotationPermissions): Promise { const textAndPositions = await this.#extractTextAndPositions(annotation.id); - const includeUnprocessed = this.#includeUnprocessed(annotation); if (annotation.isRecommendation) { const recommendation = { ...annotation, @@ -320,7 +317,7 @@ export class AnnotationActionsService { await this.cancelResize(annotation); const { fileId, dossierId } = this._state; - const request = this._manualRedactionService.resize([resizeRequest], dossierId, fileId, includeUnprocessed); + const request = this._manualRedactionService.resize([resizeRequest], dossierId, fileId); return this.#processObsAndEmit(request); } @@ -477,7 +474,6 @@ export class AnnotationActionsService { #removeRedaction(redactions: AnnotationWrapper[], dialogResult: RemoveRedactionResult) { const removeFromDictionary = dialogResult.option.value === RemoveRedactionOptions.IN_DOSSIER; - const includeUnprocessed = redactions.every(redaction => this.#includeUnprocessed(redaction, true)); const body = this.#getRemoveRedactionBody(redactions, dialogResult); // todo: might not be correct, probably shouldn't get to this point if they are not all the same const isHint = redactions.every(r => r.isHint); @@ -505,7 +501,6 @@ export class AnnotationActionsService { fileId, removeFromDictionary, isHint, - includeUnprocessed, dialogResult.bulkLocal, ), ), @@ -521,7 +516,6 @@ export class AnnotationActionsService { fileId, removeFromDictionary, isHint, - includeUnprocessed, dialogResult.bulkLocal || !!dialogResult.pageNumbers.length, ), ).then(); @@ -580,20 +574,6 @@ export class AnnotationActionsService { return { changes: changedFields.join(', ') }; } - //TODO this is temporary, based on RED-8950. Should be removed when a better solution will be found - #includeUnprocessed(annotation: AnnotationWrapper, isRemoveOrRecategorize = false) { - const processed = annotation.entry.manualChanges.at(-1)?.processed; - if (!processed) { - const autoAnalysisDisabled = this._state.file().excludedFromAutomaticAnalysis; - const addedLocallyWhileDisabled = annotation.manual; - if (autoAnalysisDisabled) { - return addedLocallyWhileDisabled; - } - return isRemoveOrRecategorize && addedLocallyWhileDisabled; - } - return false; - } - #getRemoveRedactionBody( redactions: AnnotationWrapper[], dialogResult: RemoveRedactionResult, diff --git a/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts b/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts index e8017d6df..524717c07 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts @@ -75,13 +75,10 @@ export class ManualRedactionService extends GenericService { body: List | IBulkRecategorizationRequest, dossierId: string, fileId: string, - successMessageParameters?: { - [key: string]: string; - }, - includeUnprocessed = false, + successMessageParameters?: { [p: string]: string }, bulkLocal = false, ) { - return this.#recategorize(body, dossierId, fileId, includeUnprocessed, bulkLocal).pipe( + return this.#recategorize(body, dossierId, fileId, bulkLocal).pipe( this.#showToast('recategorize-annotation', false, successMessageParameters), ); } @@ -117,10 +114,9 @@ export class ManualRedactionService extends GenericService { fileId: string, removeFromDictionary = false, isHint = false, - includeUnprocessed = false, bulkLocal = false, ) { - return this.#remove(body, dossierId, fileId, includeUnprocessed, bulkLocal).pipe( + return this.#remove(body, dossierId, fileId, bulkLocal).pipe( this.#showToast(!isHint ? 'remove' : 'remove-hint', removeFromDictionary), ); } @@ -154,36 +150,23 @@ export class ManualRedactionService extends GenericService { return this._post(body, `${this.#bulkRedaction}/force/${dossierId}/${fileId}`).pipe(this.#log('Force redaction', body)); } - resize(body: List, dossierId: string, fileId: string, includeUnprocessed = false) { - return this._post(body, `${this.#bulkRedaction}/resize/${dossierId}/${fileId}?includeUnprocessed=${includeUnprocessed}`).pipe( - this.#log('Resize', body), - ); + resize(body: List, dossierId: string, fileId: string) { + return this._post(body, `${this.#bulkRedaction}/resize/${dossierId}/${fileId}`).pipe(this.#log('Resize', body)); } #recategorize( body: List | IBulkRecategorizationRequest, dossierId: string, fileId: string, - includeUnprocessed = false, bulkLocal = false, ) { const bulkPath = bulkLocal ? this.#bulkLocal : this.#bulkRedaction; - return this._post(body, `${bulkPath}/recategorize/${dossierId}/${fileId}?includeUnprocessed=${includeUnprocessed}`).pipe( - this.#log('Recategorize', body), - ); + return this._post(body, `${bulkPath}/recategorize/${dossierId}/${fileId}`).pipe(this.#log('Recategorize', body)); } - #remove( - body: List | IBulkLocalRemoveRequest, - dossierId: string, - fileId: string, - includeUnprocessed = false, - bulkLocal = false, - ) { + #remove(body: List | IBulkLocalRemoveRequest, dossierId: string, fileId: string, bulkLocal = false) { const bulkPath = bulkLocal ? this.#bulkLocal : this.#bulkRedaction; - return this._post(body, `${bulkPath}/remove/${dossierId}/${fileId}?includeUnprocessed=${includeUnprocessed}`).pipe( - this.#log('Remove', body), - ); + return this._post(body, `${bulkPath}/remove/${dossierId}/${fileId}`).pipe(this.#log('Remove', body)); } #log(action: string, body: unknown) { From 7dd24698b14668925f23c10ca3e18a5b7e5cecc7 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Mon, 28 Oct 2024 13:47:29 +0200 Subject: [PATCH 107/125] WIP on VM/RED-10256 RED-10256 - Bulk-local: Changes should not be filtered + Remove for image-based redactions --- .../remove-annotation-dialog.component.ts | 3 +- .../force-annotation-dialog.component.ts | 52 +++++++------ .../remove-redaction-dialog.component.ts | 11 ++- .../services/annotation-actions.service.ts | 77 ++++++++++--------- .../services/file-preview-dialog.service.ts | 6 +- .../file-preview/utils/dialog-options.ts | 36 ++++----- .../file-preview/utils/dialog-types.ts | 15 ++++ apps/red-ui/src/assets/i18n/redact/en.json | 2 +- .../redaction-log/recategorization.request.ts | 4 +- 9 files changed, 113 insertions(+), 93 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.ts index 6571d4ecc..11c80ccc4 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.ts @@ -46,12 +46,13 @@ export class RemoveAnnotationDialogComponent extends IqserDialogComponent< readonly iconButtonTypes = IconButtonTypes; readonly options: DetailsRadioOption[]; readonly redactedTexts: string[]; + readonly isImage = this.data.redactions.reduce((acc, next) => acc && next.isImage, true); form!: UntypedFormGroup; constructor(private readonly _formBuilder: FormBuilder) { super(); - this.options = getRemoveRedactionOptions(this.data, this.data.applyToAllDossiers, true); + this.options = getRemoveRedactionOptions(this.data, this.data.applyToAllDossiers, this.isImage, true); this.redactedTexts = this.data.redactions.map(annotation => annotation.value); this.form = this.#getForm(); } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts index a6eab119f..7b87874ef 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts @@ -1,14 +1,13 @@ -import { Component, Inject, OnInit } from '@angular/core'; -import { ReactiveFormsModule, UntypedFormGroup, Validators } from '@angular/forms'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, ReactiveFormsModule, UntypedFormGroup, Validators } from '@angular/forms'; import { - BaseDialogComponent, CircleButtonComponent, getConfig, HasScrollbarDirective, HelpButtonComponent, IconButtonComponent, IqserDenyDirective, + IqserDialogComponent, } from '@iqser/common-ui'; import { JustificationsService } from '@services/entity-services/justifications.service'; import { Dossier, ILegalBasisChangeRequest } from '@red/domain'; @@ -21,20 +20,19 @@ import { ValueColumn, } from '../../components/selected-annotations-table/selected-annotations-table.component'; import { NgForOf, NgIf } from '@angular/common'; -import { MatFormField } from '@angular/material/form-field'; import { MatOption, MatSelect, MatSelectTrigger } from '@angular/material/select'; +import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option'; +import { ForceAnnotationData, ForceAnnotationOption, ForceAnnotationResult, LegalBasisOption } from '../../utils/dialog-types'; +import { getForceAnnotationOptions } from '../../utils/dialog-options'; +import { SystemDefaults } from '../../../account/utils/dialog-defaults'; +import { MatFormField } from '@angular/material/form-field'; import { MatTooltip } from '@angular/material/tooltip'; import { TranslateModule } from '@ngx-translate/core'; -import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option'; -import { ForceAnnotationOption, LegalBasisOption } from '../../utils/dialog-types'; -import { getForceAnnotationOptions } from '../../utils/dialog-options'; import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component'; -import { SystemDefaults } from '../../../account/utils/dialog-defaults'; const DOCUMINE_LEGAL_BASIS = 'n-a.'; @Component({ - selector: 'redaction-force-annotation-dialog', templateUrl: './force-annotation-dialog.component.html', styleUrls: ['./force-annotation-dialog.component.scss'], standalone: true, @@ -57,12 +55,16 @@ const DOCUMINE_LEGAL_BASIS = 'n-a.'; DetailsRadioComponent, ], }) -export class ForceAnnotationDialogComponent extends BaseDialogComponent implements OnInit { +export class ForceAnnotationDialogComponent + extends IqserDialogComponent + implements OnInit +{ readonly isDocumine = getConfig().IS_DOCUMINE; readonly options: DetailsRadioOption[]; + readonly form: FormGroup; readonly tableColumns: ValueColumn[] = [{ label: 'Value' }, { label: 'Type' }]; - readonly tableData: ValueColumn[][] = this._data.annotations.map(redaction => [ + readonly tableData: ValueColumn[][] = this.data.annotations.map(redaction => [ { label: redaction.value, bold: true }, { label: redaction.typeLabel }, ]); @@ -72,21 +74,23 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen constructor( private readonly _justificationsService: JustificationsService, - protected readonly _dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) - private readonly _data: { readonly dossier: Dossier; readonly hint: boolean; annotations: AnnotationWrapper[] }, + private readonly _formBuilder: FormBuilder, ) { - super(_dialogRef); - this.options = getForceAnnotationOptions(this.isDocumine, this.isHintDialog); + super(); + this.options = getForceAnnotationOptions(this.isDocumine, this.isHintDialog, this.isImageDialog); this.form = this.#getForm(); } get isImageHint() { - return this._data.annotations.every(annotation => annotation.IMAGE_HINT); + return this.data.annotations.every(annotation => annotation.IMAGE_HINT); } get isHintDialog() { - return this._data.hint; + return this.data.hint; + } + + get isImageDialog() { + return this.data.image; } get disabled(): boolean { @@ -103,7 +107,7 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen async ngOnInit() { if (!this.isDocumine) { - const data = await firstValueFrom(this._justificationsService.getForDossierTemplate(this._data.dossier.dossierTemplateId)); + const data = await firstValueFrom(this._justificationsService.getForDossierTemplate(this.data.dossier.dossierTemplateId)); this.legalOptions = data.map(lbm => ({ legalBasis: lbm.reason, @@ -114,8 +118,8 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen this.legalOptions.sort((a, b) => a.label.localeCompare(b.label)); // Set pre-existing reason if it exists - const existingReason = this.legalOptions.find(option => option.legalBasis === this._data.annotations[0].legalBasis); - if (!this._data.hint && existingReason) { + const existingReason = this.legalOptions.find(option => option.legalBasis === this.data.annotations[0].legalBasis); + if (!this.data.hint && existingReason) { this.form.patchValue({ reason: existingReason }, { emitEvent: false }); } } @@ -123,12 +127,12 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen } save() { - this._dialogRef.close(this.#createForceRedactionRequest()); + this.close(this.#createForceRedactionRequest()); } #getForm(): UntypedFormGroup { return this._formBuilder.group({ - reason: this._data.hint ? ['Forced Hint'] : [null, !this.isDocumine ? Validators.required : null], + reason: this.data.hint ? ['Forced Hint'] : [null, !this.isDocumine ? Validators.required : null], comment: [null], option: this.options.find(o => o.value === SystemDefaults.FORCE_REDACTION_DEFAULT), }); diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts index 25a3a3865..5ec97ffbf 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts @@ -66,6 +66,7 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< readonly recommendation = this.data.redactions.every(redaction => redaction.isRecommendation); readonly hint = this.data.redactions.every(redaction => redaction.isHint); readonly annotationsType = this.hint ? 'hint' : this.recommendation ? 'recommendation' : 'redaction'; + readonly isImage = this.data.redactions.reduce((acc, next) => acc && next.isImage, true); readonly optionByType = { recommendation: { main: this._userPreferences.getRemoveRecommendationDefaultOption(), @@ -107,6 +108,7 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< : getRemoveRedactionOptions( this.data, this.isSystemDefault || this.isExtraOptionSystemDefault ? this.#applyToAllDossiers : this.extraOptionPreference, + this.isImage, ); readonly skipped = this.data.redactions.some(annotation => annotation.isSkipped); readonly redactedTexts = this.data.redactions.map(annotation => annotation.value); @@ -185,12 +187,9 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< } save(): void { - const optionValue = this.form.controls.option.value.value; - const pageNumbers = parseSelectedPageNumbers( - this.form.get('option').value.additionalInput?.value, - this.data.file, - this.data.redactions[0], - ); + const optionValue = this.form.controls.option?.value?.value; + const optionInputValue = this.form.controls.option?.value?.additionalInput?.value; + const pageNumbers = parseSelectedPageNumbers(optionInputValue, this.data.file, this.data.redactions[0]); const position = parseRectanglePosition(this.data.redactions[0]); this.close({ diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts index 852c3b9e3..4d5d6890c 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts @@ -7,6 +7,7 @@ import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { Core } from '@pdftron/webviewer'; import { DictionaryEntryTypes, + DownloadFileTypes, EarmarkOperation, type IBulkLocalRemoveRequest, IBulkRecategorizationRequest, @@ -51,6 +52,7 @@ import { FilePreviewStateService } from './file-preview-state.service'; import { ManualRedactionService } from './manual-redaction.service'; import { SkippedService } from './skipped.service'; import { NON_READABLE_CONTENT } from '../dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component'; +import { ForceAnnotationDialogComponent } from '../dialogs/force-redaction-dialog/force-annotation-dialog.component'; @Injectable() export class AnnotationActionsService { @@ -81,34 +83,41 @@ export class AnnotationActionsService { this._dialogService.openDialog('highlightAction', data); } - forceAnnotation(annotations: AnnotationWrapper[], hint: boolean = false) { + async forceAnnotation(annotations: AnnotationWrapper[], hint: boolean = false) { const { dossierId, fileId } = this._state; - const data = { dossier: this._state.dossier(), annotations, hint }; - this._dialogService.openDialog('forceAnnotation', data, (request: ILegalBasisChangeRequest) => { - let obs$: Observable; - if (request.option === ForceAnnotationOptions.ONLY_HERE || hint) { - obs$ = this._manualRedactionService.bulkForce( - annotations.map(a => ({ ...request, annotationId: a.id })), - dossierId, - fileId, - annotations[0].isIgnoredHint, - ); - } else { - const addAnnotationRequest = annotations.map(a => ({ - comment: request.comment, - legalBasis: request.legalBasis, - reason: request.reason, - positions: a.positions, - type: a.type, - value: a.value, - })); - obs$ = this._manualRedactionService.addAnnotation(addAnnotationRequest, dossierId, fileId, { - hint, - bulkLocal: true, - }); - } - this.#processObsAndEmit(obs$).then(); - }); + const image = annotations.every(a => a.isImage); + const data = { dossier: this._state.dossier(), annotations, hint, image }; + + const dialogRef = this._iqserDialog.openDefault(ForceAnnotationDialogComponent, { data }); + const result = await dialogRef.result(); + + if (!result) { + return; + } + + let obs$: Observable; + if (result.option === ForceAnnotationOptions.ONLY_HERE || hint || image) { + obs$ = this._manualRedactionService.bulkForce( + annotations.map(a => ({ ...result, annotationId: a.id })), + dossierId, + fileId, + annotations[0].isIgnoredHint, + ); + } else { + const addAnnotationRequest = annotations.map(a => ({ + comment: result.comment, + legalBasis: result.legalBasis, + reason: result.reason, + positions: a.positions, + type: a.type, + value: a.value, + })); + obs$ = this._manualRedactionService.addAnnotation(addAnnotationRequest, dossierId, fileId, { + hint, + bulkLocal: true, + }); + } + this.#processObsAndEmit(obs$).then(); } async editRedaction(annotations: AnnotationWrapper[]) { @@ -147,15 +156,11 @@ export class AnnotationActionsService { return body; }); } else { - const originTypes = annotations.map(a => a.type); - const originLegalBases = annotations.map(a => a.legalBasis); recategorizeBody = { value: annotations[0].value, type: result.type, legalBasis: result.legalBasis, section: result.section, - originTypes, - originLegalBases, rectangle: annotations[0].AREA, pageNumbers: result.pageNumbers, position: result.position, @@ -206,8 +211,8 @@ export class AnnotationActionsService { } if ( - result.option.value === RemoveRedactionOptions.FALSE_POSITIVE || - result.option.value === RemoveRedactionOptions.DO_NOT_RECOMMEND + result.option?.value === RemoveRedactionOptions.FALSE_POSITIVE || + result.option?.value === RemoveRedactionOptions.DO_NOT_RECOMMEND ) { this.#setAsFalsePositive(redactions, result); } else { @@ -476,7 +481,7 @@ export class AnnotationActionsService { } #removeRedaction(redactions: AnnotationWrapper[], dialogResult: RemoveRedactionResult) { - const removeFromDictionary = dialogResult.option.value === RemoveRedactionOptions.IN_DOSSIER; + const removeFromDictionary = dialogResult.option?.value === RemoveRedactionOptions.IN_DOSSIER; const includeUnprocessed = redactions.every(redaction => this.#includeUnprocessed(redaction, true)); const body = this.#getRemoveRedactionBody(redactions, dialogResult); // todo: might not be correct, probably shouldn't get to this point if they are not all the same @@ -615,8 +620,8 @@ export class AnnotationActionsService { annotationId: redaction.id, value: redaction.value, comment: dialogResult.comment, - removeFromDictionary: dialogResult.option.value === RemoveRedactionOptions.IN_DOSSIER, - removeFromAllDossiers: !!dialogResult.option.additionalCheck?.checked || !!dialogResult.applyToAllDossiers, + removeFromDictionary: dialogResult.option?.value === RemoveRedactionOptions.IN_DOSSIER, + removeFromAllDossiers: !!dialogResult.option?.additionalCheck?.checked || !!dialogResult.applyToAllDossiers, })); } } diff --git a/apps/red-ui/src/app/modules/file-preview/services/file-preview-dialog.service.ts b/apps/red-ui/src/app/modules/file-preview/services/file-preview-dialog.service.ts index 4028b154a..aa961c0e9 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/file-preview-dialog.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/file-preview-dialog.service.ts @@ -3,10 +3,9 @@ import { MatDialog } from '@angular/material/dialog'; import { ConfirmationDialogComponent, DialogConfig, DialogService } from '@iqser/common-ui'; import { ChangeLegalBasisDialogComponent } from '../dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component'; import { DocumentInfoDialogComponent } from '../dialogs/document-info-dialog/document-info-dialog.component'; -import { ForceAnnotationDialogComponent } from '../dialogs/force-redaction-dialog/force-annotation-dialog.component'; import { HighlightActionDialogComponent } from '../dialogs/highlight-action-dialog/highlight-action-dialog.component'; -type DialogType = 'confirm' | 'documentInfo' | 'changeLegalBasis' | 'forceAnnotation' | 'highlightAction'; +type DialogType = 'confirm' | 'documentInfo' | 'changeLegalBasis' | 'highlightAction'; @Injectable() export class FilePreviewDialogService extends DialogService { @@ -22,9 +21,6 @@ export class FilePreviewDialogService extends DialogService { changeLegalBasis: { component: ChangeLegalBasisDialogComponent, }, - forceAnnotation: { - component: ForceAnnotationDialogComponent, - }, highlightAction: { component: HighlightActionDialogComponent, }, diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts index a0a680575..9016bce7f 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts @@ -132,22 +132,21 @@ export const getResizeRedactionOptions = ( isApprover: boolean, canResizeInDictionary: boolean, ): DetailsRadioOption[] => { + if (isRss || !canResizeInDictionary) { + return []; + } + const translations = resizeRedactionTranslations; - const options: DetailsRadioOption[] = [ + const dictBasedType = redaction.isModifyDictionary; + + return [ { label: translations.onlyHere.label, description: translations.onlyHere.description, icon: PIN_ICON, value: ResizeOptions.ONLY_HERE, }, - ]; - - if (isRss) { - return options; - } - if (canResizeInDictionary) { - const dictBasedType = redaction.isModifyDictionary; - options.push({ + { label: translations.inDossier.label, description: translations.inDossier.description, descriptionParams: { dossierName: dossier.dossierName }, @@ -160,14 +159,14 @@ export const getResizeRedactionOptions = ( checked: applyToAllDossiers, hidden: !isApprover, }, - }); - } - return options; + }, + ]; }; export const getRemoveRedactionOptions = ( data: RemoveRedactionData, applyToAllDossiers: boolean, + isImage: boolean, isDocumine: boolean = false, ): DetailsRadioOption[] => { const translations = isDocumine ? removeAnnotationTranslations : removeRedactionTranslations; @@ -175,7 +174,7 @@ export const getRemoveRedactionOptions = ( const isBulk = redactions.length > 1; const options: DetailsRadioOption[] = []; - if (permissions.canRemoveOnlyHere) { + if (permissions.canRemoveOnlyHere && !isImage) { options.push({ label: translations.ONLY_HERE.label, description: isBulk ? translations.ONLY_HERE.descriptionBulk : translations.ONLY_HERE.description, @@ -191,9 +190,6 @@ export const getRemoveRedactionOptions = ( options.push({ label: removeRedactionTranslations.IN_DOCUMENT.label, description: removeRedactionTranslations.IN_DOCUMENT.description, - descriptionParams: { - isImage: redactions[0].isImage ? 'image' : redactions[0].typeLabel, - }, icon: DOCUMENT_ICON, value: RemoveRedactionOptions.IN_DOCUMENT, }); @@ -265,8 +261,12 @@ export const getRemoveRedactionOptions = ( return options; }; -export const getForceAnnotationOptions = (isDocumine: boolean, isHint: boolean): DetailsRadioOption[] => { - if (isDocumine || isHint) { +export const getForceAnnotationOptions = ( + isDocumine: boolean, + isHint: boolean, + isImage: boolean, +): DetailsRadioOption[] => { + if (isDocumine || isHint || isImage) { return []; } diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts index e0f84cba2..c1c5ac931 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-types.ts @@ -73,6 +73,21 @@ export interface EditRedactionData { export type AddAnnotationData = RedactTextData; export type AddHintData = RedactTextData; +export interface ForceAnnotationData { + readonly dossier: Dossier; + readonly annotations: AnnotationWrapper[]; + readonly hint: boolean; + readonly image: boolean; +} + +export interface ForceAnnotationResult { + readonly annotationId?: string; + readonly comment?: string; + readonly legalBasis?: string; + readonly reason?: string; + readonly option?: ForceAnnotationOption; +} + export interface RedactTextResult { redaction: IManualRedactionEntry; dictionary: Dictionary; diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index 8c9615cb3..70ac26653 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -2224,7 +2224,7 @@ "label": "Remove from dossier in this context" }, "in-document": { - "description": "Do not auto-redact the selected {isImage, select, image{image} other{term}} on any page of this document.", + "description": "Do not auto-redact the selected term on any page of this document.", "label": "Remove from document" }, "in-dossier": { diff --git a/libs/red-domain/src/lib/redaction-log/recategorization.request.ts b/libs/red-domain/src/lib/redaction-log/recategorization.request.ts index 9939b140a..57ec25dd7 100644 --- a/libs/red-domain/src/lib/redaction-log/recategorization.request.ts +++ b/libs/red-domain/src/lib/redaction-log/recategorization.request.ts @@ -14,8 +14,8 @@ export interface IBulkRecategorizationRequest { readonly type: string; readonly legalBasis: string; readonly section: string; - readonly originTypes: string[]; - readonly originLegalBases: string[]; + readonly originTypes?: string[]; + readonly originLegalBases?: string[]; readonly rectangle: boolean; readonly position?: IEntityLogEntryPosition; readonly pageNumbers?: number[]; From 64e7cce171e67889b2f0c23a789c901549c02310 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Mon, 28 Oct 2024 16:55:24 +0200 Subject: [PATCH 108/125] RED-9944 - Action Items don't appear in document area in webviewer when bulk-select is still unintenionally active --- .../file-workload/file-workload.component.ts | 2 +- .../file-preview-screen.component.ts | 20 +++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts index ec3b87e49..eae606c2f 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts @@ -596,7 +596,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On @HostListener('document: click') clickOutsideWorkloadView() { - if (this.multiSelectService.active()) { + if (this.multiSelectService.active() && !this._dialog.openDialogs.length) { this.multiSelectService.deactivate(); } } diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts index 86c838768..3c1fdfbdc 100644 --- a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts @@ -282,17 +282,21 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni @Bind() handleViewerClick(event: MouseEvent) { this._ngZone.run(() => { - if (this._multiSelectService.active()) { + if (event.isTrusted) { const clickedElement = event.target as HTMLElement; - if ( - clickedElement.querySelector('#selectionrect') || - clickedElement.id === `pageWidgetContainer${this.pdf.currentPage()}` - ) { - if (!this._annotationManager.selected.length) { + const editingAnnotation = + (clickedElement as HTMLImageElement).src?.includes('edit.svg') || clickedElement.getAttribute('aria-label') === 'Edit'; + if (this._multiSelectService.active() && !editingAnnotation) { + if ( + clickedElement.querySelector('#selectionrect') || + clickedElement.id === `pageWidgetContainer${this.pdf.currentPage()}` + ) { + if (!this._annotationManager.selected.length) { + this._multiSelectService.deactivate(); + } + } else { this._multiSelectService.deactivate(); } - } else { - this._multiSelectService.deactivate(); } } }); From 9e0ec97845a80b86c45f38686d0737695c45bbd9 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Mon, 28 Oct 2024 17:22:54 +0200 Subject: [PATCH 109/125] RED-10256 - Bulk-local: Changes should not be filtered + Remove for image-based redactions --- .../remove-annotation-dialog.component.ts | 3 +-- .../remove-redaction-dialog.component.ts | 2 -- .../file-preview/utils/dialog-options.ts | 17 ++++++++++------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.ts index 11c80ccc4..6571d4ecc 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.ts @@ -46,13 +46,12 @@ export class RemoveAnnotationDialogComponent extends IqserDialogComponent< readonly iconButtonTypes = IconButtonTypes; readonly options: DetailsRadioOption[]; readonly redactedTexts: string[]; - readonly isImage = this.data.redactions.reduce((acc, next) => acc && next.isImage, true); form!: UntypedFormGroup; constructor(private readonly _formBuilder: FormBuilder) { super(); - this.options = getRemoveRedactionOptions(this.data, this.data.applyToAllDossiers, this.isImage, true); + this.options = getRemoveRedactionOptions(this.data, this.data.applyToAllDossiers, true); this.redactedTexts = this.data.redactions.map(annotation => annotation.value); this.form = this.#getForm(); } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts index 5ec97ffbf..0ffa843bb 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-redaction-dialog/remove-redaction-dialog.component.ts @@ -66,7 +66,6 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< readonly recommendation = this.data.redactions.every(redaction => redaction.isRecommendation); readonly hint = this.data.redactions.every(redaction => redaction.isHint); readonly annotationsType = this.hint ? 'hint' : this.recommendation ? 'recommendation' : 'redaction'; - readonly isImage = this.data.redactions.reduce((acc, next) => acc && next.isImage, true); readonly optionByType = { recommendation: { main: this._userPreferences.getRemoveRecommendationDefaultOption(), @@ -108,7 +107,6 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent< : getRemoveRedactionOptions( this.data, this.isSystemDefault || this.isExtraOptionSystemDefault ? this.#applyToAllDossiers : this.extraOptionPreference, - this.isImage, ); readonly skipped = this.data.redactions.some(annotation => annotation.isSkipped); readonly redactedTexts = this.data.redactions.map(annotation => annotation.value); diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts index 9016bce7f..f4390648c 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts @@ -166,12 +166,12 @@ export const getResizeRedactionOptions = ( export const getRemoveRedactionOptions = ( data: RemoveRedactionData, applyToAllDossiers: boolean, - isImage: boolean, isDocumine: boolean = false, ): DetailsRadioOption[] => { const translations = isDocumine ? removeAnnotationTranslations : removeRedactionTranslations; const { permissions, redactions, isApprover, falsePositiveContext } = data; const isBulk = redactions.length > 1; + const isImage = redactions.reduce((acc, next) => acc && next.isImage, true); const options: DetailsRadioOption[] = []; if (permissions.canRemoveOnlyHere && !isImage) { @@ -187,12 +187,15 @@ export const getRemoveRedactionOptions = ( value: RemoveRedactionOptions.ONLY_HERE, }); - options.push({ - label: removeRedactionTranslations.IN_DOCUMENT.label, - description: removeRedactionTranslations.IN_DOCUMENT.description, - icon: DOCUMENT_ICON, - value: RemoveRedactionOptions.IN_DOCUMENT, - }); + const isHint = redactions.reduce((acc, next) => acc && next.isHint, true); + if (!isHint) { + options.push({ + label: removeRedactionTranslations.IN_DOCUMENT.label, + description: removeRedactionTranslations.IN_DOCUMENT.description, + icon: DOCUMENT_ICON, + value: RemoveRedactionOptions.IN_DOCUMENT, + }); + } } if (permissions.canRemoveFromDictionary) { options.push({ From 7e44bdf1e20d0616cfd7c83cddfea7227de6459e Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Mon, 28 Oct 2024 17:25:09 +0200 Subject: [PATCH 110/125] RED-10262: fixed cancel resize. --- .../resize-redaction-dialog.component.ts | 2 +- .../modules/file-preview/services/annotation-actions.service.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/resize-redaction-dialog/resize-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/resize-redaction-dialog/resize-redaction-dialog.component.ts index a5b174c13..1d8c4308e 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/resize-redaction-dialog/resize-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/resize-redaction-dialog/resize-redaction-dialog.component.ts @@ -77,7 +77,7 @@ export class ResizeRedactionDialogComponent extends IqserDialogComponent< save() { const formValue = this.form.getRawValue(); - const updateDictionary = formValue.option.value === ResizeOptions.IN_DOSSIER; + const updateDictionary = formValue.option?.value === ResizeOptions.IN_DOSSIER; super.close({ comment: formValue.comment, diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts index e0ca1ef91..020d61af5 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts @@ -329,9 +329,9 @@ export class AnnotationActionsService { async cancelResize(annotationWrapper: AnnotationWrapper) { this._annotationManager.resizingAnnotationId = undefined; this._annotationManager.annotationHasBeenResized = false; + this._annotationManager.deselect(); this._annotationManager.delete(annotationWrapper); await this._annotationDrawService.draw([annotationWrapper], this._skippedService.hideSkipped(), this._state.dossierTemplateId); - this._annotationManager.deselect(); } #generateRectangle(annotationWrapper: AnnotationWrapper) { From b389b07a6e221964e2988834eb35c17cb82e27df Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Mon, 28 Oct 2024 17:38:35 +0200 Subject: [PATCH 111/125] RED-3800: localazy manual sync. --- apps/red-ui/src/assets/i18n/redact/de.json | 4 +- apps/red-ui/src/assets/i18n/redact/en.json | 8 +- apps/red-ui/src/assets/i18n/scm/de.json | 128 ++++++++++----------- apps/red-ui/src/assets/i18n/scm/en.json | 12 +- 4 files changed, 76 insertions(+), 76 deletions(-) diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index 7f446c353..4a4640044 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -1240,7 +1240,7 @@ "entries-count": "{count} {count, plural, one{Eintrag} other{Einträge}}", "false-positives": "Falsch-Positive ({count})", "false-recommendations": "Falsche Empfehlungen ({count})", - "to-redact": "Schwärzungen ({count})" + "to-redact": "Einträge ({count})" }, "general-info": { "form": { @@ -1264,7 +1264,7 @@ "missing-owner": "Bearbeiten des Dossiers nicht möglich: Kein Besitzer zugewiesen.", "nav-items": { "choose-download": "Stellen Sie Ihr Download-Paket zusammen:", - "dictionary": "Wörterbücher", + "dictionary": "Dossier-Einträge", "dossier-attributes": "Dossier-Attribute", "dossier-dictionary": "Dossier-Einträge", "dossier-info": "Dossier-Info", diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index dfd34eb14..d64b02fb3 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -777,7 +777,7 @@ "revert-changes": "Revert", "save-changes": "Save changes", "search": "Search entries...", - "select-dictionary": "Select a dictionary for comparison above.", + "select-dictionary": "Select a dictionary for comparison from the drop-down.", "success": { "generic": "Dictionary updated" } @@ -1240,7 +1240,7 @@ "entries-count": "{count} {count, plural, one{entry} other{entries}}", "false-positives": "False positives ({count})", "false-recommendations": "False recommendations ({count})", - "to-redact": "To redact ({count})" + "to-redact": "Entries ({count})" }, "general-info": { "form": { @@ -1264,7 +1264,7 @@ "missing-owner": "Editing the dossier not possible: No owner assigned.", "nav-items": { "choose-download": "Select the documents for your download:", - "dictionary": "Dictionaries", + "dictionary": "Dossier entries", "dossier-attributes": "Dossier attributes", "dossier-dictionary": "Dossier entries", "dossier-info": "Dossier info", @@ -2224,7 +2224,7 @@ "label": "Remove from dossier in this context" }, "in-document": { - "description": "Do not auto-redact the selected term on any page of this document.", + "description": "Do not auto-redact the selected {isImage, select, image{image} other{term}} on any page of this document.", "label": "Remove from document" }, "in-dossier": { diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index bdcc10b71..5dc2c330c 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -482,7 +482,7 @@ }, "auth-error": { "heading": "Sie haben sich erfolgreich eingeloggt, können aber nicht auf die Applikation zugreifen, da Ihnen keine Rolle zugewiesen ist. Bitten Sie Ihren Admin, Ihnen eine Rolle zuzuweisen.", - "heading-with-link": "Sie haben sich erfolgreich eingeloggt, aber Ihrem Benutzer ist noch keine Rolle zugewiesen. Bitten Sie Ihren RedactManager-Admin Ihnen eine Rolle zuzuweisen.", + "heading-with-link": "Sie haben sich erfolgreich eingeloggt, aber Ihrem Benutzer ist noch keine Rolle zugewiesen. Bitten Sie Ihren DocuMine-Admin Ihnen eine Rolle zuzuweisen.", "heading-with-name": "Sie haben sich erfolgreich eingeloggt, aber Ihnen ist noch keine Rolle zugewiesen. Bitten Sie {adminName}, Ihnen eine Rolle zuzuweisen.", "heading-with-name-and-link": "Sie haben sich erfolgreich eingeloggt, aber Ihnen ist noch keine Rolle zugewiesen. Bitten Sie {adminName}, Ihnen eine Rolle zuzuweisen.", "logout": "Ausloggen" @@ -863,7 +863,7 @@ }, "add-new": "Neues Attribut", "bulk": { - "delete": "Ausgewähltes Attribut löschen" + "delete": "Ausgewählte Attribute löschen" }, "no-data": { "action": "Neues Attribut", @@ -1092,28 +1092,28 @@ "active-dossiers": "{count, plural, one{Aktives Dossier} other{Aktive Dossiers}}", "analyzed-pages": "{count} {count, plural, one{Seite} other {Seiten}} analysiert", "archived-dossiers": "{count} {count, plural, one{Dossier} other {Dossiers}} im Archiv", - "deleted-dossiers": "{count} {count, plural, one{dossier} other {dossiers}} in trash", + "deleted-dossiers": "{count} {count, plural, one{Dossier} other {Dossiers}} im Papierkorb", "total-documents": "Anzahl der Dokumente", - "total-people": "{count} {count, plural, one{user} other {users}}" + "total-people": "{count} {count, plural, one{Benutzer} other {Benutzer}}" }, "dossier-templates": { "label": "Dossier-Vorlagen", "status": { - "active": "Active", - "inactive": "Inactive", - "incomplete": "Incomplete" + "active": "Aktiv", + "inactive": "Inaktiv", + "incomplete": "Unvollständig" } }, "dossier-templates-listing": { "action": { - "clone": "Clone template", + "clone": "Vorlage klonen", "delete": "Dossier-Vorlage" }, "add-new": "Neue Dossier-Vorlage", "bulk": { "delete": "Ausgewählte Dossier-Vorlagen löschen" }, - "entities": "{length} {length, plural, one{entity} other{entities}}", + "entities": "{length} {length, plural, one{Entität} other{Entitäten}}", "error": { "conflict": "Dieses DossierTemplate kann nicht gelöscht werden! Zumindest auf Dossier wird diese Vorlage verwendet!", "generic": "Dieses DossierTemplate kann nicht gelöscht werden!" @@ -1131,22 +1131,22 @@ "modified-on": "Geändert am", "name": "Name", "status": "Status", - "valid-from": "Valid from", - "valid-to": "Valid to" + "valid-from": "Gültig von", + "valid-to": "Gültig bis" }, "table-header": { - "title": "{length} dossier {length, plural, one{template} other{templates}}" + "title": "{length} {length, plural, one{archiviertes Dossier} other{archivierte Dossiers}}" } }, "dossier-watermark-selector": { - "heading": "Watermarks on documents", - "no-watermark": "There is no watermark defined for the dossier template.
Contact your app admin to define one.", - "preview": "Watermark application on preview documents", - "watermark": "Watermark application on documents" + "heading": "Wasserzeichen auf Dokumenten", + "no-watermark": "Kein Wasserzeichen in der Dossier-Vorlage verfügbar:
Bitten Sie Ihren Admin, eines zu konfigurieren.", + "preview": "Wasserzeichen auf Vorschau-Dokumenten", + "watermark": "Wasserzeichen auf Vorschau-Dokumenten" }, "dossiers-type-switch": { - "active": "Active", - "archive": "Archived" + "active": "Aktiv", + "archive": "Archiviert" }, "download-dialog": { "actions": { @@ -1161,19 +1161,19 @@ }, "download-includes": "Wählen Sie die Dokumente für Ihr Download-Paket aus", "download-status": { - "error": "The download preparation failed, please recheck the selected files and download option settings.", + "error": "Download-Generierung fehlgeschlagen

Bitte überprüfen Sie die in den Download-Optionen ausgewählten Dateien und Einstellungen.", "queued": "Ihr Download wurde zur Warteschlange hinzugefügt. Hier finden Sie alle angeforderten Downloads: My Downloads." }, "download-type": { "annotated": "PDF mit Anmerkungen", "delta-preview": "Delta PDF", "flatten": "PDF verflachen", - "label": "{length} document {length, plural, one{version} other{versions}}", - "optimized-preview": "Optimized Preview PDF", + "label": "{length} Dokumenten{length, plural, one{typ} other{typen}}", + "optimized-preview": "Optimiertes Vorschau-PDF", "original": "Optimiertes PDF", "preview": "PDF-Vorschau", "redacted": "geschwärztes PDF", - "redacted-only": "Redacted PDF (redacted documents only)" + "redacted-only": "Geschwärztes PDF (nur freigegebene Dateien)" }, "downloads-list": { "actions": { @@ -1193,7 +1193,7 @@ "status": "Status" }, "table-header": { - "title": "{length} {length, plural, one{download} other{downloads}}" + "title": "{length} {length, plural, one{Download} other{Downloads}}" } }, "edit-color-dialog": { @@ -1207,7 +1207,7 @@ }, "edit-dossier-dialog": { "actions": { - "revert": "Rückgängig machen", + "revert": "Zurücksetzen", "save": "Änderungen speichern", "save-and-close": "Speichern" }, @@ -1250,7 +1250,7 @@ "label": "Dossier-Status", "no-state-placeholder": "Für dieses Dossier ist noch kein Status festgelegt" }, - "due-date": "Termin", + "due-date": "Enddatum", "name": { "label": "Dossier-Name", "placeholder": "Namen eingeben" @@ -1313,25 +1313,25 @@ } }, "reason": "", - "redacted-text": "Annotated text", + "redacted-text": "Annotierter Text", "section": "", - "type": "Type", - "unchanged": "Unchanged" + "type": "Typ", + "unchanged": "Ungeändert" }, - "title": "Edit annotation" + "title": "Annotation bearbeiten" } }, "entities-listing": { "action": { - "delete": "Wörterbuch löschen", - "edit": "Wörterbuch bearbeiten" + "delete": "Entität löschen", + "edit": "Entität bearbeiten" }, - "add-new": "Neues Wörterbuch", + "add-new": "Neue Entität", "bulk": { - "delete": "Ausgewählte Wörterbücher löschen" + "delete": "Ausgewählte Entitäten löschen" }, "no-data": { - "action": "Neues Wörterbuch", + "action": "Neue Entität", "title": "Es gibt noch keine Wörterbücher." }, "no-match": { @@ -1339,36 +1339,36 @@ }, "search": "Suche ...", "table-col-names": { - "dictionary-entries": "Dictionary entries", - "hint-redaction": "Hinweis/Schwärzung", + "dictionary-entries": "Wörterbucheinträge", + "hint-redaction": "Hinweis/Annotation", "rank": "Rang", "type": "Typ" }, "table-header": { - "title": "{length} {length, plural, one{entity} other{entities}}" + "title": "{length} {length, plural, one{Wörterbuch} other{Wörterbücher}}" } }, "entity": { "info": { "actions": { - "revert": "Revert", - "save": "Save changes" + "revert": "Zurücksetzen", + "save": "Änderungen speichern" }, - "heading": "Edit entity" + "heading": "Entität bearbeiten" } }, "entity-rules-screen": { "error": { - "generic": "Something went wrong... Entity rules update failed!" + "generic": "Fehler: Aktualisierung der Entitätsregeln fehlgeschlagen." }, - "errors-found": "{errors, plural, one{An error} other{{errors} errors}} found in rules", - "revert-changes": "Revert", - "save-changes": "Save changes", + "errors-found": "{errors, plural, one{An error} other{{errors} errors}} in den Regeln", + "revert-changes": "Zurücksetzen", + "save-changes": "Änderungen speichern", "success": { - "generic": "Entity rules updated!" + "generic": "Die Entitätsregeln wurden aktualisiert." }, - "title": "Entity rule editor", - "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} found in rules" + "title": "Entitätsregeln-Editor", + "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} in Regeln gefunden" }, "error": { "deleted-entity": { @@ -1458,7 +1458,7 @@ "none": "Keine" }, "save": { - "error": "Fehler beim Erstellen der Datei-Attribute!", + "error": "Erstellung der Datei-Attribute fehlgeschlagen.", "label": "Attribute speichern", "success": "{count} Datei-{count, plural, one{Attribut} other{Attribute}} erfolgreich erstellt!" }, @@ -1489,7 +1489,7 @@ "file-attributes-listing": { "action": { "delete": "Attribut löschen", - "edit": "Attribute bearbeiten" + "edit": "Attribut bearbeiten" }, "add-new": "Neues Attribut", "bulk-actions": { @@ -1551,7 +1551,7 @@ "redacted": "Vorschau", "redacted-tooltip": "In der Vorschau sehen Sie nur die Annotationen. Es handelt sich also um eine Vorschau der endgültigen Version. Diese Ansicht ist nur verfügbar, wenn für die Datei keine Änderungen ausstehen und keine Reanalyse erforderlich ist", "standard": "Standard", - "standard-tooltip": "In der Standard-Ansicht des Workloads werden alle Hinweise, Schwärzungen, Empfehlungen und Vorschläge angezeigt. In dieser Ansicht ist die Bearbeitung möglich.", + "standard-tooltip": "Standard zeigt alle Annotationstypen und ermöglicht die Bearbeitung.", "tabs": { "annotations": { "hide-skipped": "", @@ -1686,7 +1686,7 @@ "port": "Port", "reply-to": "Antwort an", "reply-to-display-name": "Name für „Antwort an“", - "reply-to-display-name-placeholder": "Anzeigename zu Antwort-E-Mail", + "reply-to-display-name-placeholder": "Anzeigename zu „Antwort an“-E-Mail-Adresse", "reply-to-placeholder": "„Antwort an“-E-Mail-Adresse", "ssl": "SSL aktivieren", "starttls": "StartTLS aktivieren" @@ -1724,7 +1724,7 @@ "enable": "Hilfemodus aktivieren" }, "help-mode": { - "bottom-text": "Hilfe-Modus", + "bottom-text": "Hilfemodus", "clicking-anywhere-on": "Klicken Sie auf eine beliebige Stelle, um zu sehen, welche Bereiche interaktiv sind. Wenn Sie mit der Maus über einen interaktiven Bereich fahren, verändert sich der Mauszeiger. So erkennen Sie, dass ein Element anklickbar ist.", "instructions": "Anleitung für Hilfemodus öffnen", "options": { @@ -1775,7 +1775,7 @@ }, "success": "{operation, select, convert{Markierungen werden konvertiert...} delete{Markierungen erfolgreich entfernt.} other{}} " }, - "highlights": "{color} - {length} {length, plural, one{earmark} other{earmarks}}", + "highlights": "{color} - {length} {length, plural, one{Markierung} other{Markierungen}}", "image-category": { "formula": "Formel", "image": "Bild", @@ -1943,7 +1943,7 @@ }, "notifications-screen": { "category": { - "email-notifications": "E-Mail Benachrichtigungen", + "email-notifications": "E-Mail-Benachrichtigungen", "in-app-notifications": "In-App-Benachrichtigungen" }, "error": { @@ -2120,7 +2120,7 @@ }, "in-dossier": { "description": "Fügen Sie die Schwärzung zu jedem Dokument in {dossierName} hinzu.", - "extraOptionLabel": "In alle Dossiers übernehmen", + "extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen", "label": "Im Dossier schwärzen" }, "only-here": { @@ -2154,9 +2154,9 @@ "list-item-false-positive": "\"{text} im Kontext: \"{context}\"", "options": { "false-positive": { - "description": "''{value}''ist kein ''{type}'' in diesem Kontext: ''{context}''.", + "description": "Markieren Sie die Schwärzung als falsch-positiv. Der Begriff wird in diesem Dossier nicht geschwärzt, wenn er im gleichen Kontext vorkommt.", "description-bulk": "Markieren Sie die Schwärzung als falsch-positiv. Der Begriff wird in diesem Dossier nicht geschwärzt, wenn er im gleichen Kontext vorkommt.", - "label": "Falsch-Positiv" + "label": "In diesem Kontext aus dem Dossier entfernen" }, "in-document": { "description": "", @@ -2276,8 +2276,8 @@ "justification-text": "Dieser Platzhalter wird durch die Schwärzungsbegründung (Text) ersetzt.", "page": "Dieser Platzhalter wird durch die Seitenzahl der Komponente ersetzt.", "paragraph": "Dieser Platzhalter wird durch den Absatz ersetzt, der die Komponente enthält.", - "paragraph-idx": "The placeholder is replaced by the number of the paragraph containing the redaction. Paragraphs are numbered on a per-page basis.", - "value": "This placeholder is replaced by the value that was extracted." + "paragraph-idx": "Dieser Platzhalter wird durch die Nummer des Absatzes ersetzt, in dem sich die Schwärzung befindet. Absätze sind seitenweise nummeriert.", + "value": "Dieser Platzhalter wird durch den extrahierten Wert ersetzt." }, "time": { "h-m": "Dieser Platzhalter wird durch den Zeitpunkt ersetzt, zu dem der Bericht erstellt wurde." @@ -2286,14 +2286,14 @@ }, "invalid-upload": "Ungültiges Upload-Format ausgewählt! Unterstützt werden Dokumente im .xlsx- und im .docx-Format", "multi-file-report": "(Mehrere Dateien)", - "report-documents": "Dokumente für den Bericht", + "report-documents": "Berichtsvorlagen", "setup": "Dieser Platzhalter wird durch die Nummer der Seite ersetzt, auf der sich die Schwärzung befindet.", "table-header": { "description": "Beschreibung", "placeholders": "Platzhalter" }, "title": "Berichte", - "upload-document": "Ein Dokument hochladen" + "upload-document": "Dokument hochladen" }, "reset-filters": "Zurücksetzen", "reset-password-dialog": { @@ -2464,8 +2464,8 @@ "restore": "Wiederherstellen" }, "bulk": { - "delete": "Ausgewählte Dossiert endgültig löschen", - "restore": "Ausgewählte Dossiers wiederherstellen" + "delete": "Ausgewählte Elemente endgültig löschen", + "restore": "Ausgewählte Elemente wiederherstellen" }, "label": "Papierkorb", "no-data": { @@ -2509,7 +2509,7 @@ "dialog": { "actions": { "cancel": "Upload abbrechen", - "re-upload": "Upload erneut versuchen" + "re-upload": "Neuen Upload-Versuch starten" }, "title": "Datei-Uploads ({len})" }, diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index 44997e9ca..921f570ec 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -1141,7 +1141,7 @@ "dossier-watermark-selector": { "heading": "Watermarks on documents", "no-watermark": "There is no watermark defined for the dossier template.
Contact your app admin to define one.", - "preview": "Watermark application on preview documents", + "preview": "Watermark on preview documents", "watermark": "Watermark application on documents" }, "dossiers-type-switch": { @@ -1161,7 +1161,7 @@ }, "download-includes": "Choose what is included at download:", "download-status": { - "error": "The download preparation failed, please recheck the selected files and download option settings.", + "error": "Download generation failed

Please check the selected files and download option settings.", "queued": "Your download has been queued, you can find all your requested downloads here:
My downloads." }, "download-type": { @@ -1350,13 +1350,13 @@ }, "entity-rules-screen": { "error": { - "generic": "Something went wrong... Entity rules update failed!" + "generic": "Error: Entity rules update failed." }, "errors-found": "{errors, plural, one{An error} other{{errors} errors}} found in rules", "revert-changes": "Revert", "save-changes": "Save changes", "success": { - "generic": "Entity rules updated!" + "generic": "Entity rules updated." }, "title": "Entity rule editor", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} found in rules" @@ -1458,7 +1458,7 @@ "none": "None" }, "save": { - "error": "Failed to create file attributes!", + "error": "Failed to create file attributes.", "label": "Save attributes", "success": "{count} file {count, plural, one{attribute} other{attributes}} created successfully!" }, @@ -1551,7 +1551,7 @@ "redacted": "Preview", "redacted-tooltip": "Component preview shows only annotations. Consider this a preview for the final version. This view is only available if the file has no pending changes & doesn't require a reanalysis", "standard": "Standard", - "standard-tooltip": "Standard workload view shows all hints, annotations & recommendations. This view allows editing.", + "standard-tooltip": "Standard shows all annotation types and allows for editing.", "tabs": { "annotations": { "hide-skipped": "", From 305bde5561f961b147ab6c4954a5503f3e9ea669 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Mon, 28 Oct 2024 17:47:37 +0200 Subject: [PATCH 112/125] RED-7340 - Rectangle redactions: Use bulk-local redactions + New dialog design --- .../edit-redaction-dialog/edit-redaction-dialog.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html index d3a0b61f3..ecdfece60 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.html @@ -90,7 +90,7 @@
-
+
Date: Mon, 28 Oct 2024 18:21:03 +0200 Subject: [PATCH 113/125] RED-10244: fix dossier with files not having template field disabled. --- .../edit-dossier-general-info.component.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts index be407e73a..21706f19e 100644 --- a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts +++ b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts @@ -119,7 +119,11 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti private readonly _dossierStatesService: DossierStatesService, ) { effect(() => { - if (this.dossierStatusIdControl() !== this.initialFormValue.dossierStatusId && this.dossierStatusIdControl()) { + const shouldBeDisabled = this.#formValue.find(item => item.key === 'dossierTemplateId')?.disabled; + if ( + (this.dossierStatusIdControl() !== this.initialFormValue.dossierStatusId && this.dossierStatusIdControl()) || + shouldBeDisabled + ) { this.form.controls.dossierTemplateId.disable(); } else { this.form.controls.dossierTemplateId.enable(); @@ -180,7 +184,6 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti get #formValue(): { key: string; value: string; disabled: boolean }[] { const dossier = untracked(this.dossier); const formFieldWithArchivedCheck = value => ({ value, disabled: !dossier.isActive }); - const dossierStateId = untracked(this.dossierStatusIdControl); const states = untracked(this.states); return [ { @@ -190,7 +193,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti { key: 'dossierTemplateId', value: dossier.dossierTemplateId, - disabled: this._dossierStatsService.get(dossier.id).hasFiles || !dossier.isActive || !!dossierStateId, + disabled: this._dossierStatsService.get(dossier.id).hasFiles || !dossier.isActive, }, { key: 'dossierStatusId', @@ -209,7 +212,6 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti } ngOnInit() { - this.#patchFormValue(); if (isJustOne(this._dossierTemplatesService.all)) { this._loadingService.loadWhile( firstValueFrom(this._dossierTemplatesService.loadOnlyDossierTemplates()).then(async () => { @@ -220,7 +222,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti } else { this.#filterInvalidDossierTemplates(); } - + this.#patchFormValue(); if (!this.permissionsService.canEditDossier(this.dossier())) { this.form.disable(); } From 370b1166568c368d01f46ff50c99d40ead155f59 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Tue, 29 Oct 2024 13:11:04 +0200 Subject: [PATCH 114/125] RED-9733: translated initials in workload icons. --- .../file-workload.component.html | 23 +++++++++++++++---- .../file-workload/file-workload.component.ts | 2 ++ .../edit-dossier-dictionary.component.html | 4 +++- .../edit-dossier-dictionary.component.ts | 2 ++ 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/apps/red-ui/src/app/modules/dossier-overview/components/table-item/file-workload/file-workload.component.html b/apps/red-ui/src/app/modules/dossier-overview/components/table-item/file-workload/file-workload.component.html index 18a3391fa..f173c4f07 100644 --- a/apps/red-ui/src/app/modules/dossier-overview/components/table-item/file-workload/file-workload.component.html +++ b/apps/red-ui/src/app/modules/dossier-overview/components/table-item/file-workload/file-workload.component.html @@ -2,18 +2,33 @@ + - - - + + -
diff --git a/apps/red-ui/src/app/modules/dossier-overview/components/table-item/file-workload/file-workload.component.ts b/apps/red-ui/src/app/modules/dossier-overview/components/table-item/file-workload/file-workload.component.ts index e28112268..e177da9fe 100644 --- a/apps/red-ui/src/app/modules/dossier-overview/components/table-item/file-workload/file-workload.component.ts +++ b/apps/red-ui/src/app/modules/dossier-overview/components/table-item/file-workload/file-workload.component.ts @@ -10,6 +10,7 @@ import { AnnotationIconComponent } from '@shared/components/annotation-icon/anno import { AsyncPipe, NgIf } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; import { MatIcon } from '@angular/material/icon'; +import { workloadTranslations } from '@translations/workload-translations'; @Component({ selector: 'redaction-file-workload', @@ -27,6 +28,7 @@ export class FileWorkloadComponent implements OnInit { analysisColor$: Observable; hintColor$: Observable; redactionColor$: Observable; + readonly workloadTranslations = workloadTranslations; constructor( private readonly _userService: UserService, diff --git a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.html b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.html index d2ad69a42..7adbcaea3 100644 --- a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.html +++ b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.html @@ -8,7 +8,9 @@ >
diff --git a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.ts b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.ts index a2b8ce569..28d5e725f 100644 --- a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.ts +++ b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/edit-dossier-dictionary.component.ts @@ -20,6 +20,7 @@ import { AnnotationIconComponent } from '@shared/components/annotation-icon/anno import { MatTooltip } from '@angular/material/tooltip'; import { MatIcon } from '@angular/material/icon'; import { TranslateModule } from '@ngx-translate/core'; +import { workloadTranslations } from '@translations/workload-translations'; @Component({ selector: 'redaction-edit-dossier-dictionary', @@ -47,6 +48,7 @@ export class EditDossierDictionaryComponent implements OnInit { activeEntryType = DictionaryEntryTypes.ENTRY; entriesToDisplay: List = []; readonly entryTypes = DictionaryEntryTypes; + protected readonly workloadTranslations = workloadTranslations; @ViewChild(DictionaryManagerComponent, { static: false }) private readonly _dictionaryManager: DictionaryManagerComponent; constructor( From 5805bb2a3384c6c5ae4ca23255b757e1b4c81b3c Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Tue, 29 Oct 2024 14:19:49 +0200 Subject: [PATCH 115/125] RED-3800: localazy manual sync. --- apps/red-ui/src/assets/i18n/redact/de.json | 12 ++++++------ apps/red-ui/src/assets/i18n/scm/de.json | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index 4a4640044..9544346b1 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -114,6 +114,9 @@ } }, "add-edit-dossier-attribute": { + "error": { + "generic": "Speichern des Attributs fehlgeschlagen." + }, "form": { "label": "Name des Attributs", "label-placeholder": "Namen eingeben", @@ -137,9 +140,6 @@ }, "add-edit-entity": { "form": { - "ai-creation-enabled": "KI-Erstellung aktivieren", - "ai-description": "KI-Beschreibung", - "ai-description-placeholder": "KI-Beschreibung eingeben", "case-sensitive": "Groß-/Kleinschreibung beachten", "color": "Farbe {type, select, redaction{Schwärzung} hint{Hinweis} recommendation{Empfehlung} skipped{Ingorierte Schwärzung} ignored{Ignorierter Hinweis} other{}}", "color-placeholder": "#", @@ -777,7 +777,7 @@ "revert-changes": "Zurücksetzen", "save-changes": "Änderungen speichern", "search": "Suche...", - "select-dictionary": "Wählen Sie oben ein Wörterbuch für den Vergleich aus.", + "select-dictionary": "Wählen Sie aus dem Drop-down oben ein Wörterbuch für den Vergleich aus.", "success": { "generic": "Wörterbuch wurde aktualisiert" } @@ -1252,7 +1252,7 @@ "label": "Dossier-Status", "no-state-placeholder": "Für dieses Dossier ist noch kein Status festgelegt" }, - "due-date": "Enddatum", + "due-date": "Termin", "name": { "label": "Dossier-Name", "placeholder": "Namen eingeben" @@ -2484,7 +2484,7 @@ "time-to-restore": "Verbleibende Zeit für Wiederherstellung" }, "table-header": { - "title": "{length} {length, plural, one{gelöschtes Dossier} other{gelöschte Dossiers}}" + "title": "{length} {length, plural, one{gelöschtes Element} other{gelöschte Elemente}}" } }, "type": "Typ", diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 5dc2c330c..ed0bf757a 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -174,7 +174,7 @@ "name": "Name des Attributs", "name-placeholder": "Namen eingeben", "primary": "Zum Primärattribut machen", - "read-only": "Schreibgeschützt", + "read-only": "Schreibschutz aktivieren", "type": "Typ" }, "save": "Attribut speichern", @@ -234,7 +234,7 @@ "options": { "in-dossier": { "description": "Fügen Sie den Hinweis zu jedem Dokument in {dossierName} hinzu.", - "extraOptionLabel": "In alle Dossiers übernehmen", + "extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen", "label": "Zu Dossier hinzufügen" }, "only-here": { @@ -391,7 +391,7 @@ "hint": "Hinweis", "ignored-hint": "Ignorierter Hinweis", "manual-hint": "Manueller Hinweis", - "manual-redaction": "Manuelle Schwärzung", + "manual-redaction": "Manuelle Annotation", "recommendation": "Empfehlung", "redaction": "Annotation", "skipped": "Übersprungen", @@ -419,7 +419,7 @@ "dialog": { "approver": "Genehmiger", "approvers": "Dossier-Mitglieder", - "make-approver": "Zum Genehmiger ernennen", + "make-approver": "Zum Genehmiger machen", "no-reviewers": "Es wurden noch keine Mitglieder zum Dossier hinzugefügt, die nur die Prüfer-Berechtigung haben.", "reviewers": "Prüfer", "search": "Suche ...", @@ -452,7 +452,7 @@ "title": "Benutzeraktivitäten" }, "categories": { - "all-categories": "Alle Bereiche", + "all-categories": "Alle Kategorien", "audit": "Benutzeraktivitäten", "audit-log": "Aktivitätenprotokoll", "dictionary": "Wörterbuch", @@ -993,7 +993,7 @@ "search": "Name des Dokuments eingeben..." }, "header-actions": { - "download-csv": "CSV-Dateibericht herunterladen", + "download-csv": "CSV-Bericht herunterladen", "edit": "Dossier bearbeiten", "upload-document": "Dokument hochgeladen" }, @@ -1093,7 +1093,7 @@ "analyzed-pages": "{count} {count, plural, one{Seite} other {Seiten}} analysiert", "archived-dossiers": "{count} {count, plural, one{Dossier} other {Dossiers}} im Archiv", "deleted-dossiers": "{count} {count, plural, one{Dossier} other {Dossiers}} im Papierkorb", - "total-documents": "Anzahl der Dokumente", + "total-documents": "Dokumente", "total-people": "{count} {count, plural, one{Benutzer} other {Benutzer}}" }, "dossier-templates": { From e678f6f4b3c4eb07aa0adcde9d62eaf7370d0a15 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Tue, 29 Oct 2024 15:22:48 +0200 Subject: [PATCH 116/125] RED-10275: differentiate available types by applyToAll flag state. --- .../redact-recommendation-dialog.component.ts | 6 +++++- .../redact-text-dialog/redact-text-dialog.component.ts | 6 +++++- .../src/app/services/entity-services/dictionary.service.ts | 5 +++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts index 45422d827..479dd7820 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-recommendation-dialog/redact-recommendation-dialog.component.ts @@ -162,7 +162,11 @@ export class RedactRecommendationDialogComponent } #setDictionaries() { - this.dictionaries = this._dictionaryService.getRedactTextDictionaries(this.#dossier.dossierId, !this.#applyToAllDossiers); + this.dictionaries = this._dictionaryService.getRedactTextDictionaries( + this.#dossier.dossierId, + !this.#applyToAllDossiers, + this.#dossier.dossierTemplateId, + ); } #selectReason() { diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts index be81ad416..8dd73df9b 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.ts @@ -219,7 +219,11 @@ export class RedactTextDialogComponent } #setDictionaries() { - this.dictionaries = this._dictionaryService.getRedactTextDictionaries(this.#dossier.dossierId, !this.#applyToAllDossiers); + this.dictionaries = this._dictionaryService.getRedactTextDictionaries( + this.#dossier.dossierId, + !this.#applyToAllDossiers, + this.#dossier.dossierTemplateId, + ); } #getForm(): FormGroup { diff --git a/apps/red-ui/src/app/services/entity-services/dictionary.service.ts b/apps/red-ui/src/app/services/entity-services/dictionary.service.ts index aa91e81f0..ee5011d4f 100644 --- a/apps/red-ui/src/app/services/entity-services/dictionary.service.ts +++ b/apps/red-ui/src/app/services/entity-services/dictionary.service.ts @@ -152,8 +152,9 @@ export class DictionaryService extends EntitiesService .filter(d => d.model['typeId'] && (d.hasDictionary || d.addToDictionaryAction)); } - getRedactTextDictionaries(dossierId: string, dossierDictionaryOnly: boolean): Dictionary[] { - return this.#extractDossierLevelTypes(dossierId) + getRedactTextDictionaries(dossierId: string, dossierDictionaryOnly: boolean, dossierTemplateId: string): Dictionary[] { + const types = dossierDictionaryOnly ? this.#extractDossierLevelTypes(dossierId) : this.getDictionariesOptions(dossierTemplateId); + return types .filter(d => d.model['typeId'] && !d.hint && d.addToDictionaryAction && (dossierDictionaryOnly || !d.dossierDictionaryOnly)) .sort((a, b) => a.label.localeCompare(b.label)); } From 76b7ec9bc5abc70af7837a00b9d90a4d1f2f8e4f Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Tue, 29 Oct 2024 15:41:21 +0200 Subject: [PATCH 117/125] RED-10320: removed general configuration header subtitle. --- .../general-config-form/general-config-form.component.html | 1 - apps/red-ui/src/assets/i18n/redact/de.json | 1 - apps/red-ui/src/assets/i18n/redact/en.json | 1 - apps/red-ui/src/assets/i18n/scm/de.json | 1 - apps/red-ui/src/assets/i18n/scm/en.json | 1 - 5 files changed, 5 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/screens/general-config/general-config-form/general-config-form.component.html b/apps/red-ui/src/app/modules/admin/screens/general-config/general-config-form/general-config-form.component.html index 1b90795d1..51066d3cf 100644 --- a/apps/red-ui/src/app/modules/admin/screens/general-config/general-config-form/general-config-form.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/general-config/general-config-form/general-config-form.component.html @@ -1,6 +1,5 @@
-
diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index 9544346b1..39f96ad50 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -1697,7 +1697,6 @@ "form": { "forgot-password": "„Passwort vergessen?“-Link auf Login-Seite anzeigen" }, - "subtitle": "", "title": "Allgemeine Einstellungen" }, "subtitle": "SMTP (Simple Mail Transfer Protocol) ermöglicht es Ihnen, Ihre E-Mails über die angegebenen Servereinstellungen zu versenden.", diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index d64b02fb3..5cd9042f7 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -1697,7 +1697,6 @@ "form": { "forgot-password": "Show 'Forgot password' link on login screen" }, - "subtitle": " ", "title": "General configurations" }, "subtitle": "SMTP (Simple Mail Transfer Protocol) enables you to send your e-mails through the specified server settings.", diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index ed0bf757a..9f78185b8 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -1695,7 +1695,6 @@ "form": { "forgot-password": "„Passwort vergessen?“-Link auf Login-Seite anzeigen" }, - "subtitle": "", "title": "Allgemeine Einstellungen" }, "subtitle": "SMTP (Simple Mail Transfer Protocol) ermöglicht es Ihnen, Ihre E-Mails über die angegebenen Servereinstellungen zu versenden.", diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index 921f570ec..eb741958e 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -1695,7 +1695,6 @@ "form": { "forgot-password": "Show 'Forgot password' link on login screen" }, - "subtitle": " ", "title": "General configurations" }, "subtitle": "SMTP (Simple Mail Transfer Protocol) enables you to send your e-mails through the specified server settings.", From e5c3d9c07bdfeb3ab742e36151278681823380f9 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Tue, 29 Oct 2024 16:39:22 +0200 Subject: [PATCH 118/125] RED-10326: fix display of documents in trash on retention capacity chart. --- .../license-retention-capacity.component.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/screens/license/components/license-retention-capacity-usage/license-retention-capacity.component.ts b/apps/red-ui/src/app/modules/admin/screens/license/components/license-retention-capacity-usage/license-retention-capacity.component.ts index 37c5e5bbf..863fab286 100644 --- a/apps/red-ui/src/app/modules/admin/screens/license/components/license-retention-capacity-usage/license-retention-capacity.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/license/components/license-retention-capacity-usage/license-retention-capacity.component.ts @@ -78,9 +78,9 @@ export class LicenseRetentionCapacityComponent { return [ { - data: monthlyData.flatMap(d => d.activeFilesUploadedBytes), - label: this._translateService.instant('license-info-screen.retention-capacity-usage.active-documents'), - ...getLineConfig(ChartGreen, false, 'origin'), + data: monthlyData.flatMap(d => d.trashFilesUploadedBytes), + label: this._translateService.instant('license-info-screen.retention-capacity-usage.trash-documents'), + ...getLineConfig(ChartRed, false, 'origin'), stack: 'storage', }, { @@ -90,9 +90,9 @@ export class LicenseRetentionCapacityComponent { stack: 'storage', }, { - data: monthlyData.flatMap(d => d.trashFilesUploadedBytes), - label: this._translateService.instant('license-info-screen.retention-capacity-usage.trash-documents'), - ...getLineConfig(ChartRed, false, '-1'), + data: monthlyData.flatMap(d => d.activeFilesUploadedBytes), + label: this._translateService.instant('license-info-screen.retention-capacity-usage.active-documents'), + ...getLineConfig(ChartGreen, false, 'origin'), stack: 'storage', }, { From d66ea4e154e792e04d7165e51ec79aa442574c9d Mon Sep 17 00:00:00 2001 From: Kilian Schuettler Date: Wed, 30 Oct 2024 09:17:51 +0100 Subject: [PATCH 119/125] Copy AnotationId to clipboard on ctrl + alt + click --- .../annotations-list/annotations-list.component.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts b/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts index a57c30e43..1b5deaff9 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts @@ -15,6 +15,7 @@ import { JsonPipe, NgForOf, NgIf } from '@angular/common'; import { HighlightsSeparatorComponent } from '../highlights-separator/highlights-separator.component'; import { AnnotationWrapperComponent } from '../annotation-wrapper/annotation-wrapper.component'; import { AnnotationReferencesListComponent } from '../annotation-references-list/annotation-references-list.component'; +import { Clipboard } from '@angular/cdk/clipboard'; @Component({ selector: 'redaction-annotations-list', @@ -54,11 +55,15 @@ export class AnnotationsListComponent extends HasScrollbarDirective { private readonly _annotationManager: REDAnnotationManager, private readonly _listingService: AnnotationsListingService, readonly annotationReferencesService: AnnotationReferencesService, + private readonly clipboard: Clipboard, ) { super(_elementRef); } annotationClicked(annotation: AnnotationWrapper, $event: MouseEvent): void { + if ($event.ctrlKey && $event.altKey) { + this.clipboard.copy(annotation.id); + } if (this._userPreferenceService.isIqserDevMode) { console.log('Selected Annotation:', annotation); } From b1f8453dafdb400f7d9df03a0608ba823b3dda65 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Wed, 30 Oct 2024 12:30:58 +0200 Subject: [PATCH 120/125] RED-10218: fixed fileNameColumn width overlap. --- .../file-attribute.component.html | 7 +++-- .../file-attribute.component.scss | 2 +- .../file-attribute.component.ts | 27 +++++-------------- 3 files changed, 10 insertions(+), 26 deletions(-) diff --git a/apps/red-ui/src/app/modules/dossier-overview/components/file-attribute/file-attribute.component.html b/apps/red-ui/src/app/modules/dossier-overview/components/file-attribute/file-attribute.component.html index f7609306c..1393e2e0f 100644 --- a/apps/red-ui/src/app/modules/dossier-overview/components/file-attribute/file-attribute.component.html +++ b/apps/red-ui/src/app/modules/dossier-overview/components/file-attribute/file-attribute.component.html @@ -9,7 +9,7 @@ @@ -56,13 +56,12 @@ class="edit-input" iqserStopPropagation > - + = 1800 ? 0.85 : 0.7; isInEditMode = false; closedDatepicker = true; @Input({ required: true }) fileAttribute!: IFileAttributeConfig; @@ -66,7 +65,10 @@ export class FileAttributeComponent extends BaseFormComponent implements OnDestr @Input({ required: true }) dossier!: Dossier; @Input() fileNameColumn = false; readonlyAttrs: string[] = []; - @Input() width?: number; + readonly width = input(); + readonly inputFormWidth = computed(() => (this.width() ? this.width() + 'px' : 'unset')); + readonly inputFieldWidth = computed(() => (this.width() ? this.width() - 50 + 'px' : 'unset')); + readonly attributeValueWidth = computed(() => (this.width() ? `${this.width() * 0.9}px` : 'unset')); constructor( router: Router, @@ -99,14 +101,6 @@ export class FileAttributeComponent extends BaseFormComponent implements OnDestr ); } - get editFieldWidth(): string { - return this.width ? `${this.width * this.#widthFactor}px` : 'unset'; - } - - get attributeValueWidth(): string { - return this.width ? `${this.width * 0.9}px` : 'unset'; - } - get isDate(): boolean { return this.fileAttribute.type === FileAttributeConfigTypes.DATE; } @@ -123,15 +117,6 @@ export class FileAttributeComponent extends BaseFormComponent implements OnDestr return this.file.fileAttributes.attributeIdToValue[this.fileAttribute.id]; } - @HostListener('window:resize') - onResize() { - if (window.innerWidth >= 1800) { - this.#widthFactor = 0.85; - } else { - this.#widthFactor = 0.7; - } - } - @Debounce(60) @HostListener('document:click', ['$event']) clickOutside($event: MouseEvent) { From 4695d31c720e2e59dc31b083f41bd110992e0c61 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Wed, 30 Oct 2024 13:34:26 +0200 Subject: [PATCH 121/125] RED-10048 - Improve display of error messages for csv files --- .../upload-status-overlay/upload-status-overlay.component.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/red-ui/src/app/modules/upload-download/upload-status-overlay/upload-status-overlay.component.scss b/apps/red-ui/src/app/modules/upload-download/upload-status-overlay/upload-status-overlay.component.scss index db699df1e..da9b28b2f 100644 --- a/apps/red-ui/src/app/modules/upload-download/upload-status-overlay/upload-status-overlay.component.scss +++ b/apps/red-ui/src/app/modules/upload-download/upload-status-overlay/upload-status-overlay.component.scss @@ -99,6 +99,8 @@ .error-message { margin-top: 2px; color: var(--iqser-primary); + white-space: normal; + word-wrap: break-word; } } From fa7fd420a88e3bf898a65822a169d2a90fc4d4a5 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Wed, 30 Oct 2024 14:22:50 +0200 Subject: [PATCH 122/125] RED-10256 - Bulk-local: Changes should not be filtered + Remove for image-based redactions and hints --- .../edit-redaction-dialog.component.ts | 7 ++++--- .../file-preview/services/annotation-actions.service.ts | 2 -- .../src/app/modules/file-preview/utils/dialog-options.ts | 6 +++++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts index 03753ad6a..645fa6850 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/edit-redaction-dialog/edit-redaction-dialog.component.ts @@ -33,6 +33,7 @@ import { LegalBasisOption, RectangleRedactOption, RectangleRedactOptions, + RedactOrHintOptions, } from '../../utils/dialog-types'; import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component'; import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option'; @@ -88,7 +89,7 @@ export class EditRedactionDialogComponent { label: redaction.value, bold: true }, { label: redaction.typeLabel }, ]); - options = this.allRectangles ? getRectangleRedactOptions('edit') : getEditRedactionOptions(); + options = this.allRectangles ? getRectangleRedactOptions('edit') : getEditRedactionOptions(this.isHint); legalOptions: LegalBasisOption[] = []; dictionaries: Dictionary[] = []; typeSelectOptions: TypeSelectOptions[] = []; @@ -214,7 +215,7 @@ export class EditRedactionDialogComponent const initialReason: LegalBasisOption = this.initialFormValue.reason; const initialLegalBasis = initialReason?.legalBasis ?? ''; const pageNumbers = parseSelectedPageNumbers( - this.form.get('option').value.additionalInput?.value, + this.form.get('option').value?.additionalInput?.value, this.data.file, this.data.annotations[0], ); @@ -226,7 +227,7 @@ export class EditRedactionDialogComponent comment: value.comment, type: value.type, value: this.allRectangles ? value.value : null, - option: value.option.value, + option: value.option?.value ?? RedactOrHintOptions.ONLY_HERE, position, pageNumbers, }); diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts index 020d61af5..863bd1b43 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotation-actions.service.ts @@ -588,8 +588,6 @@ export class AnnotationActionsService { return { value: redaction.value, rectangle: redaction.value === NON_READABLE_CONTENT, - originTypes: [redaction.entry.type], - originLegalBases: [redaction.legalBasis], pageNumbers: dialogResult.pageNumbers, position: dialogResult.position, comment: dialogResult.comment, diff --git a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts index f4390648c..29db18b8e 100644 --- a/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts +++ b/apps/red-ui/src/app/modules/file-preview/utils/dialog-options.ts @@ -30,7 +30,11 @@ const DOCUMENT_ICON = 'iqser:document'; const FOLDER_ICON = 'red:folder'; const REMOVE_FROM_DICT_ICON = 'red:remove-from-dict'; -export const getEditRedactionOptions = (): DetailsRadioOption[] => { +export const getEditRedactionOptions = (hint: boolean): DetailsRadioOption[] => { + if (hint) { + return []; + } + return [ { label: editRedactionTranslations.onlyHere.label, From c787881c769c90ed2678447a88fb68e312f2111d Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Wed, 30 Oct 2024 14:36:06 +0200 Subject: [PATCH 123/125] RED-10198 - missleading error message - creating user with existing email --- .../user-details/user-details.component.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-user-dialog/user-details/user-details.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-user-dialog/user-details/user-details.component.ts index 4bb40a420..f1c04fec6 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-user-dialog/user-details/user-details.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-user-dialog/user-details/user-details.component.ts @@ -101,11 +101,7 @@ export class UserDetailsComponent extends BaseFormComponent implements OnInit { this.closeDialog.emit(true); }) .catch(error => { - if (error.status === HttpStatusCode.Conflict) { - this._toaster.error(_('add-edit-user.error.email-already-used')); - } else { - this._toaster.error(_('add-edit-user.error.generic')); - } + this._toaster.error(null, { error }); this._loadingService.stop(); }); } else { From 1070d62e47ee733962b2fa135f933ed12dc2b751 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Wed, 30 Oct 2024 15:26:51 +0200 Subject: [PATCH 124/125] RED-9663: removed UNASSIGNED option from the status filter. --- .../src/app/translations/file-status-translations.ts | 1 - libs/red-domain/src/lib/files/types.ts | 1 - libs/red-domain/src/lib/shared/sorters/status-sorter.ts | 9 ++++----- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/apps/red-ui/src/app/translations/file-status-translations.ts b/apps/red-ui/src/app/translations/file-status-translations.ts index c4ad99897..f61ac6458 100644 --- a/apps/red-ui/src/app/translations/file-status-translations.ts +++ b/apps/red-ui/src/app/translations/file-status-translations.ts @@ -4,7 +4,6 @@ import { ProcessingFileStatus, WorkflowFileStatus } from '@red/domain'; export const workflowFileStatusTranslations: { [key in WorkflowFileStatus]: string } = { APPROVED: _('file-status.approved'), NEW: _('file-status.new'), - UNASSIGNED: _('file-status.unassigned'), UNDER_APPROVAL: _('file-status.under-approval'), UNDER_REVIEW: _('file-status.under-review'), }; diff --git a/libs/red-domain/src/lib/files/types.ts b/libs/red-domain/src/lib/files/types.ts index 7c5c081a2..2a3844918 100644 --- a/libs/red-domain/src/lib/files/types.ts +++ b/libs/red-domain/src/lib/files/types.ts @@ -5,7 +5,6 @@ export const FILE_ID = 'fileId'; export const WorkflowFileStatuses = { APPROVED: 'APPROVED', NEW: 'NEW', - UNASSIGNED: 'UNASSIGNED', UNDER_APPROVAL: 'UNDER_APPROVAL', UNDER_REVIEW: 'UNDER_REVIEW', } as const; diff --git a/libs/red-domain/src/lib/shared/sorters/status-sorter.ts b/libs/red-domain/src/lib/shared/sorters/status-sorter.ts index 1b9ff671f..dfed58bd0 100644 --- a/libs/red-domain/src/lib/shared/sorters/status-sorter.ts +++ b/libs/red-domain/src/lib/shared/sorters/status-sorter.ts @@ -1,4 +1,4 @@ -import { WorkflowFileStatus } from '../../files/types'; +import { WorkflowFileStatus } from '../../files'; type StatusSorterItem = { key: WorkflowFileStatus } | WorkflowFileStatus | string; type Sorter = Record & { @@ -7,10 +7,9 @@ type Sorter = Record & { export const StatusSorter: Sorter = { NEW: 0, - UNASSIGNED: 1, - UNDER_REVIEW: 2, - UNDER_APPROVAL: 3, - APPROVED: 4, + UNDER_REVIEW: 1, + UNDER_APPROVAL: 2, + APPROVED: 3, byStatus: (a: StatusSorterItem, b: StatusSorterItem): number => { if (typeof a !== typeof b) { throw TypeError('Used different types when calling StatusSorter.byStatus1'); From ada527370f7667ef2080dc7e0307339c517755c4 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Wed, 30 Oct 2024 16:06:13 +0200 Subject: [PATCH 125/125] RED-10331: fixed missing remove-button from pdf-viewer on multi-select. --- .../file-preview/services/pdf-annotation-actions.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/red-ui/src/app/modules/file-preview/services/pdf-annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/pdf-annotation-actions.service.ts index 08ed74c69..45b8ec5d8 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/pdf-annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/pdf-annotation-actions.service.ts @@ -26,7 +26,7 @@ export class PdfAnnotationActionsService { get(annotations: AnnotationWrapper[], annotationChangesAllowed: boolean): IHeaderElement[] { const availableActions: IHeaderElement[] = []; const permissions = this.#getAnnotationsPermissions(annotations); - const sameType = annotations.every(a => a.type === annotations[0].type); + const sameType = annotations.every(a => a.superType === annotations[0].superType); // you can only resize one annotation at a time if (permissions.canResizeAnnotation && annotationChangesAllowed) {