diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7ebac71ca..bb177da4b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,38 +4,40 @@ variables: PROJECT: red-ui DOCKERFILELOCATION: 'docker/$PROJECT/Dockerfile' - include: - project: 'gitlab/gitlab' ref: 'main' file: 'ci-templates/docker_build_nexus_v2.yml' rules: - - if: $CI_PIPELINE_SOURCE != "schedule" + - if: $CI_PIPELINE_SOURCE != "schedule" localazy update: - image: node:20.5 - cache: - - key: - files: - - yarn.lock - 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 - - cd tools/localazy - - yarn install --cache-folder .yarn-cache - - yarn start - - cd ../.. - - git add . - - |- - CHANGES=$(git status --porcelain | wc -l) - if [ "$CHANGES" -gt "0" ] - then - git status - git commit -m "push back localazy update" - git push gitlab_origin HEAD:${CI_COMMIT_REF_NAME} - fi - rules: - - if: $CI_PIPELINE_SOURCE == "schedule" + image: node:20.5 + cache: + - key: + files: + - yarn.lock + 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 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 + - cd ../.. + - git add . + - |- + CHANGES=$(git status --porcelain | wc -l) + if [ "$CHANGES" -gt "0" ] + then + 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 + fi + rules: + - if: $CI_PIPELINE_SOURCE == "schedule" 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; 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/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; diff --git a/apps/red-ui/src/app/models/file/annotation.wrapper.ts b/apps/red-ui/src/app/models/file/annotation.wrapper.ts index fe01347fd..c0f69a8ee 100644 --- a/apps/red-ui/src/app/models/file/annotation.wrapper.ts +++ b/apps/red-ui/src/app/models/file/annotation.wrapper.ts @@ -26,6 +26,12 @@ import { } from '@red/domain'; import { annotationTypesTranslations } from '@translations/annotation-types-translations'; +interface AnnotationContent { + translation: string; + params: { [key: string]: string }; + untranslatedContent: string; +} + export class AnnotationWrapper implements IListable { id: string; superType: SuperType; @@ -36,7 +42,7 @@ export class AnnotationWrapper implements IListable { numberOfComments = 0; firstTopLeftPoint: IPoint; shortContent: string; - content: string; + content: AnnotationContent; value: string; pageNumber: number; dictionaryOperation = false; @@ -279,7 +285,7 @@ export class AnnotationWrapper implements IListable { ); const content = this.#createContent(annotationWrapper, logEntry, isDocumine); - annotationWrapper.shortContent = this.#getShortContent(annotationWrapper, legalBasisList) || content; + annotationWrapper.shortContent = this.#getShortContent(annotationWrapper, legalBasisList) || content.untranslatedContent; annotationWrapper.content = content; const lastRelevantManualChange = logEntry.manualChanges?.at(-1); @@ -311,39 +317,57 @@ export class AnnotationWrapper implements IListable { } static #createContent(annotationWrapper: AnnotationWrapper, logEntry: IEntityLogEntry, isDocumine: boolean) { - let content = ''; + let untranslatedContent = ''; + const params: { [key: string]: string } = {}; if (logEntry.matchedRule) { - content += `Rule ${logEntry.matchedRule} matched${isDocumine ? ':' : ''} \n\n`; + params['hasRule'] = 'true'; + params['matchedRule'] = logEntry.matchedRule.replace(/(^[, ]*)|([, ]*$)/g, ''); + params['ruleSymbol'] = isDocumine ? ':' : ''; + + untranslatedContent += `Rule ${logEntry.matchedRule} matched${isDocumine ? ':' : ''} \n\n`; } if (logEntry.reason) { + params['hasReason'] = 'true'; if (isDocumine && logEntry.reason.slice(-1) === '.') { logEntry.reason = logEntry.reason.slice(0, -1); } - - content += logEntry.reason + '\n\n'; + if (!params['hasRule']) { + params['reason'] = logEntry.reason.substring(0, 1).toUpperCase() + logEntry.reason.substring(1); + } else { + params['reason'] = logEntry.reason; + } + params['reason'] = params['reason'].replace(/(^[, ]*)|([, ]*$)/g, ''); + untranslatedContent += logEntry.reason + '\n\n'; //remove leading and trailing commas and whitespaces - content = content.replace(/(^[, ]*)|([, ]*$)/g, ''); - content = content.substring(0, 1).toUpperCase() + content.substring(1); + untranslatedContent = untranslatedContent.replace(/(^[, ]*)|([, ]*$)/g, ''); + untranslatedContent = untranslatedContent.substring(0, 1).toUpperCase() + untranslatedContent.substring(1); } if (annotationWrapper.legalBasis && !isDocumine) { - content += 'Legal basis: ' + annotationWrapper.legalBasis + '\n\n'; + params['hasLb'] = 'true'; + params['legalBasis'] = annotationWrapper.legalBasis; + untranslatedContent += 'Legal basis: ' + annotationWrapper.legalBasis + '\n\n'; } if (annotationWrapper.hasBeenRemovedByManualOverride) { - content += 'Removed by manual override'; + params['hasOverride'] = 'true'; + untranslatedContent += 'Removed by manual override'; } if (logEntry.section) { + params['hasSection'] = 'true'; + params['sectionSymbol'] = isDocumine ? '' : ':'; + params['shouldLower'] = untranslatedContent.length.toString(); + params['section'] = logEntry.section; let prefix = `In section${isDocumine ? '' : ':'} `; - if (content.length) { + if (untranslatedContent.length) { prefix = ` ${prefix.toLowerCase()}`; } - content += `${prefix} "${logEntry.section}"`; + untranslatedContent += `${prefix} "${logEntry.section}"`; } - return content; + return { translation: _('annotation-content'), params: params, untranslatedContent: untranslatedContent }; } static #getShortContent(annotationWrapper: AnnotationWrapper, legalBasisList: ILegalBasis[]) { 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, @@ -45,43 +73,29 @@ export class UserProfileScreenComponent extends BaseFormComponent implements OnI protected readonly _userPreferenceService: UserPreferenceService, private readonly _changeRef: ChangeDetectorRef, private readonly _toaster: Toaster, + 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 { @@ -106,15 +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(); @@ -125,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/modules/account/utils/dialog-defaults.ts b/apps/red-ui/src/app/modules/account/utils/dialog-defaults.ts index a723d5878..1ce97d73e 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,18 @@ 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, + RectangleRedactOptions, + RedactOrHintOptions, + RemoveRedactionOptions, +} from '../../file-preview/utils/dialog-types'; export const SystemDefaults = { + RECTANGLE_REDACT_DEFAULT: RectangleRedactOptions.ONLY_THIS_PAGE, 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 +35,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/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/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,38 +89,38 @@ 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); }) .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 { - 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 +131,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/app/modules/admin/screens/audit/audit-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.ts index 9ee61a43e..5a0afc1fb 100644 --- a/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.ts @@ -17,7 +17,7 @@ import { RouterHistoryService } from '@services/router-history.service'; import { auditCategoriesTranslations } from '@translations/audit-categories-translations'; import { Roles } from '@users/roles'; import { applyIntervalConstraints } from '@utils/date-inputs-utils'; -import { Dayjs } from 'dayjs'; +import dayjs, { Dayjs } from 'dayjs'; import { firstValueFrom } from 'rxjs'; import { AdminDialogService } from '../../services/admin-dialog.service'; import { AuditService } from '../../services/audit.service'; @@ -139,16 +139,9 @@ export class AuditScreenComponent extends ListingComponent implements OnI const promises = []; const category = this.form.get('category').value; const userId = this.form.get('userId').value; - const from = this.form.get('from').value; - let to = this.form.get('to').value; - if (to) { - const hoursLeft = new Date(to).getHours(); - const minutesLeft = new Date(to).getMinutes(); - to = to - .clone() - .add(24 - hoursLeft - 1, 'h') - .add(60 - minutesLeft - 1); - } + const from = this.form.get('from').value ? dayjs(this.form.get('from').value).startOf('day').toISOString() : null; + const to = this.form.get('to').value ? dayjs(this.form.get('to').value).endOf('day').toISOString() : null; + const logsRequestBody: IAuditSearchRequest = { pageSize: PAGE_SIZE, page: page, 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 { this._loadingService.stop(); - this._toaster.error(_('add-edit-dossier-attribute.error.generic'), { error }); + this._toaster.rawError(error.error.message); return undefined; }); 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); 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/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..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 @@ -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,15 +19,17 @@ 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) { - if (child.changed) { + if (child?.changed) { return true; } } @@ -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 { 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/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..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 @@ -17,8 +17,17 @@ type="text" />
+
+ +
{{ this.technicalName() || '-' }}
+ +
-
+
-
+
+ + + + +
+
+
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..2826b01a4 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): void { - this.#applyToAllDossiers = option.extraOption.checked; + this.#applyToAllDossiers = option.additionalCheck.checked; this.#setDictionaries(); if (this.#applyToAllDossiers && this.form.get('dictionary').value) { @@ -153,7 +176,7 @@ export class AddHintDialogComponent extends IqserDialogComponent d.type === selectedDictionaryType); - this.options[1].extraOption.disabled = selectedDictionary.dossierDictionaryOnly; + this.options[1].additionalCheck.disabled = selectedDictionary.dossierDictionaryOnly; } } @@ -200,7 +223,7 @@ export class AddHintDialogComponent extends IqserDialogComponent implements OnInit { - readonly #dossier: Dossier; readonly roles = Roles; readonly iconButtonTypes = IconButtonTypes; readonly redactedTexts: string[]; dictionaries: Dictionary[] = []; form: UntypedFormGroup; + readonly #dossier: Dossier; constructor( private readonly _activeDossiersService: ActiveDossiersService, @@ -60,7 +60,7 @@ export class EditAnnotationDialogComponent private readonly _formBuilder: FormBuilder, ) { super(); - this.#dossier = _activeDossiersService.find(this.data.dossierId); + this.#dossier = this._activeDossiersService.find(this.data.dossierId); const annotations = this.data.annotations; this.redactedTexts = annotations.map(annotation => annotation.value); this.form = this.#getForm(); @@ -83,10 +83,6 @@ export class EditAnnotationDialogComponent this.#setTypes(); } - reasonChanged() { - this.form.patchValue({ reason: this.dictionaries.find(d => d.type === SuperTypes.ManualRedaction) }); - } - save(): void { const value = this.form.value; this.dialogRef.close({ @@ -106,8 +102,4 @@ export class EditAnnotationDialogComponent type: [sameType ? this.data.annotations[0].type : null], }); } - - #allRectangles() { - return this.data.annotations.reduce((acc, a) => acc && a.AREA, true); - } } 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..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 @@ -6,16 +6,23 @@ class="dialog-header heading-l" >
-
-
+
+
-
+ + +
@@ -83,7 +90,7 @@
-
+
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 4a0e68714..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 @@ -5,7 +5,6 @@ import { MatDialogClose } from '@angular/material/dialog'; import { MatFormField } from '@angular/material/form-field'; import { MatOption, MatSelect, MatSelectTrigger } from '@angular/material/select'; import { MatTooltip } from '@angular/material/tooltip'; -import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option'; import { CircleButtonComponent, HasScrollbarDirective, @@ -26,10 +25,20 @@ import { SelectedAnnotationsTableComponent, ValueColumn, } from '../../components/selected-annotations-table/selected-annotations-table.component'; -import { DialogHelpModeKeys } from '../../utils/constants'; -import { getEditRedactionOptions } from '../../utils/dialog-options'; -import { EditRedactionData, EditRedactResult, RedactOrHintOption } from '../../utils/dialog-types'; -import { LegalBasisOption } from '../manual-redaction-dialog/manual-annotation-dialog.component'; +import { getEditRedactionOptions, getRectangleRedactOptions } from '../../utils/dialog-options'; +import { + EditRedactionData, + EditRedactionOption, + EditRedactResult, + 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'; +import { validatePageRange } from '../../utils/form-validators'; +import { parseRectanglePosition, parseSelectedPageNumbers, prefillPageRange } from '../../utils/enhance-manual-redaction-request.utils'; interface TypeSelectOptions { type: string; @@ -58,18 +67,16 @@ interface TypeSelectOptions { HelpButtonComponent, MatDialogClose, HasScrollbarDirective, + DetailsRadioComponent, ], }) export class EditRedactionDialogComponent extends IqserDialogComponent implements OnInit { - readonly #dossier = inject(ActiveDossiersService).find(this.data.dossierId); - readonly #applyToAllDossiers = this.data.applyToAllDossiers; - protected readonly roles = Roles; + readonly ignoredKeys = ['option', 'comment']; readonly annotations = this.data.annotations; readonly iconButtonTypes = IconButtonTypes; - readonly isModifyDictionary = this.annotations.every(annotation => annotation.isModifyDictionary); readonly isImage = this.annotations.reduce((acc, next) => acc && next.isImage, true); readonly redactedTexts = !this.isImage ? this.annotations.map(annotation => annotation.value).filter(value => !!value) : null; readonly isManualRedaction = this.annotations.some(annotation => annotation.type === SuperTypes.ManualRedaction); @@ -77,33 +84,34 @@ 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; + options = this.allRectangles ? getRectangleRedactOptions('edit') : getEditRedactionOptions(this.isHint); legalOptions: LegalBasisOption[] = []; dictionaries: Dictionary[] = []; typeSelectOptions: TypeSelectOptions[] = []; readonly form = this.#getForm(); hasTypeChanged = false; initialReasonDisabled = this.someSkipped; + protected readonly roles = Roles; + readonly #dossier = inject(ActiveDossiersService).find(this.data.dossierId); constructor( private readonly _justificationsService: JustificationsService, private readonly _dictionaryService: DictionaryService, ) { super(); + + if (this.allRectangles) { + prefillPageRange( + this.data.annotations[0], + this.data.allFileAnnotations, + this.options as DetailsRadioOption[], + ); + } } get displayedDictionaryLabel() { @@ -153,20 +161,18 @@ export class EditRedactionDialogComponent return this.annotations.length > 1; } - get helpButtonKey() { - if (this.isHint) { - return DialogHelpModeKeys.HINT_EDIT; - } - if (this.someSkipped) { - return DialogHelpModeKeys.SKIPPED_EDIT; - } - return DialogHelpModeKeys.REDACTION_EDIT; - } - get sameType() { 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)); @@ -188,7 +194,6 @@ export class EditRedactionDialogComponent typeChanged() { const selectedDictionaryType = this.form.controls.type.value; - this.#setOptions(selectedDictionaryType); const initialReason = this.form.get('type').value === this.initialFormValue.type && !this.initialReasonDisabled; if (this.redactBasedTypes.includes(selectedDictionaryType) || initialReason) { @@ -202,19 +207,29 @@ export class EditRedactionDialogComponent } else { this.form.controls.reason.disable(); } - this.form.patchValue({ reason: null, option: null }); + this.form.patchValue({ reason: null }); } save() { 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, comment: value.comment, type: value.type, value: this.allRectangles ? value.value : null, + option: value.option?.value ?? RedactOrHintOptions.ONLY_HERE, + position, + pageNumbers, }); } @@ -239,22 +254,6 @@ export class EditRedactionDialogComponent } } - #setOptions(type: string, reasonChanged = false) { - const selectedDictionary = this.dictionaries.find(d => d.type === type); - this.options = getEditRedactionOptions( - this.#dossier.dossierName, - this.#applyToAllDossiers, - !!selectedDictionary?.dossierDictionaryOnly, - this.isModifyDictionary, - ); - this.form.patchValue( - { - option: !this.isModifyDictionary || reasonChanged ? this.options[0] : this.options[1], - }, - { emitEvent: false }, - ); - } - #getForm() { const sameSection = this.annotations.every(annotation => annotation.section === this.annotations[0].section); return new FormGroup({ @@ -265,7 +264,10 @@ export class EditRedactionDialogComponent disabled: this.isImported, }), section: new FormControl({ value: sameSection ? this.annotations[0].section : null, disabled: this.isImported }), - option: new FormControl(null), + 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/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..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 @@ -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..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,21 +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'; - -export interface LegalBasisOption { - label?: string; - legalBasis?: string; - description?: string; -} +import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component'; 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, @@ -55,24 +52,21 @@ const DOCUMINE_LEGAL_BASIS = 'n-a.'; CircleButtonComponent, NgForOf, HelpButtonComponent, + DetailsRadioComponent, ], }) -export class ForceAnnotationDialogComponent extends BaseDialogComponent implements OnInit { +export class ForceAnnotationDialogComponent + extends IqserDialogComponent + implements OnInit +{ readonly isDocumine = getConfig().IS_DOCUMINE; + readonly options: DetailsRadioOption[]; - readonly tableColumns = [ - { - label: 'Value', - show: true, - }, - { - label: 'Type', - show: true, - }, - ]; - readonly tableData: ValueColumn[][] = this._data.annotations.map(redaction => [ - { label: redaction.value, show: true, bold: true }, - { label: redaction.typeLabel, show: true }, + readonly form: FormGroup; + readonly tableColumns: ValueColumn[] = [{ label: 'Value' }, { label: 'Type' }]; + readonly tableData: ValueColumn[][] = this.data.annotations.map(redaction => [ + { label: redaction.value, bold: true }, + { label: redaction.typeLabel }, ]); legalOptions: LegalBasisOption[] = []; @@ -80,20 +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); + 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 { @@ -110,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, @@ -121,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 }); } } @@ -130,13 +127,14 @@ 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), }); } @@ -145,6 +143,8 @@ 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/manual-redaction-dialog/manual-annotation-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.html deleted file mode 100644 index e5c522316..000000000 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.html +++ /dev/null @@ -1,129 +0,0 @@ -
- -
- -
-
- -
- {{ form.get('selectedText').value }} - -
- - -
- -
- -
- -
- - - - - - {{ displayedDictionaryLabel }} - - {{ dictionary.label }} - - - -
- -
- - - - - {{ option.label }} - - - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - {{ '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 deleted file mode 100644 index 970bd01d9..000000000 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts +++ /dev/null @@ -1,235 +0,0 @@ -import { Component, Inject, OnInit } 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'; -import { - BaseDialogComponent, - CircleButtonComponent, - HasScrollbarDirective, - IconButtonComponent, - IqserDenyDirective, - IqserPermissionsService, -} from '@iqser/common-ui'; -import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper'; -import { Dictionary, Dossier, File, IAddRedactionRequest, 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'; -import { MatOption, MatSelect, MatSelectTrigger } from '@angular/material/select'; -import { MatTooltip } from '@angular/material/tooltip'; -import { MatCheckbox } from '@angular/material/checkbox'; - -export interface LegalBasisOption { - label?: string; - legalBasis?: string; - description?: string; -} - -@Component({ - templateUrl: './manual-annotation-dialog.component.html', - styleUrls: ['./manual-annotation-dialog.component.scss'], - standalone: true, - imports: [ - ReactiveFormsModule, - NgIf, - CircleButtonComponent, - TranslateModule, - HasScrollbarDirective, - MatFormField, - MatSelectTrigger, - MatSelect, - MatOption, - NgForOf, - MatTooltip, - IqserDenyDirective, - MatCheckbox, - IconButtonComponent, - ], - 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[] = []; - - constructor( - readonly iqserPermissionsService: IqserPermissionsService, - private readonly _justificationsService: JustificationsService, - private readonly _manualRedactionService: ManualRedactionService, - 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 }, - ) { - super(_dialogRef); - 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.form = this.#getForm(); - this.initialFormValue = this.form.getRawValue(); - } - - get title() { - 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) { - return this.possibleDictionaries.find(d => d.type === dictType).label; - } - return null; - } - - get disabled() { - return this.form.invalid || (this.applyOnMultiplePages && !this.form.get('multiplePages')?.value); - } - - 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, - description: lbm.description, - label: lbm.name, - })); - - 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, - dictionary: this.possibleDictionaries.find(d => d.type === this.form.get('dictionary').value), - }); - } catch (e) { - this._toaster.error(_('manual-annotation.dialog.error')); - } - } - - 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', - ); - } - - #getForm() { - 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], - comment: [null], - classification: ['non-readable content'], - multiplePages: '', - }); - } - - #enhanceManualRedaction(addRedactionRequest: IAddRedactionRequest) { - const legalOption: LegalBasisOption = this.form.get('reason').value; - addRedactionRequest.type = this.form.get('dictionary').value; - 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'; - } - 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; - } - - #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/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 new file mode 100644 index 000000000..64523c836 --- /dev/null +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.html @@ -0,0 +1,62 @@ +
+
+
+ +
+ + +
+ + + + @for (option of legalOptions; track option) { + + {{ option.label }} + + } + + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ +
+ + +
+
+ + +
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..c383543e9 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: 600px; + padding-top: 8px; +} + .apply-on-multiple-pages { min-height: 55px; display: flex; 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 new file mode 100644 index 000000000..fdbc7c7ed --- /dev/null +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component.ts @@ -0,0 +1,185 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, ReactiveFormsModule, UntypedFormGroup, Validators } from '@angular/forms'; +import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; +import { + CircleButtonComponent, + HasScrollbarDirective, + IconButtonComponent, + IqserDenyDirective, + IqserDialogComponent, + Toaster, +} from '@iqser/common-ui'; +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'; +import { firstValueFrom } from 'rxjs'; +import { ManualRedactionService } from '../../services/manual-redaction.service'; +import { NgForOf, NgIf } from '@angular/common'; +import { TranslateModule } from '@ngx-translate/core'; +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 { + 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'; + +export const NON_READABLE_CONTENT = 'non-readable content'; + +@Component({ + templateUrl: './rectangle-annotation-dialog.component.html', + styleUrls: ['./rectangle-annotation-dialog.component.scss'], + standalone: true, + imports: [ + ReactiveFormsModule, + NgIf, + CircleButtonComponent, + TranslateModule, + HasScrollbarDirective, + MatFormField, + MatSelectTrigger, + MatSelect, + MatOption, + NgForOf, + MatTooltip, + IqserDenyDirective, + MatCheckbox, + IconButtonComponent, + DetailsRadioComponent, + ], + providers: [ManualRedactionService], +}) +export class RectangleAnnotationDialog + extends IqserDialogComponent + implements OnInit +{ + readonly #dossier: Dossier; + protected readonly roles = Roles; + protected readonly options: DetailsRadioOption[]; + protected legalOptions: LegalBasisOption[] = []; + + readonly form: UntypedFormGroup; + + constructor( + private readonly activeDossiersService: ActiveDossiersService, + private readonly _justificationsService: JustificationsService, + private readonly _formBuilder: FormBuilder, + private readonly _toaster: Toaster, + ) { + super(); + this.#dossier = this.activeDossiersService.find(this.data.dossierId); + + this.options = getRectangleRedactOptions(); + + this.form = this.#getForm(); + 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(() => { + this.form.get('option')?.updateValueAndValidity(); + }, 0); + } + } + + async ngOnInit() { + const data = await firstValueFrom(this._justificationsService.getForDossierTemplate(this.#dossier.dossierTemplateId)); + this.legalOptions = data.map(lbm => ({ + legalBasis: lbm.reason, + description: lbm.description, + label: lbm.name, + })); + + this.legalOptions.sort((a, b) => a.label.localeCompare(b.label)); + + this.#selectReason(); + } + + save() { + this.#enhanceManualRedaction(this.data.manualRedactionEntryWrapper.manualRedactionEntry); + try { + const annotation = (this.#isMultiplePages ? this.#multiplePagesRectangle : this.data.manualRedactionEntryWrapper) + .manualRedactionEntry; + super.close({ + annotation, + }); + } catch (e) { + this._toaster.error(_('manual-annotation.dialog.error')); + } + } + + #getForm() { + return this._formBuilder.group({ + selectedText: this.data?.manualRedactionEntryWrapper?.manualRedactionEntry?.value, + section: [null], + reason: [null, Validators.required], + comment: [null], + classification: [NON_READABLE_CONTENT], + option: [this.#getOption(SystemDefaults.RECTANGLE_REDACT_DEFAULT), validatePageRange(this.data.file.numberOfPages)], + }); + } + + #enhanceManualRedaction(addRedactionRequest: IAddRedactionRequest) { + const legalOption: LegalBasisOption = this.form.get('reason').value; + addRedactionRequest.type = SuperTypes.ManualRedaction; + if (legalOption) { + addRedactionRequest.reason = legalOption.description; + addRedactionRequest.legalBasis = legalOption.legalBasis; + } + + addRedactionRequest.addToDictionary = false; + const commentValue = this.form.get('comment').value; + addRedactionRequest.comment = commentValue ? (this.#isMultiplePages ? commentValue : { text: commentValue }) : null; + addRedactionRequest.section = this.form.get('section').value; + addRedactionRequest.value = this.form.get('classification').value; + } + + #getOption(option: RectangleRedactOption): DetailsRadioOption { + 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++) { + 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/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/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..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 @@ -22,8 +22,14 @@ 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 { LegalBasisOption } from '../manual-redaction-dialog/manual-annotation-dialog.component'; +import { + LegalBasisOption, + RedactOrHintOption, + RedactOrHintOptions, + RedactRecommendationData, + RedactRecommendationResult, + ResizeOptions, +} from '../../utils/dialog-types'; @Component({ templateUrl: './redact-recommendation-dialog.component.html', @@ -69,19 +75,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( @@ -105,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) { @@ -131,7 +132,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) { @@ -147,7 +148,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; } } @@ -156,11 +157,16 @@ export class RedactRecommendationDialogComponent this.close({ redaction, isMulti: this.isMulti, + bulkLocal: this.isBulkLocal, }); } #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() { @@ -183,7 +189,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.html b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.html index b0906c3e3..698b338c8 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.html +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/redact-text-dialog/redact-text-dialog.component.html @@ -9,14 +9,14 @@ [ngClass]="isEditingSelectedText ? 'flex relative' : 'flex-align-items-center'" >
- +
+
+ + {{ '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..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 @@ -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'; @@ -62,6 +62,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 +159,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 +253,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/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..edae56a05 --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/approve-warning-details/approve-warning-details.component.scss @@ -0,0 +1,15 @@ +@use 'common-mixins'; + +:host { + height: 250px; + margin-bottom: 16px; +} + +.scrollable { + overflow-y: auto; + max-height: 240px; + @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/dictionary-manager/dictionary-manager.component.html b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html index 546c0c2f2..c1429100c 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 }} - - - -
-
-
+ + +
@@ -107,6 +93,7 @@
= this.#dictionaries; + protected readonly _isSearchOpen = signal(false); + 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 +104,6 @@ export class DictionaryManagerComponent implements OnChanges, OnInit { readonly dossierTemplatesService: DossierTemplatesService, ) {} - ngOnInit() { - this.initialDossierTemplateId = this.currentDossierTemplateId; - this.#updateDropdownsOptions(); - } - get selectedDossierTemplate() { return this.#dossierTemplate; } @@ -150,6 +150,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 +186,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 +201,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 +223,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..e2538f236 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 @@ -1,19 +1,19 @@ -import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; +import { Component, Input, model, OnChanges, OnInit, SimpleChanges, untracked } from '@angular/core'; import { LoadingService } from '@iqser/common-ui'; import { EditorThemeService } from '@services/editor-theme.service'; 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,14 +35,11 @@ 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; @Input() canEdit = false; + readonly isSearchOpen = model.required(); /** * Used as [modified] input on diff editor * Shouldn't be updated when editing in diff editor. @@ -51,6 +48,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 +85,16 @@ export class EditorComponent implements OnInit, OnChanges { return this.currentEntries.length; } + async toggleFindPanel(): Promise { + const isFindPanelOpen = untracked(this.isSearchOpen); + const editor = this.showDiffEditor ? this._diffEditor.getOriginalEditor() : this.codeEditor; + if (isFindPanelOpen) { + await (editor.getContribution('editor.contrib.findController') as any).closeFindWidget(); + } else { + await editor.getAction('actions.find').run(); + } + } + onPaste(event: ClipboardEvent) { if ((event.target as HTMLTextAreaElement).ariaRoleDescription === 'editor') { this._loadingService.start(); @@ -122,11 +133,13 @@ export class EditorComponent implements OnInit, OnChanges { this._diffEditor.getModifiedEditor().onDidChangeModelContent(() => { this.value = this._diffEditor.getModel().modified.getValue(); }); + this._initializeFindWidget(editor.getOriginalEditor()); this.#setTheme(); } onCodeEditorInit(editor: MonacoStandaloneCodeEditor): void { this.codeEditor = editor; + this._initializeFindWidget(editor); this.#setTheme(); } @@ -138,6 +151,15 @@ export class EditorComponent implements OnInit, OnChanges { this._editorTextChanged$.next(this.value); } + private _initializeFindWidget(editor: MonacoStandaloneCodeEditor): void { + this.isSearchOpen.set(false); + (editor.getContribution('editor.contrib.findController') as any).getState().onFindReplaceStateChange(event => { + if (event.isRevealed) { + this.isSearchOpen.update(v => !v); + } + }); + } + #getDecorations(newText: string) { const currentEntries = newText.split('\n'); const newDecorations: IModelDeltaDecoration[] = []; 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..47b99ddf9 --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.html @@ -0,0 +1,4 @@ + + {{ 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..42e8e1a68 --- /dev/null +++ b/apps/red-ui/src/app/modules/shared/components/warning-details-panel/warning-details-panel.component.ts @@ -0,0 +1,42 @@ +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 warnings = input(); + readonly filename = input(); + readonly openByDefault = input(); + readonly tableColumns = computed(() => [ + { label: 'Value' }, + { label: 'Type' }, + { label: 'Page' }, + { + 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]), + }, + ]), + ); +} 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/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; } } 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)), diff --git a/apps/red-ui/src/app/services/entity-services/component-mappings.service.ts b/apps/red-ui/src/app/services/entity-services/component-mappings.service.ts index 76be4dd06..e3446d5fe 100644 --- a/apps/red-ui/src/app/services/entity-services/component-mappings.service.ts +++ b/apps/red-ui/src/app/services/entity-services/component-mappings.service.ts @@ -28,6 +28,7 @@ export class ComponentMappingsService 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')); @@ -157,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)); } @@ -249,30 +245,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) { 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/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 ({ ...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/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/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/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/apps/red-ui/src/app/translations/pdf-viewer-translations.ts b/apps/red-ui/src/app/translations/pdf-viewer-translations.ts new file mode 100644 index 000000000..b352e3b79 --- /dev/null +++ b/apps/red-ui/src/app/translations/pdf-viewer-translations.ts @@ -0,0 +1,22 @@ +import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; +import { HeaderElements, HeaderElementType } from '../modules/file-preview/utils/constants'; + +export const viewerHeaderButtonsTranslations: Record = { + leftPanelButton: _('pdf-viewer.header.left-panel-button'), + thumbnailsPanelButton: _('pdf-viewer.header.thumbnails-panel-button'), + outlinesPanelButton: _('pdf-viewer.header.outlines-panel-button'), + outlineMultiSelect: _('pdf-viewer.header.outline-multi-select'), + noOutlinesText: _('pdf-viewer.header.no-outlines-text'), + layersPanelButton: _('pdf-viewer.header.layers-panel-button'), + signaturePanelButton: _('pdf-viewer.header.signature-panel-button'), + noSignaturesText: _('pdf-viewer.header.no-signatures-text'), + zoomInButton: _('pdf-viewer.header.zoom-in-button'), + zoomOutButton: _('pdf-viewer.header.zoom-out-button'), + panToolButton: _('pdf-viewer.header.pan-tool-button'), + selectToolButton: _('pdf-viewer.header.select-tool-button'), + [HeaderElements.COMPARE_BUTTON]: _('pdf-viewer.header.compare-button'), + [HeaderElements.ROTATE_LEFT_BUTTON]: _('pdf-viewer.header.rotate-left-button'), + [HeaderElements.ROTATE_RIGHT_BUTTON]: _('pdf-viewer.header.rotate-right-button'), + [HeaderElements.SHAPE_TOOL_GROUP_BUTTON]: _('pdf-viewer.header.rectangle-tool-button'), + [HeaderElements.LOAD_ALL_ANNOTATIONS]: _('pdf-viewer.header.load-all-annotations'), +}; 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..65359c754 --- /dev/null +++ b/apps/red-ui/src/app/translations/rectangle-redact-translations.ts @@ -0,0 +1,44 @@ +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; + +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/app/translations/redact-text-translations.ts b/apps/red-ui/src/app/translations/redact-text-translations.ts index 76bfadb81..69c774c54 100644 --- a/apps/red-ui/src/app/translations/redact-text-translations.ts +++ b/apps/red-ui/src/app/translations/redact-text-translations.ts @@ -7,13 +7,18 @@ export interface DialogOption { descriptionBulk?: string; extraOptionLabel?: string; extraOptionDescription?: string; + extraOptionPlaceholder?: 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'), @@ -21,20 +26,13 @@ export const redactTextTranslations: Record<'onlyHere' | 'inDossier', DialogOpti }, } as const; -export const editRedactionTranslations: Record<'onlyHere' | 'inDossier', DialogOption> = { +export const editRedactionTranslations: Record<'onlyHere' | 'inDocument', DialogOption> = { onlyHere: { label: _('edit-redaction.dialog.content.options.only-here.label'), description: _('edit-redaction.dialog.content.options.only-here.description'), }, - inDossier: { - label: _('edit-redaction.dialog.content.options.in-dossier.label'), - description: _('edit-redaction.dialog.content.options.in-dossier.description'), - extraOptionLabel: _('edit-redaction.dialog.content.options.in-dossier.extraOptionLabel'), + inDocument: { + label: _('edit-redaction.dialog.content.options.in-document.label'), + description: _('edit-redaction.dialog.content.options.in-document.description'), }, } as const; - -export const editRedactionLabelsTranslations = { - redactedText: _('edit-redaction.dialog.content.redacted-text'), - customRectangle: _('edit-redaction.dialog.content.custom-rectangle'), - imported: _('edit-redaction.dialog.content.imported'), -} as const; 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/app/utils/functions.ts b/apps/red-ui/src/app/utils/functions.ts index 0aca86784..ea763c79a 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 { AbstractControl } 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: AbstractControl) { + 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 0c8874d5c..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'; @@ -27,8 +27,6 @@ export function mainGuard(): AsyncGuard { const logger = inject(NGXLogger); logger.info('[ROUTES] Main resolver started...'); - console.log('main guard'); - const router = inject(Router); inject(FeaturesService).loadConfig(); if (inject(IqserPermissionsService).has(Roles.dossiers.read)) { @@ -40,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(); @@ -53,6 +52,7 @@ export function mainGuard(): AsyncGuard { firstValueFrom(updatedDisplayName$), ]); + await languageService.setInitialLanguage(); const lastDossierTemplate = userPreferenceService.getLastDossierTemplate(); if (lastDossierTemplate && !isUsersAdminOnly) { diff --git a/apps/red-ui/src/assets/config/config.json b/apps/red-ui/src/assets/config/config.json index f00828870..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://dom4.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://dom4.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 053511056..39f96ad50 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -108,6 +108,8 @@ "file": "Mapping-Datei", "name": "Mapping-Name", "name-placeholder": "Mapping-Name", + "quote-char": "Quotation marker", + "quote-char-placeholder": "\"", "version": "Version" } }, @@ -138,7 +140,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 +148,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,11 +209,14 @@ "generic": "Speichern des Benutzers fehlgeschlagen." }, "form": { + "account-setup": "Konfiguration des Benutzerkontos", "email": "E-Mail", "first-name": "Vorname", "last-name": "Nachname", "reset-password": "Passwort zurücksetzen", - "role": "Rolle" + "role": "Rolle", + "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{}}" }, @@ -239,9 +244,9 @@ "label": "Nur hier hinzufügen" } }, - "selected-text": "Ausgewählter Text:", "type": "Typ", - "type-placeholder": "Typ auswählen..." + "type-placeholder": "Typ auswählen...", + "value": "Wert" }, "title": "Hinweis hinzufügen" } @@ -368,7 +373,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,8 +381,9 @@ "removed-manual": "Schwärzung/Hinweis wurde entfernt", "resized": "Schwärzungsbereich wurde geändert" }, + "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", + "dictionary": "Basiert auf Wörterbuch", "dossier-dictionary": "Basiert auf Dossier-Wörterbuch", "imported": "Importiert", "ner": "Basiert auf KI-Modell", @@ -416,7 +422,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" @@ -568,7 +574,7 @@ }, "search": "Nach Name suchen...", "table-col-names": { - "column-labels": "Column labels", + "column-labels": "Spaltenbeschriftungen", "name": "Name", "number-of-lines": "Zeilenzahl", "version": "Version" @@ -637,24 +643,15 @@ }, "confirmation-dialog": { "approve-file": { + "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!" - }, - "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" + "title": "Warnung!", + "warning-reason": { + "legal-basis-missing": "Rechtsgrundlage fehlt", + "pending-changes": "Änderungen stehen aus", + "unmapped-justification": "Nicht gemappte Begründung" + } }, "assign-file-to-me": { "question": { @@ -670,7 +667,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": { @@ -679,7 +676,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?", @@ -727,7 +724,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", @@ -769,7 +766,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", @@ -780,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" } @@ -859,7 +856,7 @@ "date": "Datum", "image": "Bild", "number": "Nummer", - "text": "Freier Text" + "text": "Text" }, "dossier-attributes-listing": { "action": { @@ -951,7 +948,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", @@ -994,8 +991,8 @@ } }, "filters": { - "label": "Name des Dokuments", - "search": "Name des Dokuments..." + "label": "Dokumentname", + "search": "Name des Dokuments eingeben..." }, "header-actions": { "download-csv": "CSV-Bericht herunterladen", @@ -1170,14 +1167,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}}", - "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": { @@ -1239,12 +1237,10 @@ "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}}", - "false-positives": "Falsch-Positive", - "false-recommendation-entries": "{length} {length, plural, one{falsche Empfehlung} other{falsche Empfehlungen}}", - "false-recommendations": "Falsche Empfehlungen", - "to-redact": "Schwärzungen" + "entries-count": "{count} {count, plural, one{Eintrag} other{Einträge}}", + "false-positives": "Falsch-Positive ({count})", + "false-recommendations": "Falsche Empfehlungen ({count})", + "to-redact": "Einträge ({count})" }, "general-info": { "form": { @@ -1256,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" @@ -1268,9 +1264,9 @@ "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": "Wörterbücher", + "dossier-dictionary": "Dossier-Einträge", "dossier-info": "Dossier-Info", "download-package": "Download-Paket", "general-info": "Allgemeine Informationen", @@ -1279,6 +1275,25 @@ }, "side-nav-title": "Konfiguration" }, + "edit-rectangle": { + "dialog": { + "content": { + "options": { + "multiple-pages": { + "description": "Bearbeiten Sie die Schwärzung auf einer Reihe von Seiten", + "extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.", + "extraOptionLabel": "Seiten", + "extraOptionPlaceholder": "z. B. 1-20,22,32", + "label": "Auf mehreren 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": { @@ -1288,18 +1303,15 @@ "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": "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.", - "label": "Typ nur hier ändern" + "label": "Nur hier ändern" } }, "reason": "Grund", @@ -1481,7 +1493,7 @@ "delete": "Attribut löschen", "edit": "Attribut bearbeiten" }, - "add-new": "Neue Attribute", + "add-new": "Neues Attribut", "bulk-actions": { "delete": "Ausgewählte Attribute löschen" }, @@ -1500,7 +1512,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", @@ -1531,7 +1543,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", @@ -1539,7 +1551,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": { @@ -1550,13 +1562,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", @@ -1629,7 +1641,7 @@ "hint": "Nur Hinweise", "image": "Bilder", "none": "Keine Annotationen", - "redaction": "Schwärzungen", + "redaction": "Schwärzung", "updated": "Aktualisiert" }, "filter-menu": { @@ -1649,7 +1661,7 @@ "empty": "Leer", "filter-by": "Filter:", "needs-work": "Annotationen", - "people": "Dossier-Mitglieder" + "people": "Dossier-Mitglied(er)" }, "general-config-screen": { "actions": { @@ -1664,7 +1676,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", @@ -1685,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.", @@ -1784,8 +1795,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" }, @@ -1874,20 +1885,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": "Fügen Sie die Schwärzung auf einer Reihe von Seiten hinzu", + "extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.", + "extraOptionLabel": "Seiten", + "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": "Bereichsschwärzung", - "section": "Absatz / Textstelle", - "text": "Ausgewählter Text:", - "type": "Entität" + "section": "Absatz / Textstelle" }, "error": "Fehler: Ungültige Seitenauswahl", "header": { @@ -2010,14 +2026,34 @@ "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": "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": "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": { @@ -2079,6 +2115,10 @@ "edit-text": "Text bearbeiten", "legal-basis": "Rechtsgrundlage", "options": { + "in-document": { + "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.", "extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen", @@ -2094,7 +2134,8 @@ "revert-text": "Zurück zu ursprünglicher Auswahl", "type": "Typ", "type-placeholder": "Typ auswählen...", - "unchanged": "Ungeändert" + "unchanged": "Ungeändert", + "value": "Wert" }, "title": "Text schwärzen" } @@ -2118,6 +2159,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": "", @@ -2135,6 +2180,25 @@ "title": "{count, plural, one{Annotation} other {Annotationen}} entfernen" } }, + "remove-rectangle": { + "dialog": { + "content": { + "options": { + "multiple-pages": { + "description": "Entfernen Sie die Schwärzung auf einer Reihe von Seiten", + "extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.", + "extraOptionLabel": "Seiten", + "extraOptionPlaceholder": "z. B. 1-20,22,32", + "label": "Auf mehreren 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": { @@ -2154,10 +2218,14 @@ "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" }, + "in-document": { + "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}}.", "description-bulk": "Die ausgewählten Begriffe werden in diesem Dossier nicht {type, select, hint{annotiert} other{automatisch geschwärzt}}.", @@ -2402,7 +2470,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." @@ -2415,7 +2483,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", @@ -2519,10 +2587,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.", @@ -2551,6 +2615,10 @@ "orientation": "Textrichtung", "text-label": "Text für Wasserzeichen", "text-placeholder": "Text eingeben" + }, + "pagination": { + "landscape": "Querformat", + "portrait": "Hochformat" } }, "watermarks-listing": { @@ -2573,7 +2641,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 7070fd39f..5cd9042f7 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -102,6 +102,8 @@ }, "disabled-file-options": "", "form": { + "quote-char": "Quotation marker", + "quote-char-placeholder": "\"", "delimiter": "", "delimiter-placeholder": "", "encoding-type": "", @@ -112,9 +114,6 @@ } }, "add-edit-dossier-attribute": { - "error": { - "generic": "Failed to save attribute." - }, "form": { "label": "Attribute name", "label-placeholder": "Enter name", @@ -138,6 +137,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": "#", @@ -207,11 +209,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" }, @@ -239,9 +244,9 @@ "label": "Add hint only here" } }, - "selected-text": "Selected text:", "type": "Type", - "type-placeholder": "Select type..." + "type-placeholder": "Select type...", + "value": "Value" }, "title": "Add hint" } @@ -262,7 +267,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", @@ -373,6 +378,7 @@ "removed-manual": "Redaction/Hint removed", "resized": "Redaction area has been modified" }, + "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": "Based on dictionary", "dossier-dictionary": "Based on dossier dictionary", @@ -636,25 +642,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": { + "confirmationText": "Approve anyway", + "denyText": "No, cancel", "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!" + "title": "Warning!", + "warning-reason": { + "legal-basis-missing": "Legal basis missing", + "pending-changes": "Pending Changes", + "unmapped-justification": "Unmapped justification" + } }, "assign-file-to-me": { "question": { @@ -780,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" } @@ -951,7 +948,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", @@ -1065,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." @@ -1174,6 +1171,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", @@ -1239,12 +1237,10 @@ "save": "Save", "title": "Edit {label}" }, - "entries": "{length} {length, plural, one{entry} other{entries}} to 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" + "entries-count": "{count} {count, plural, one{entry} other{entries}}", + "false-positives": "False positives ({count})", + "false-recommendations": "False recommendations ({count})", + "to-redact": "Entries ({count})" }, "general-info": { "form": { @@ -1268,9 +1264,9 @@ "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": "Dictionaries", + "dossier-dictionary": "Dossier entries", "dossier-info": "Dossier info", "download-package": "Download package", "general-info": "General information", @@ -1279,6 +1275,25 @@ }, "side-nav-title": "Configurations" }, + "edit-rectangle": { + "dialog": { + "content": { + "options": { + "multiple-pages": { + "description": "Edit redaction on a range of pages", + "extraOptionDescription": "Minus(-) for range and comma(,) for enumeration", + "extraOptionLabel": "Pages", + "extraOptionPlaceholder": "e.g. 1-20,22,32", + "label": "Change on multiple pages" + }, + "only-this-page": { + "description": "Edit redaction only at this position in this document", + "label": "Change only on this page" + } + } + } + } + }, "edit-redaction": { "dialog": { "actions": { @@ -1288,18 +1303,15 @@ "content": { "comment": "Comment", "comment-placeholder": "Add remarks or notes...", - "custom-rectangle": "Custom Rectangle", - "imported": "Imported Redaction", "legal-basis": "Legal basis", "options": { - "in-dossier": { - "description": "Edit redaction in every document in {dossierName}.", - "extraOptionLabel": "Apply to all active and future dossiers", - "label": "Change type in dossier" + "in-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", @@ -1539,7 +1551,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": { @@ -1556,7 +1568,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", @@ -1638,12 +1650,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", @@ -1685,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.", @@ -1874,20 +1885,25 @@ "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": { + "description": "Add redaction on a range of pages", + "extraOptionDescription": "Minus(-) for range and comma(,) for enumeration", + "extraOptionLabel": "Pages", + "extraOptionPlaceholder": "e.g. 1-20,22,32", + "label": "Apply on multiple pages" + }, + "only-this-page": { + "description": "Add redaction only at this position in this document", + "label": "Apply only on this page" + } + }, "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": { @@ -2010,14 +2026,34 @@ "previous": "Prev" }, "pdf-viewer": { + "header": { + "all-annotations-loaded": "All annotations loaded", + "compare-button": "Compare", + "layers-panel-button": "Layers", + "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" + }, "text-popup": { "actions": { "search": "Search for selected text" } - }, - "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" + } }, "permissions-screen": { "dossier": { @@ -2079,6 +2115,10 @@ "edit-text": "Edit text", "legal-basis": "Legal basis", "options": { + "in-document": { + "description": "Add redaction for each instance 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", @@ -2094,7 +2134,8 @@ "revert-text": "Revert to selected text", "type": "Type", "type-placeholder": "Select type...", - "unchanged": "Unchanged" + "unchanged": "Unchanged", + "value": "Value" }, "title": "Redact text" } @@ -2118,6 +2159,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": "", @@ -2135,6 +2180,25 @@ "title": "Remove {count, plural, one{annotation} other {annotations}}" } }, + "remove-rectangle": { + "dialog": { + "content": { + "options": { + "multiple-pages": { + "description": "Remove redaction on a range of pages", + "extraOptionDescription": "Minus(-) for range and comma(,) for enumeration", + "extraOptionLabel": "Pages", + "extraOptionPlaceholder": "e.g. 1-20,22,32", + "label": "Remove on multiple pages" + }, + "only-this-page": { + "description": "Remove redaction only at this position in this document", + "label": "Remove only on this page" + } + } + } + } + }, "remove-redaction": { "dialog": { "actions": { @@ -2158,6 +2222,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 {isImage, select, image{image} other{term}} on any page 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.", @@ -2519,10 +2587,6 @@ "view-as": "View as:", "workflow": "Workflow" }, - "viewer-header": { - "all-annotations-loaded": "All annotations loaded", - "load-all-annotations": "Load all annotations" - }, "watermark-screen": { "action": { "change-success": "Watermark has been updated.", @@ -2551,6 +2615,10 @@ "orientation": "Orientation", "text-label": "Watermark text", "text-placeholder": "Enter text" + }, + "pagination": { + "landscape": "Landscape", + "portrait": "Portrait" } }, "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 dcb68dc0b..9f78185b8 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,26 +95,23 @@ }, "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", + "disabled-file-options": "Aktualisierte Mapping-Datei hochladen", "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!" - }, "form": { "label": "Name des Attributs", "label-placeholder": "Namen eingeben", @@ -126,41 +123,44 @@ }, "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", + "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": "#", - "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": { @@ -174,11 +174,11 @@ "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", - "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,95 +203,98 @@ "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": "Konfiguration des Benutzerkontos", "email": "E-Mail", "first-name": "Vorname", "last-name": "Nachname", "reset-password": "Passwort zurücksetzen", - "role": "Rolle" + "role": "Rolle", + "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 aktiven und zukünftigen 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" } }, - "selected-text": "Selected text:", - "type": "Type", - "type-placeholder": "Select type..." + "type": "Typ", + "type-placeholder": "Typ auswählen...", + "value": "Wert\n" }, - "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": "Analysis disabled", + "analysis-disabled": "Analyse deaktiviert", "annotation": { - "pending": "(Pending analysis)" + "pending": "(Analyse steht aus)" }, "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" }, "convert-highlights": { - "label": "Convert Selected Earmarks" + "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": { @@ -303,41 +306,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": { - "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": "Failed to remove hint: {error}", - "success": "Hint removed!" + "error": "Entfernen des Hinweises fehlgeschlagen: {error}", + "success": "Hinweis wurde entfernt" }, "undo": { "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", @@ -346,78 +349,79 @@ } }, "remove-annotation": { - "remove-redaction": "Remove" + "remove-redaction": "Entfernen" }, "remove-highlights": { - "label": "Remove selected earmarks" + "label": "Ausgewählte Markierungen entfernen" }, "resize": { "label": "Größe ändern" }, "resize-accept": { - "label": "Größe speichern" + "label": "Neue Größe speichern" }, "resize-cancel": { "label": "Größenänderung abbrechen" }, "see-references": { - "label": "See references" + "label": "Referenzen anzeigen" }, "show": "Zeigen", "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 {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{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-redaction": "Manuelle Schwärzung", + "manual-hint": "Manueller Hinweis", + "manual-redaction": "Manuelle Annotation", "recommendation": "Empfehlung", - "redaction": "Schwärzung", + "redaction": "Annotation", "skipped": "Übersprungen", - "text-highlight": "Earmark" + "text-highlight": "Markierung" }, - "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", - "make-approver": "Zum Genehmiger ernennen", - "no-reviewers": "Es gibt noch keine Reviewer.\nBitte aus der Liste unten auswählen.", - "reviewers": "Reviewer", + "approver": "Genehmiger", + "approvers": "Dossier-Mitglieder", + "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 ...", "single-user": "Besitzer" } @@ -436,7 +440,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": { @@ -445,11 +449,11 @@ }, "all-users": "Alle Benutzer", "audit-info-dialog": { - "title": "Audit info" + "title": "Benutzeraktivitäten" }, "categories": { - "all-categories": "Alle Bereiche", - "audit": "Aktivitätenprotokoll", + "all-categories": "Alle Kategorien", + "audit": "Benutzeraktivitäten", "audit-log": "Aktivitätenprotokoll", "dictionary": "Wörterbuch", "document": "Dokument", @@ -459,28 +463,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 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" }, "change-legal-basis-dialog": { @@ -492,17 +496,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", @@ -515,207 +519,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": { - "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": "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": "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": { @@ -727,20 +722,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" } }, @@ -764,7 +759,7 @@ "system-default": "", "title": "" }, - "dictionary": "Wörterbuch", + "dictionary": "Typ", "dictionary-overview": { "compare": { "compare": "Vergleichen", @@ -772,88 +767,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", @@ -868,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", @@ -879,35 +874,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" @@ -916,8 +911,8 @@ "action": "Dossier bearbeiten" }, "filters": { - "label": "Dossiername", - "search": "Dossiername..." + "label": "Dossier-Name", + "search": "Dossier-Namen eingeben..." }, "no-data": { "action": "Neues Dossier", @@ -927,35 +922,35 @@ "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", + "documents-status": "Dokumentenstatus", + "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", - "back-to-new": "Move to 'New'", + "assign-me": "Mir zuweisen", + "assign-reviewer": "Benutzer zuweisen", + "back-to-new": "Nach \"Neu\" verschieben", "bulk": { "delete": "Dokumente löschen", "reanalyse": "Dokumente analysieren" @@ -965,28 +960,28 @@ }, "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" }, "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", @@ -995,14 +990,14 @@ }, "filters": { "label": "Dokumentname", - "search": "Dokumentname..." + "search": "Name des Dokuments eingeben..." }, "header-actions": { - "download-csv": "CSV-Dateibericht herunterladen", + "download-csv": "CSV-Bericht herunterladen", "edit": "Dossier bearbeiten", "upload-document": "Dokument hochgeladen" }, - "import-redactions": "Import annotations", + "import-redactions": "Annotationen importieren", "new-rule": { "toast": { "actions": { @@ -1032,93 +1027,93 @@ "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", - "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}}" + "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}} im Papierkorb", + "total-documents": "Dokumente", + "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!" @@ -1136,48 +1131,49 @@ "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": { "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": { - "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}}", + "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": { @@ -1197,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": { @@ -1211,7 +1207,7 @@ }, "edit-dossier-dialog": { "actions": { - "revert": "Rückgängig machen", + "revert": "Zurücksetzen", "save": "Änderungen speichern", "save-and-close": "Speichern" }, @@ -1239,12 +1235,10 @@ "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}}", - "false-positives": "False positives", - "false-recommendation-entries": "{length} false recommendation {length, plural, one{entry} other{entries}}", - "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": { @@ -1253,10 +1247,10 @@ "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", + "due-date": "Enddatum", "name": { "label": "Dossier-Name", "placeholder": "Namen eingeben" @@ -1265,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", @@ -1279,23 +1273,39 @@ }, "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": { - "cancel": "Cancel", - "save": "Save changes" + "cancel": "Abbrechen", + "save": "Änderungen speichern" }, "content": { - "comment": "Comment", - "comment-placeholder": "Add remarks or mentions...", - "custom-rectangle": "", - "imported": "", + "comment": "Kommentar", + "comment-placeholder": "Bemerkungen oder Notizen hinzufügen...", "legal-basis": "", "options": { - "in-dossier": { + "in-document": { "description": "", - "extraOptionLabel": "", - "label": "" + "label": "In Dokument ändern" }, "only-here": { "description": "", @@ -1303,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": { @@ -1329,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": { @@ -1376,24 +1386,24 @@ } }, "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": "Failed to update file attribute value!", - "success": "File attribute value has been updated successfully!" + "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": { @@ -1407,18 +1417,18 @@ "text": "Freier Text" }, "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": { @@ -1438,9 +1448,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": { @@ -1448,9 +1458,9 @@ "none": "Keine" }, "save": { - "error": "Fehler beim Erstellen der Datei-Attribute!", + "error": "Erstellung der Datei-Attribute fehlgeschlagen.", "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 ..." @@ -1459,7 +1469,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" }, @@ -1471,24 +1481,24 @@ "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": { "action": { "delete": "Attribut löschen", - "edit": "Attribute bearbeiten" + "edit": "Attribut 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." @@ -1504,70 +1514,70 @@ "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.", + "standard-tooltip": "Standard zeigt alle Annotationstypen und ermöglicht die Bearbeitung.", "tabs": { "annotations": { "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", @@ -1576,76 +1586,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": "Nut Hinweise", + "hint": "Nur Hinweise", "image": "Bilder", - "none": "Keine Anmerkungen", - "redaction": "Geschwärzt", + "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" }, "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", @@ -1653,119 +1663,118 @@ }, "general-config-screen": { "actions": { - "save": "Einstellungen speichern", + "save": "Konfiguration speichern", "test-connection": "Verbindung testen" }, "app-name": { - "label": "Name der Applikation", - "placeholder": "RedactManager" + "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-display-name-placeholder": "Anzeigename zu Antwort-E-Mail", - "reply-to-placeholder": "Antwort-E-Mail", + "reply-to": "Antwort an", + "reply-to-display-name": "Name für „Antwort an“", + "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" }, "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" }, "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", + "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": { - "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", - "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", - "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.", - "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}}", + "highlights": "{color} - {length} {length, plural, one{Markierung} other{Markierungen}}", "image-category": { "formula": "Formel", "image": "Bild", @@ -1774,23 +1783,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": { @@ -1798,7 +1807,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" }, @@ -1808,155 +1817,160 @@ "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": { - "email-notifications": "E-Mail Benachrichtigungen", + "email-notifications": "E-Mail-Benachrichtigungen", "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", @@ -1966,221 +1980,273 @@ }, "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", "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 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" } - }, - "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": { - "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": "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 aktiven und zukünftigen 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...", - "unchanged": "" + "type": "Typ", + "type-placeholder": "Typ auswählen...", + "unchanged": "", + "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": "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": "In diesem Kontext aus dem Dossier entfernen" + }, + "in-document": { + "description": "", + "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-placeholder": "Add remarks or mentions...", + "comment": "Kommentar", + "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 {type} \"{value}\" in any document of the current 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.", @@ -2198,19 +2264,19 @@ }, "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.", - "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." + "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": "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." @@ -2219,14 +2285,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", - "setup": "Click the upload button on the right to upload your component report templates.", + "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": { @@ -2242,95 +2308,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", @@ -2344,48 +2410,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" } } @@ -2397,12 +2463,12 @@ "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": { - "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." @@ -2411,19 +2477,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": { @@ -2432,24 +2498,24 @@ "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": { "actions": { "cancel": "Upload abbrechen", - "re-upload": "Upload erneut versuchen" + "re-upload": "Neuen Upload-Versuch starten" }, "title": "Datei-Uploads ({len})" }, "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": { @@ -2463,22 +2529,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": { @@ -2489,98 +2555,98 @@ "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" - }, - "viewer-header": { - "all-annotations-loaded": "All annotations loaded", - "load-all-annotations": "Load all annotations" + "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": { + "landscape": "", + "portrait": "" } }, "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 0679117d1..eb741958e 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..." @@ -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": { @@ -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", @@ -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": "#", @@ -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,14 +204,17 @@ }, "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", "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" }, @@ -227,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": { @@ -239,9 +242,9 @@ "label": "Add hint only here" } }, - "selected-text": "Selected text:", "type": "Type", - "type-placeholder": "Select type..." + "type-placeholder": "Select type...", + "value": "Value" }, "title": "Add hint" } @@ -262,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", @@ -300,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}", @@ -310,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": "", @@ -330,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}", @@ -373,6 +376,7 @@ "removed-manual": "Annotation/Hint removed", "resized": "Annotation area has been modified" }, + "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{Hint} other{Annotation}} based on dictionary", "dossier-dictionary": "Annotation based on dossier dictionary", @@ -478,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" @@ -596,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", @@ -619,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}}." @@ -632,46 +636,37 @@ "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-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": "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", + "unmapped-justification": "Unmapped justification" + } }, "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?", @@ -694,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": { @@ -774,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!" } @@ -790,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": { @@ -816,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" } }, @@ -838,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", @@ -890,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", @@ -902,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": { @@ -986,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", @@ -1065,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": { @@ -1146,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": { @@ -1158,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", @@ -1166,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": { @@ -1174,6 +1169,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", @@ -1239,12 +1235,10 @@ "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}}", - "false-positives": "False positives", - "false-recommendation-entries": "{length} false recommendation {length, plural, one{entry} other{entries}}", - "false-recommendations": "False recommendations", - "to-redact": "To redact" + "entries-count": "{count} {count, plural, one{entry} other{entries}}", + "false-positives": "False positives ({count})", + "false-recommendations": "False recommendations ({count})", + "to-redact": "To redact ({count})" }, "general-info": { "form": { @@ -1265,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", @@ -1279,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": { @@ -1287,15 +1300,12 @@ }, "content": { "comment": "Comment", - "comment-placeholder": "Add remarks or mentions...", - "custom-rectangle": "", - "imported": "", + "comment-placeholder": "Add remarks or notes...", "legal-basis": "", "options": { - "in-dossier": { + "in-document": { "description": "", - "extraOptionLabel": "", - "label": "" + "label": "In Dokument ändern" }, "only-here": { "description": "", @@ -1340,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" @@ -1377,12 +1387,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", @@ -1402,7 +1412,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!" } }, @@ -1438,7 +1448,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}.", @@ -1448,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!" }, @@ -1459,7 +1469,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" }, @@ -1487,8 +1497,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." @@ -1504,7 +1514,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" }, @@ -1518,20 +1528,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", @@ -1541,14 +1551,14 @@ "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": "", "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", @@ -1556,7 +1566,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", @@ -1588,7 +1598,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", @@ -1597,7 +1607,7 @@ }, "file-status": { "analyse": "Analyzing", - "approved": "Done", + "approved": "Approved", "error": "Re-processing required", "figure-detection-analyzing": "", "full-processing": "Processing", @@ -1628,7 +1638,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" }, @@ -1658,7 +1668,7 @@ }, "app-name": { "label": "Display name", - "placeholder": "RedactManager" + "placeholder": "DocuMine" }, "form": { "auth": "Enable authentication", @@ -1685,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.", @@ -1703,7 +1712,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." }, @@ -1715,12 +1724,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": { @@ -1735,7 +1744,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" } }, @@ -1864,8 +1873,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": { @@ -1874,20 +1883,25 @@ "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": { + "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 annotation only at this position in this document", + "label": "Apply only on this page" + } + }, "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": { @@ -1904,16 +1918,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}}}!", @@ -1967,12 +1981,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!", @@ -1981,16 +1995,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" } }, @@ -2010,14 +2024,34 @@ "previous": "Prev" }, "pdf-viewer": { + "header": { + "all-annotations-loaded": "All annotations loaded", + "compare-button": "Compare", + "layers-panel-button": "Layers", + "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" + }, "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{}} annotation tooltips" + } }, "permissions-screen": { "dossier": { @@ -2044,14 +2078,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" }, @@ -2075,13 +2109,17 @@ }, "content": { "comment": "Comment", - "comment-placeholder": "Add remarks or mentions...", + "comment-placeholder": "Add remarks or notes...", "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", + "extraOptionLabel": "Apply to all active and future dossiers", "label": "Redact in dossier" }, "only-here": { @@ -2094,7 +2132,8 @@ "revert-text": "", "type": "Type", "type-placeholder": "Select type...", - "unchanged": "" + "unchanged": "", + "value": "Value" }, "title": "Redact text" } @@ -2109,23 +2148,27 @@ }, "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-bulk": "The selected items should not be annotated in their respective contexts.", - "label": "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 this redaction as a false-positive. The term will not be redacted in this dossier if it occurs in the same context.", + "label": "Remove from dossier in this context" + }, + "in-document": { + "description": "", + "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" } @@ -2135,6 +2178,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": { @@ -2143,31 +2205,35 @@ }, "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": "", + "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", + "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" } } @@ -2201,7 +2267,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.", @@ -2264,7 +2330,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" }, @@ -2319,7 +2385,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}}" }, @@ -2355,7 +2421,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}}", @@ -2448,7 +2514,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}" } }, @@ -2503,7 +2569,7 @@ }, "title": "Edit profile", "update": { - "success": "Successfully updated profile!" + "success": "Successfully updated profile." } }, "user-stats": { @@ -2519,15 +2585,11 @@ "view-as": "View as:", "workflow": "Workflow" }, - "viewer-header": { - "all-annotations-loaded": "All annotations loaded", - "load-all-annotations": "Load all annotations" - }, "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" }, @@ -2551,6 +2613,10 @@ "orientation": "Orientation", "text-label": "Watermark text", "text-placeholder": "Enter text" + }, + "pagination": { + "landscape": "", + "portrait": "" } }, "watermarks-listing": { diff --git a/apps/red-ui/src/styles.scss b/apps/red-ui/src/styles.scss index 3af183e3e..071efef6e 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: 35%; --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); } diff --git a/libs/common-ui b/libs/common-ui index 007e761bd..9e457a13b 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 007e761bd597a1534599b05d28826258bfc52570 +Subproject commit 9e457a13b4b4555586e733038fc30cd8b6d4e7cf diff --git a/libs/red-domain/src/lib/component-mappings/component-mapping.ts b/libs/red-domain/src/lib/component-mappings/component-mapping.ts index 9bfa2d6b1..0fd6246bf 100644 --- a/libs/red-domain/src/lib/component-mappings/component-mapping.ts +++ b/libs/red-domain/src/lib/component-mappings/component-mapping.ts @@ -10,6 +10,7 @@ export interface IComponentMapping extends IListable { numberOfLines: number; encoding: string; delimiter: string; + quoteChar: string; } export class ComponentMapping implements IComponentMapping, IListable { @@ -22,6 +23,7 @@ export class ComponentMapping implements IComponentMapping, IListable { readonly numberOfLines: number; readonly encoding: string; readonly delimiter: string; + readonly quoteChar: string; constructor(componentMapping: IComponentMapping) { this.id = componentMapping.id; @@ -33,6 +35,7 @@ export class ComponentMapping implements IComponentMapping, IListable { this.numberOfLines = componentMapping.numberOfLines; this.encoding = componentMapping.encoding; this.delimiter = componentMapping.delimiter; + this.quoteChar = componentMapping.quoteChar; } get searchKey(): string { 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 */ 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'; 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/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-change.request.ts b/libs/red-domain/src/lib/legal-basis/legal-basis-change.request.ts index e1d95b092..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 @@ -1,5 +1,9 @@ +import { ForceAnnotationOption } from '../../../../../apps/red-ui/src/app/modules/file-preview/utils/dialog-types'; + export interface ILegalBasisChangeRequest { annotationId?: string; comment?: string; legalBasis?: string; + reason?: string; + option?: ForceAnnotationOption; } 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; } 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..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; @@ -14,4 +14,6 @@ export interface IAddRedactionRequest { section?: string; rectangle?: boolean; addToAllDossiers?: boolean; + pageNumbers?: []; + caseSensitive?: boolean; } 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 5892fd7a4..57ec25dd7 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; @@ -6,3 +8,16 @@ export interface IRecategorizationRequest { readonly section?: string; readonly value?: string; } + +export interface IBulkRecategorizationRequest { + readonly value: string; + readonly type: string; + readonly legalBasis: string; + readonly section: string; + readonly originTypes?: string[]; + readonly originLegalBases?: string[]; + 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 40290994a..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 @@ -1,5 +1,20 @@ +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[]; + comment?: string; } 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'); 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;