From 8bd22fc9066dcd472707f9648ef6c7f65e6b9ba2 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Tue, 9 Apr 2024 18:50:17 +0300 Subject: [PATCH 1/4] RED-8692 - Automatic code validation in the rule editor --- .../rules/rules-screen/rules-screen.component.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen/rules-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen/rules-screen.component.ts index 174fdaea8..7ee016d00 100644 --- a/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen/rules-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen/rules-screen.component.ts @@ -17,7 +17,7 @@ interface SyntaxError { line: number; column: number; message: string; - warning: boolean; + warning?: boolean; } interface UploadResponse { @@ -43,6 +43,7 @@ export class RulesScreenComponent implements OnInit, ComponentCanDeactivate { automaticLayout: true, readOnly: !this.permissionsService.canEditRules(), glyphMargin: true, + fixedOverflowWidgets: true, }; initialLines: string[] = []; currentLines: string[] = []; @@ -151,10 +152,18 @@ export class RulesScreenComponent implements OnInit, ComponentCanDeactivate { } }, error => { - const errors = this.#mapErrors(error.error); + let errors: SyntaxError[]; + if (error.error?.syntaxErrorMessages) { + errors = this.#mapErrors(error.error); + } else { + const syntaxError: SyntaxError = { message: error.error.message, line: 1, column: 0 }; + errors = this.#mapErrors({ blacklistErrorMessages: [], syntaxErrorMessages: [syntaxError], deprecatedWarnings: [] }); + } this.#drawErrorMarkers(errors); this._loadingService.stop(); - this._toaster.error(rulesScreenTranslations[this.type]['error.generic']); + if (!dryRun) { + this._toaster.error(rulesScreenTranslations[this.type]['error.generic']); + } }, ); } @@ -252,6 +261,7 @@ export class RulesScreenComponent implements OnInit, ComponentCanDeactivate { }, }); }); + this.#errors.set(errors); this.#errorGlyphs.set(this.#codeEditor.deltaDecorations(this.#errorGlyphs(), glyphs)); (window as any).monaco.editor.setModelMarkers(model, model.id, markers); From 15d07f98d7170dc4ece969c759bffc3460827706 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Tue, 9 Apr 2024 19:26:46 +0300 Subject: [PATCH 2/4] RED-8638 - Adapt UI to new manualChanges types --- .../annotation-details.component.ts | 5 + apps/red-ui/src/assets/i18n/redact/de.json | 149 +++++++++--------- apps/red-ui/src/assets/i18n/redact/en.json | 3 +- apps/red-ui/src/assets/i18n/scm/de.json | 149 +++++++++--------- apps/red-ui/src/assets/i18n/scm/en.json | 3 +- 5 files changed, 159 insertions(+), 150 deletions(-) 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 b714ee549..b3b385268 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 @@ -93,6 +93,11 @@ export class AnnotationDetailsComponent implements OnChanges { description: _('annotation-engines.imported'), show: isBasedOn(annotation, Engines.IMPORTED), }, + { + icon: 'red:redaction-changes', + description: _('annotation-engines.manual'), + show: isBasedOn(annotation, Engines.MANUAL), + }, ]; } } diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index 4756ded38..cc15d495a 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -250,9 +250,6 @@ "watermarks": "Watermarks" }, "analysis-disabled": "", - "annotation": { - "pending": "(Pending analysis)" - }, "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" @@ -311,14 +308,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" @@ -331,15 +328,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" }, @@ -358,6 +355,7 @@ "annotation-engines": { "dictionary": "{isHint, select, true{Hint} other{Redaction}} basierend auf Wörterbuch", "imported": "Imported", + "manual": "", "ner": "Redaktion basierend auf KI", "rule": "Schwärzung basierend auf Regel {rule}" }, @@ -371,6 +369,9 @@ "skipped": "Übersprungen", "text-highlight": "Earmark" }, + "annotation": { + "pending": "(Pending analysis)" + }, "archived-dossiers-listing": { "no-data": { "title": "No archived dossiers." @@ -576,18 +577,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 redactions.", "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": { @@ -596,6 +593,10 @@ "question": "Analysis required to detect new redactions 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?", @@ -940,13 +941,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" + }, "start-auto-analysis": "Enable auto-analysis", "stop-auto-analysis": "Stop auto-analysis", "table-col-names": { @@ -1015,14 +1016,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", @@ -1058,6 +1051,14 @@ "title": "{length} {length, plural, one{Dossier-Vorlage} other{Dossier-Vorlagen}}" } }, + "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.", @@ -1243,15 +1244,6 @@ "title": "{length} {length, plural, one{Wörterbuch} other{Wörterbücher}}" } }, - "entity": { - "info": { - "actions": { - "revert": "Revert", - "save": "Save changes" - }, - "heading": "Edit entity" - } - }, "entity-rules-screen": { "error": { "generic": "Something went wrong... Entity rules update failed!" @@ -1266,19 +1258,28 @@ "warning-text": "Warning: experimental feature!", "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": { @@ -1296,12 +1297,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", @@ -1312,6 +1307,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": { @@ -1530,15 +1531,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", @@ -1548,6 +1540,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", @@ -1818,13 +1819,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", @@ -1838,6 +1832,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", @@ -1855,7 +1850,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", @@ -1863,6 +1857,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", @@ -1954,16 +1955,16 @@ "warnings-subtitle": "Do not show again options", "warnings-title": "Prompts and dialogs settings" }, - "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": { @@ -2187,12 +2188,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", @@ -2216,6 +2211,12 @@ "no-match": "Keine Dokumente entsprechen Ihren aktuellen Filtern.", "table-header": "{length} {length, plural, one{Suchergebnis} other{Suchergebnisse}}" }, + "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": { @@ -2467,4 +2468,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 b7b1e5dd1..5019b6fa6 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -355,6 +355,7 @@ "annotation-engines": { "dictionary": "Based on dictionary", "imported": "Imported", + "manual": "Manual", "ner": "Based on AI", "rule": "Based on rule" }, @@ -2467,4 +2468,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 0331d4eea..3dbebf3fd 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -250,9 +250,6 @@ "watermarks": "Watermarks" }, "analysis-disabled": "Analysis disabled", - "annotation": { - "pending": "(Pending analysis)" - }, "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" @@ -311,14 +308,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" @@ -331,15 +328,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" }, @@ -358,6 +355,7 @@ "annotation-engines": { "dictionary": "{isHint, select, true{Hint} other{Redaction}} basierend auf Wörterbuch", "imported": "Annotation is imported", + "manual": "", "ner": "Redaktion basierend auf KI", "rule": "Schwärzung basierend auf Regel {rule}" }, @@ -371,6 +369,9 @@ "skipped": "Übersprungen", "text-highlight": "Earmark" }, + "annotation": { + "pending": "(Pending analysis)" + }, "archived-dossiers-listing": { "no-data": { "title": "No archived dossiers." @@ -576,18 +577,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": { @@ -596,6 +593,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?", @@ -940,13 +941,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" + }, "start-auto-analysis": "Enable auto-analysis", "stop-auto-analysis": "Stop auto-analysis", "table-col-names": { @@ -1015,14 +1016,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", @@ -1058,6 +1051,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.", @@ -1243,15 +1244,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!" @@ -1266,19 +1258,28 @@ "warning-text": "Warning: experimental feature!", "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": { @@ -1296,12 +1297,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", @@ -1312,6 +1307,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": { @@ -1530,15 +1531,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", @@ -1548,6 +1540,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", @@ -1818,13 +1819,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", @@ -1838,6 +1832,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", @@ -1855,7 +1850,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", @@ -1863,6 +1857,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", @@ -1954,16 +1955,16 @@ "warnings-subtitle": "Do not show again options", "warnings-title": "Prompts and dialogs settings" }, - "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": { @@ -2187,12 +2188,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", @@ -2216,6 +2211,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": { @@ -2467,4 +2468,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 3c7eeb618..e9c929495 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -355,6 +355,7 @@ "annotation-engines": { "dictionary": "{isHint, select, true{Hint} other{Annotation}} based on dictionary", "imported": "Annotation is imported", + "manual": "Manual", "ner": "Annotation based on AI", "rule": "Annotation based on rule {rule}" }, @@ -2467,4 +2468,4 @@ } }, "yesterday": "Yesterday" -} \ No newline at end of file +} From 2abf0aefab39e6599c334f88d2fbf60089a09a0c Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Wed, 10 Apr 2024 12:47:15 +0300 Subject: [PATCH 3/4] RED-8711 - check for positions property to be sure it exists and is not null --- apps/red-ui/src/app/services/files/entity-log.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 5bd4bce64..dbc05ea4e 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 @@ -26,7 +26,7 @@ export class EntityLogService extends GenericService { #filterInvalidEntries(entityLogEntry: IEntityLogEntry[]) { return entityLogEntry.filter(entry => { - entry.positions = entry.positions.filter(p => !!p.rectangle?.length); + entry.positions = entry.positions?.filter(p => !!p.rectangle?.length); const hasPositions = !!entry.positions?.length; const isRemoved = entry.state === EntryStates.REMOVED; if (!hasPositions) { From 28f7f9752fad39f48d9012f3000ece60d8d1ea7f Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Wed, 10 Apr 2024 16:04:31 +0300 Subject: [PATCH 4/4] RED-8636: use the new recategorize endpoint & updated success message. --- .../services/annotation-actions.service.ts | 80 ++++++++++--------- .../services/manual-redaction.service.ts | 40 ++++++---- .../annotation-actions-translations.ts | 10 +-- apps/red-ui/src/assets/i18n/redact/de.json | 12 +-- apps/red-ui/src/assets/i18n/redact/en.json | 38 ++++----- apps/red-ui/src/assets/i18n/scm/de.json | 12 +-- apps/red-ui/src/assets/i18n/scm/en.json | 12 +-- libs/red-domain/src/lib/annotations/types.ts | 3 +- .../redaction-log/recategorization.request.ts | 3 + 9 files changed, 101 insertions(+), 109 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 23a115d14..a5e7058b4 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 @@ -16,7 +16,7 @@ import { 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, zip } from 'rxjs'; +import { firstValueFrom, Observable } from 'rxjs'; import { getFirstRelevantTextPart } from '../../../utils'; import { AnnotationDrawService } from '../../pdf-viewer/services/annotation-draw.service'; import { REDAnnotationManager } from '../../pdf-viewer/services/annotation-manager.service'; @@ -32,6 +32,7 @@ import { ResizeRedactionDialogComponent } from '../dialogs/resize-redaction-dial import { RemoveRedactionOptions } from '../utils/dialog-options'; import { EditRedactionData, + EditRedactResult, RemoveRedactionData, RemoveRedactionPermissions, RemoveRedactionResult, @@ -101,47 +102,34 @@ export class AnnotationActionsService { }; const result = await this.#getEditRedactionDialog(data).result(); - - const requests: Observable[] = []; - if (!result) { return; } - if ( - !this.#isDocumine && - (!annotations.every(annotation => annotation.legalBasis === result.legalBasis) || - !annotations.every(annotation => annotation.section === result.section)) - ) { - const changeLegalBasisBody = annotations.map(annotation => ({ - annotationId: annotation.id, - legalBasis: result.legalBasis, - section: result.section ?? annotation.section, - value: result.value ?? annotation.value, - })); - requests.push( - this._manualRedactionService.changeLegalBasis( - changeLegalBasisBody, - dossierId, - fileId, - file().excludedFromAutomaticAnalysis && isUnprocessed, - ), - ); - } - if (result.type && !annotations.every(annotation => annotation.type === result.type)) { - const recategorizeBody: List = annotations.map(annotation => ({ - annotationId: annotation.id, - type: result.type ?? annotation.type, - })); - requests.push( - this._manualRedactionService.recategorizeRedactions( + const recategorizeBody: List = annotations.map(annotation => { + const body = { annotationId: annotation.id, type: result.type ?? annotation.type }; + if (!this.#isDocumine) { + return { + ...body, + legalBasis: result.legalBasis, + section: result.section ?? annotation.section, + value: result.value ?? annotation.value, + }; + } + return body; + }); + + await this.#processObsAndEmit( + this._manualRedactionService + .recategorizeRedactions( recategorizeBody, dossierId, fileId, + this.#getChangedFields(annotations, result), file().excludedFromAutomaticAnalysis && isUnprocessed, - ), - ); - } + ) + .pipe(log()), + ); if (result.comment) { try { @@ -152,11 +140,6 @@ export class AnnotationActionsService { this._toaster.rawError(error.error.message); } } - - if (!requests.length) { - return; - } - await this.#processObsAndEmit(zip(requests).pipe(log())); } async removeRedaction(redactions: AnnotationWrapper[], permissions: AnnotationPermissions) { @@ -498,4 +481,23 @@ export class AnnotationActionsService { isApprover, }; } + + #getChangedFields(annotations: AnnotationWrapper[], result: EditRedactResult) { + const changedFields = []; + if (result.type && !annotations.every(annotation => annotation.type === result.type)) { + changedFields.push('type'); + } + + if (this.#isDocumine) { + return { changes: changedFields.join(', ') }; + } + + if (result.legalBasis && !annotations.every(annotation => annotation.legalBasis === result.legalBasis)) { + changedFields.push('reason'); + } + if (typeof result.section === 'string' && !annotations.every(annotation => annotation.section === result.section)) { + changedFields.push('paragraph/location'); + } + return { changes: changedFields.join(', ') }; + } } 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 e8c7799b1..a86a57ef7 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 @@ -18,7 +18,7 @@ import type { import { dictionaryActionsTranslations, manualRedactionActionsTranslations } from '@translations/annotation-actions-translations'; import { Roles } from '@users/roles'; import { NGXLogger } from 'ngx-logger'; -import { EMPTY, of, OperatorFunction, pipe } from 'rxjs'; +import { EMPTY, of, pipe } from 'rxjs'; import { catchError, tap } from 'rxjs/operators'; function getResponseType(error: boolean, isConflict: boolean) { @@ -62,12 +62,18 @@ export class ManualRedactionService extends GenericService { return this.addAnnotation(recommendations, dossierId, fileId); } - changeLegalBasis(body: List, dossierId: string, fileId: string, includeUnprocessed = false) { - return this.legalBasisChange(body, dossierId, fileId, includeUnprocessed).pipe(this.#showToast('change-legal-basis')); - } - - recategorizeRedactions(body: List, dossierId: string, fileId: string, includeUnprocessed = false) { - return this.recategorize(body, dossierId, fileId, includeUnprocessed).pipe(this.#showToast('change-type')); + recategorizeRedactions( + body: List, + dossierId: string, + fileId: string, + successMessageParameters?: { + [key: string]: string; + }, + includeUnprocessed = false, + ) { + return this.recategorize(body, dossierId, fileId, includeUnprocessed).pipe( + this.#showToast('recategorize-annotation', false, successMessageParameters), + ); } addAnnotation( @@ -131,13 +137,6 @@ export class ManualRedactionService extends GenericService { ); } - legalBasisChange(body: List, dossierId: string, fileId: string, includeUnprocessed = false) { - return this._post( - body, - `${this.#bulkRedaction}/legalBasisChange/${dossierId}/${fileId}?includeUnprocessed=${includeUnprocessed}`, - ).pipe(this.#log('Legal basis change', body)); - } - undo(annotationIds: List, dossierId: string, fileId: string) { const url = `${this._defaultModelPath}/bulk/undo/${dossierId}/${fileId}`; return super.delete(annotationIds, url).pipe(this.#log('Undo', annotationIds)); @@ -165,7 +164,11 @@ export class ManualRedactionService extends GenericService { }); } - #showToast(action: ManualRedactionActions | DictionaryActions, isDictionary = false) { + #showToast( + action: ManualRedactionActions | DictionaryActions, + isDictionary = false, + successMessageParameters?: { [key: string]: string }, + ) { return pipe( catchError((error: unknown) => { const isConflict = (error as HttpErrorResponse).status === HttpStatusCode.Conflict; @@ -175,7 +178,12 @@ export class ManualRedactionService extends GenericService { }); return EMPTY; }), - tap(() => this._toaster.success(getMessage(action, isDictionary), { positionClass: 'toast-file-preview' })), + tap(() => + this._toaster.success(getMessage(action, isDictionary), { + params: successMessageParameters, + positionClass: 'toast-file-preview', + }), + ), ); } diff --git a/apps/red-ui/src/app/translations/annotation-actions-translations.ts b/apps/red-ui/src/app/translations/annotation-actions-translations.ts index fe1b0f8b6..b08871dea 100644 --- a/apps/red-ui/src/app/translations/annotation-actions-translations.ts +++ b/apps/red-ui/src/app/translations/annotation-actions-translations.ts @@ -28,10 +28,6 @@ export const manualRedactionActionsTranslations: Record{type}", + "label": "No longer annotate as ''{type}''", "label-bulk": "" }, "only-here": { - "description": "Do not annotate the term at this position in the current document.", + "description": "Do not annotate ''{value}'' at this position in the current document.", "description-bulk": "Do not auto-annotate the selected terms at this position in the current document.", "label": "Remove here" } @@ -2046,8 +2042,8 @@ "comment-placeholder": "Add remarks or mentions...", "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 term in any document of the current dossier.", + "description-bulk": "Do not recommend the selected terms in any document of the current dossier.", "extraOptionLabel": "Apply to all active and future dossiers", "label": "Remove from dossier" }, @@ -2059,7 +2055,7 @@ "label": "Remove from dossier in this context" }, "in-dossier": { - "description": "Do not {type, select, hint{annotate} other{redact}} the selected term in any document of this dossier.", + "description": "Do not {type, select, hint{annotate} other{redact}} the selected term in any document of the current dossier.", "description-bulk": "Do not auto-redact the selected term in this dossier.", "extraOptionLabel": "Apply to all active and future dossiers", "label": "Remove from dossier", diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 3dbebf3fd..a698f9b92 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -288,14 +288,6 @@ "error": "Fehler beim Speichern der Schwärzung: {error}", "success": "Schwärzung hinzugefügt!" }, - "change-legal-basis": { - "error": "Fehler beim Bearbeiten der in der Anmerkung genannten Begründung: {error}", - "success": "In der Anmerkung genannte Begründung wurde bearbeitet." - }, - "change-type": { - "error": "", - "success": "" - }, "force-hint": { "error": "Failed to save hint: {error}", "success": "Hint added!" @@ -304,6 +296,10 @@ "error": "Die Schwärzung konnte nicht gespeichert werden!", "success": "Schwärzung eingefügt!" }, + "recategorize-annotation": { + "error": "", + "success": "" + }, "recategorize-image": { "error": "Rekategorisierung des Bildes gescheitert: {error}", "success": "Bild wurde einer neuen Kategorie zugeordnet." diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index e9c929495..514016196 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -288,14 +288,6 @@ "error": "Failed to save annotation: {error}", "success": "Annotation added!" }, - "change-legal-basis": { - "error": "Failed to edit annotation reason: {error}", - "success": "Annotation reason was edited." - }, - "change-type": { - "error": "", - "success": "" - }, "force-hint": { "error": "Failed to save hint: {error}", "success": "Hint added!" @@ -304,6 +296,10 @@ "error": "Failed to save annotation: {error}", "success": "Annotation added!" }, + "recategorize-annotation": { + "error": "", + "success": "" + }, "recategorize-image": { "error": "Failed to recategorize image: {error}", "success": "Image recategorized." diff --git a/libs/red-domain/src/lib/annotations/types.ts b/libs/red-domain/src/lib/annotations/types.ts index b9c5f79b0..97355218a 100644 --- a/libs/red-domain/src/lib/annotations/types.ts +++ b/libs/red-domain/src/lib/annotations/types.ts @@ -6,12 +6,11 @@ export type ManualRedactionActions = | 'add' | 'remove' | 'remove-hint' - | 'change-legal-basis' | 'recategorize-image' | 'undo' | 'force-redaction' | 'force-hint' - | 'change-type'; + | 'recategorize-annotation'; export const AnnotationIconTypes = { square: 'square', 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 6c374d977..5892fd7a4 100644 --- a/libs/red-domain/src/lib/redaction-log/recategorization.request.ts +++ b/libs/red-domain/src/lib/redaction-log/recategorization.request.ts @@ -2,4 +2,7 @@ export interface IRecategorizationRequest { readonly annotationId?: string; readonly comment?: string; readonly type?: string; + readonly legalBasis?: string; + readonly section?: string; + readonly value?: string; }