From 170c3ae20b1c1ac4c91f81514e51deea341f7381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Tue, 12 Jan 2021 16:36:43 +0200 Subject: [PATCH] Dictionary description and guard improvements --- .../manual-annotation-dialog.component.html | 2 +- .../manual-annotation-dialog.component.ts | 7 -- .../add-edit-dictionary-dialog.component.html | 12 +++ .../add-edit-dictionary-dialog.component.ts | 6 +- .../dictionary-overview-screen.component.html | 5 ++ .../dictionary-overview-screen.component.ts | 35 +++++---- .../project-details.component.scss | 8 -- apps/red-ui/src/app/state/app-state.guard.ts | 25 +++++- .../red-ui/src/app/state/app-state.service.ts | 7 +- apps/red-ui/src/assets/i18n/de.json | 76 +++++++++++++++++-- apps/red-ui/src/assets/i18n/en.json | 7 +- .../src/assets/styles/red-page-layout.scss | 8 ++ tools/auto-i18n/translateCache-de.txt | 31 ++++++++ 13 files changed, 179 insertions(+), 50 deletions(-) diff --git a/apps/red-ui/src/app/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.html b/apps/red-ui/src/app/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.html index 1793e4cf8..e43c5a5a2 100644 --- a/apps/red-ui/src/app/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.html +++ b/apps/red-ui/src/app/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.html @@ -43,7 +43,7 @@ {{ dictionary.label }}
- {{ dictionaryDescriptions[dictionary.label] }} + {{ dictionary.description }}
diff --git a/apps/red-ui/src/app/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts b/apps/red-ui/src/app/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts index c048094b9..dac99e604 100644 --- a/apps/red-ui/src/app/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts @@ -31,13 +31,6 @@ export class ManualAnnotationDialogComponent implements OnInit { redactionDictionaries: TypeValue[] = []; legalOptions: LegalBasisOption[] = []; - public dictionaryDescriptions = { - 'CBI Address': 'Laboratory Address: Redaction in combination with vertebrates', - 'CBI Author': 'Study Author: Redaction in combination with vertebrates', - 'CBI Sponsor': 'Batch Sponsor: Redaction in combination with "batches produced at"', - PII: 'Personal Identification Information: Employee name, email, phone, fax, ...' - }; - get title() { return this._manualAnnotationService.getTitle(this.manualRedactionEntryWrapper.type); } diff --git a/apps/red-ui/src/app/screens/admin/dictionary-listing-screen/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component.html b/apps/red-ui/src/app/screens/admin/dictionary-listing-screen/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component.html index 2f7fa0f80..27919896f 100644 --- a/apps/red-ui/src/app/screens/admin/dictionary-listing-screen/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component.html +++ b/apps/red-ui/src/app/screens/admin/dictionary-listing-screen/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component.html @@ -48,6 +48,18 @@ +
+ + +
+
{{ 'add-edit-dictionary.form.redaction' | translate }} diff --git a/apps/red-ui/src/app/screens/admin/dictionary-listing-screen/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component.ts b/apps/red-ui/src/app/screens/admin/dictionary-listing-screen/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component.ts index db9b3f414..668806a3c 100644 --- a/apps/red-ui/src/app/screens/admin/dictionary-listing-screen/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component.ts +++ b/apps/red-ui/src/app/screens/admin/dictionary-listing-screen/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component.ts @@ -29,7 +29,8 @@ export class AddEditDictionaryDialogComponent { this.dictionary = data.dictionary; this._ruleSetId = data.ruleSetId; this.dictionaryForm = this._formBuilder.group({ - type: [this.dictionary?.type, Validators.required], + type: [this.dictionary?.type, [Validators.required, Validators.minLength(3)]], + description: [this.dictionary?.description], rank: [this.dictionary?.rank, Validators.required], hexColor: [this.dictionary?.hexColor, [Validators.required, Validators.minLength(7)]], hint: [!!this.dictionary?.hint], @@ -72,7 +73,7 @@ export class AddEditDictionaryDialogComponent { observable.subscribe( () => { - this.dialogRef.close({ dictionary: typeValue }); + this.dialogRef.close({ dictionary: this.dictionary ? null : typeValue }); }, (error) => { if (error.status === 409) { @@ -93,6 +94,7 @@ export class AddEditDictionaryDialogComponent { private _formToObject(): TypeValue { return { caseInsensitive: !this.dictionaryForm.get('caseSensitive').value, + description: this.dictionaryForm.get('description').value, hexColor: this.dictionaryForm.get('hexColor').value, hint: this.dictionaryForm.get('hint').value, type: this.dictionaryForm.get('type').value, diff --git a/apps/red-ui/src/app/screens/admin/dictionary-overview-screen/dictionary-overview-screen.component.html b/apps/red-ui/src/app/screens/admin/dictionary-overview-screen/dictionary-overview-screen.component.html index 67f241f79..01f33794d 100644 --- a/apps/red-ui/src/app/screens/admin/dictionary-overview-screen/dictionary-overview-screen.component.html +++ b/apps/red-ui/src/app/screens/admin/dictionary-overview-screen/dictionary-overview-screen.component.html @@ -139,6 +139,11 @@ {{ (dictionary.hint ? 'hint' : 'redaction') | translate }}
+ +
+
+
{{ dictionary.description }}
+
diff --git a/apps/red-ui/src/app/screens/admin/dictionary-overview-screen/dictionary-overview-screen.component.ts b/apps/red-ui/src/app/screens/admin/dictionary-overview-screen/dictionary-overview-screen.component.ts index a95701945..f9d181bf0 100644 --- a/apps/red-ui/src/app/screens/admin/dictionary-overview-screen/dictionary-overview-screen.component.ts +++ b/apps/red-ui/src/app/screens/admin/dictionary-overview-screen/dictionary-overview-screen.component.ts @@ -26,8 +26,6 @@ export class DictionaryOverviewScreenComponent extends ComponentHasChanges { @ViewChild('editorComponent') editorComponent: AceEditorComponent; - dictionary: TypeValue; - activeEditMarkers: any[] = []; activeSearchMarkers: any[] = []; @@ -59,36 +57,37 @@ export class DictionaryOverviewScreenComponent extends ComponentHasChanges { ) { super(_translateService); this._appStateService.activateDictionary(this._activatedRoute.snapshot.params.type, this._activatedRoute.snapshot.params.ruleSetId); - this.dictionary = this._appStateService.activeDictionary; this._initialize(); } private _initialize() { - this._dictionaryControllerService.getDictionaryForType(this.dictionary.type, this.dictionary.ruleSetId).subscribe( - (data) => { - this.initialDictionaryEntries = data.entries.sort((str1, str2) => str1.localeCompare(str2, undefined, { sensitivity: 'accent' })); - this.revert(); - }, - () => { - this.processing = false; - } - ); + if (this.dictionary.type) + this._dictionaryControllerService.getDictionaryForType(this.dictionary.type, this.dictionary.ruleSetId).subscribe( + (data) => { + this.initialDictionaryEntries = data.entries.sort((str1, str2) => str1.localeCompare(str2, undefined, { sensitivity: 'accent' })); + this.revert(); + }, + () => { + this.processing = false; + } + ); + } + + public get dictionary(): TypeValue { + return this._appStateService.activeDictionary; } openEditDictionaryDialog($event: any) { $event.stopPropagation(); - this._dialogService.openAddEditDictionaryDialog(this.dictionary, this.dictionary.ruleSetId, async (newDictionary) => { - if (newDictionary) { - await this._appStateService.loadDictionaryData(); - this.dictionary = this._appStateService.dictionaryData[this.dictionary.type]; - } + this._dialogService.openAddEditDictionaryDialog(this.dictionary, this.dictionary.ruleSetId, async () => { + await this._appStateService.loadDictionaryData(); }); } openDeleteDictionaryDialog($event: any) { this._dialogService.openDeleteDictionaryDialog($event, this.dictionary, this.dictionary.ruleSetId, async () => { await this._appStateService.loadDictionaryData(); - this._router.navigate(['/ui/admin/dictionaries']); + this._router.navigate(['..']); }); } diff --git a/apps/red-ui/src/app/screens/project-overview-screen/project-details/project-details.component.scss b/apps/red-ui/src/app/screens/project-overview-screen/project-details/project-details.component.scss index 9b01c9835..b8e66b45a 100644 --- a/apps/red-ui/src/app/screens/project-overview-screen/project-details/project-details.component.scss +++ b/apps/red-ui/src/app/screens/project-overview-screen/project-details/project-details.component.scss @@ -47,10 +47,6 @@ } } -.mt-8 { - margin-top: 8px; -} - .mt-12 { margin-top: 12px; } @@ -62,7 +58,3 @@ .mt-24 { margin-top: 24px; } - -.pb-32 { - padding-bottom: 32px; -} diff --git a/apps/red-ui/src/app/state/app-state.guard.ts b/apps/red-ui/src/app/state/app-state.guard.ts index b6c3ab4bc..59845752b 100644 --- a/apps/red-ui/src/app/state/app-state.guard.ts +++ b/apps/red-ui/src/app/state/app-state.guard.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot } from '@angular/router'; +import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; import { AppStateService } from './app-state.service'; import { UserService } from '../user/user.service'; @@ -7,7 +7,7 @@ import { UserService } from '../user/user.service'; providedIn: 'root' }) export class AppStateGuard implements CanActivate { - constructor(private readonly _appStateService: AppStateService, private readonly _userService: UserService) {} + constructor(private readonly _appStateService: AppStateService, private readonly _userService: UserService, private readonly _router: Router) {} async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise { await this._userService.loadAllUsersIfNecessary(); @@ -19,6 +19,27 @@ export class AppStateGuard implements CanActivate { await this._appStateService.loadAllProjectsIfNecessary(); } + const { projectId, fileId, ruleSetId, type } = route.params; + + if (projectId && !this._appStateService.getProjectById(projectId)) { + await this._router.navigate(['ui', 'projects']); + return false; + } + + if (fileId && !this._appStateService.getFileById(projectId, fileId)) { + await this._router.navigate(['ui', 'projects', projectId]); + return false; + } + + if (ruleSetId && !this._appStateService.getRuleSetById(ruleSetId)) { + await this._router.navigate(['ui', 'admin', 'project-templates']); + return false; + } + + if (type && !this._appStateService.dictionaryData[ruleSetId][type]) { + await this._router.navigate(['ui', 'admin', 'project-templates', ruleSetId]); + return false; + } return true; } } diff --git a/apps/red-ui/src/app/state/app-state.service.ts b/apps/red-ui/src/app/state/app-state.service.ts index 4c0109137..a550ccd32 100644 --- a/apps/red-ui/src/app/state/app-state.service.ts +++ b/apps/red-ui/src/app/state/app-state.service.ts @@ -576,15 +576,16 @@ export class AppStateService { } async loadDictionaryData() { - this._dictionaryData = {}; + const obj = {}; const observables = []; for (const ruleSet of this.ruleSets) { - this.dictionaryData[ruleSet.ruleSetId] = {}; - observables.push(...this.getDictionaryDataForRuleSetObservables(ruleSet.ruleSetId, this.dictionaryData[ruleSet.ruleSetId])); + obj[ruleSet.ruleSetId] = {}; + observables.push(...this.getDictionaryDataForRuleSetObservables(ruleSet.ruleSetId, obj[ruleSet.ruleSetId])); } await forkJoin(observables).toPromise(); + this._dictionaryData = obj; } async updateDictionaryVersion() { diff --git a/apps/red-ui/src/assets/i18n/de.json b/apps/red-ui/src/assets/i18n/de.json index b1c3d58a7..62a9764fa 100644 --- a/apps/red-ui/src/assets/i18n/de.json +++ b/apps/red-ui/src/assets/i18n/de.json @@ -454,6 +454,8 @@ "hints": "Tipp Wörterbücher" }, "annotation-type": { + "recommendation": "Empfehlung", + "remove-only-here": "Ausstehende Entfernung (nur hier)", "add-dictionary": "Ausstehend zum Wörterbuch hinzufügen", "remove-dictionary": "Ausstehend aus dem Wörterbuch entfernen", "suggestion-add-dictionary": "Vorgeschlagenes Wörterbuch hinzufügen", @@ -463,7 +465,7 @@ "ignore": "Ignorieren", "hint": "Hinweis", "redaction": "Redaktion", - "manual": "Manuelle Redaktion", + "manual-redaction": "Manuelle Redaktion", "declined-suggestion": "Abgelehnter Vorschlag" }, "manual-annotation": { @@ -545,6 +547,8 @@ "name": "Wörterbuchname", "name-placeholder": "Name eingeben", "name-hint": "Kann nach dem Speichern nicht bearbeitet werden.", + "description": "Beschreibung", + "description-placeholder": "Beschreibung eingeben", "rank": "Rang", "rank-placeholder": "1000", "color": "Hex Farbe", @@ -560,6 +564,20 @@ }, "save": "Wörterbuch speichern" }, + "add-edit-project-template": { + "title": { + "edit": "Bearbeiten Sie die {{name}} Projektvorlage", + "new": "Projektvorlage erstellen" + }, + "form": { + "name": "Name der Projektvorlage", + "name-placeholder": "Name eingeben", + "description": "Beschreibung", + "description-placeholder": "Beschreibung eingeben", + "valid-from": "Gültig ab" + }, + "save": "Projektvorlage speichern" + }, "dictionary-overview": { "action": { "delete": "Wörterbuch löschen", @@ -577,7 +595,10 @@ "search": "Suche...", "save-changes": "Änderungen speichern", "revert-changes": "Zurückkehren", - "compare": "Vergleichen Sie" + "compare": "Vergleichen Sie", + "dictionary-details": { + "description": "Beschreibung" + } }, "dictionary-listing": { "action": { @@ -597,9 +618,34 @@ }, "table-col-names": { "type": "Art", + "order-of-importance": "Reihenfolge der Wichtigkeit", "hint-redaction": "Hinweis / Redaktion" }, - "search": "Suche..." + "search": "Suche...", + "no-data": { + "title": "Es gibt noch keine Wörterbücher.", + "action": "Neues Wörterbuch" + } + }, + "project-templates": "Projektvorlagen", + "project-templates-listing": { + "table-header": { + "title": "{{Länge}} Projektvorlagen" + }, + "entries": "{{Länge}} Einträge", + "dictionaries": "{{Länge}} Wörterbücher", + "action": { + "delete": "Vorlage löschen", + "edit": "Vorlage bearbeiten" + }, + "add-new": "Neue Projektvorlage", + "search": "Suche...", + "table-col-names": { + "name": "Name", + "created-by": "Erstellt von", + "created-on": "Erstellt am", + "modified-on": "Geändert am" + } }, "user-listing": { "table-header": { @@ -627,18 +673,20 @@ }, "watermark-screen": { "form": { - "text": "Text", + "text-placeholder": "Text eingeben", "opacity": "Opazität", "color": "Farbe", - "font-size": "Schriftgröße" + "font-size": "Schriftgröße", + "font-type": "Schriftart", + "orientation": "Orientierung" }, "action": { - "save": "speichern", + "save": "Änderungen speichern", "revert": "Zurückkehren", "success": "Wasserzeichen aktualisiert!", "error": "Wasserzeichen konnte nicht aktualisiert werden" }, - "title": "Wasserzeichen konfigurieren" + "title": "Wasserzeichen" }, "dictionaries": "Wörterbücher", "user-management": "Benutzerverwaltung", @@ -650,5 +698,17 @@ "mark-unread": "als ungelesen markieren" }, "rule-editor": "Regeleditor", - "watermark": "Wasserzeichen" + "watermark": "Wasserzeichen", + "pending-changes-guard": "WARNUNG: Sie haben nicht gespeicherte Änderungen. Drücken Sie Abbrechen, um zurück zu gehen und diese Änderungen zu speichern, oder OK, um diese Änderungen zu verlieren.", + "reset-filters": "Filter zurücksetzen", + "overwrite-files-dialog": { + "title": "Die Datei existiert bereits!", + "question": "{{Dateiname}} existiert bereits. Was möchten Sie tun?", + "options": { + "overwrite": "Überschreiben", + "no-overwrite": "Bewahren Sie die alte Datei auf", + "cancel": "Alle Uploads abbrechen", + "remember": "Option merken" + } + } } diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index 3bacef518..9d183c2d6 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -551,6 +551,8 @@ "name": "Dictionary Name", "name-placeholder": "Enter Name", "name-hint": "Cannot be edited after saving.", + "description": "Description", + "description-placeholder": "Enter Description", "rank": "Rank", "rank-placeholder": "1000", "color": "Hex Color", @@ -597,7 +599,10 @@ "search": "Search...", "save-changes": "Save Changes", "revert-changes": "Revert", - "compare": "Compare" + "compare": "Compare", + "dictionary-details": { + "description": "Description" + } }, "dictionary-listing": { "action": { diff --git a/apps/red-ui/src/assets/styles/red-page-layout.scss b/apps/red-ui/src/assets/styles/red-page-layout.scss index 3262c59ec..b16d82c3d 100644 --- a/apps/red-ui/src/assets/styles/red-page-layout.scss +++ b/apps/red-ui/src/assets/styles/red-page-layout.scss @@ -186,10 +186,18 @@ body { margin-top: 5px; } +.mt-8 { + margin-top: 8px; +} + .mt-20 { margin-top: 20px; } +.pb-32 { + padding-bottom: 32px; +} + .break-20 { height: 20px; background: transparent; diff --git a/tools/auto-i18n/translateCache-de.txt b/tools/auto-i18n/translateCache-de.txt index 468e3f2fd..dcb5b5e8f 100644 --- a/tools/auto-i18n/translateCache-de.txt +++ b/tools/auto-i18n/translateCache-de.txt @@ -464,3 +464,34 @@ No members yet. Select from the list below.|Noch keine Mitglieder. Wählen Sie aus der folgenden Liste. No members yet. Select from the list below.|Noch keine Mitglieder. Wählen Sie aus der folgenden Liste. +No members yet. +Select from the list below.|Noch keine Mitglieder. Wählen Sie aus der folgenden Liste. +Recommendation|Empfehlung +Pending removal ( only here )|Ausstehende Entfernung (nur hier) +Edit {{name}} Project Template|Bearbeiten Sie die {{name}} Projektvorlage +Create Project Template|Projektvorlage erstellen +Project Template Name|Name der Projektvorlage +Valid from|Gültig ab +Save Project Template|Projektvorlage speichern +Order Of Importance|Reihenfolge der Wichtigkeit +There are no dictionaries yet.|Es gibt noch keine Wörterbücher. +Project Templates|Projektvorlagen +{{length}} project templates|{{Länge}} Projektvorlagen +{{length}} entries|{{Länge}} Einträge +Delete Template|Vorlage löschen +Edit Template|Vorlage bearbeiten +New Project Template|Neue Projektvorlage +Created by|Erstellt von +Created on|Erstellt am +Modified on|Geändert am +Enter text|Text eingeben +Font Type|Schriftart +Orientation|Orientierung +WARNING: You have unsaved changes. Press Cancel to go back and save these changes, or OK to lose these changes.|WARNUNG: Sie haben nicht gespeicherte Änderungen. Drücken Sie Abbrechen, um zurück zu gehen und diese Änderungen zu speichern, oder OK, um diese Änderungen zu verlieren. +Reset Filters|Filter zurücksetzen +File already exists!|Die Datei existiert bereits! +{{filename}} already exists. What do you want to do?|{{Dateiname}} existiert bereits. Was möchten Sie tun? +Overwrite|Überschreiben +Keep old file|Bewahren Sie die alte Datei auf +Cancel all uploads|Alle Uploads abbrechen +Remember option|Option merken