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