Compare commits

...

20 Commits

Author SHA1 Message Date
Dan Percic
eb4368c3ce Merge branch 'RED-10072' into 'release/4.951.x'
Revert "RED-10072: AI description field and toggle for entities"

See merge request redactmanager/red-ui!638
2024-10-23 11:20:10 +02:00
Maverick Studer
9772145239 Revert "RED-10072: AI description field and toggle for entities" 2024-10-23 11:20:10 +02:00
Nicoleta Panaghiu
183b19c9da RED-10255: fixed force ignored hint action. 2024-10-22 19:19:50 +03:00
Nicoleta Panaghiu
4c9b487c78 RED-10227: fixed audit log date filters. 2024-10-22 18:59:58 +03:00
Nicoleta Panaghiu
ba311ad8e3 RED-8277: update common ui. 2024-10-22 18:03:08 +03:00
Nicoleta Panaghiu
62d4d18eaa RED-10220: description and legalBasis fields are no longer required. 2024-10-22 17:41:27 +03:00
Valentin Mihai
7f8dca3098 RED-9944 - Action Items don't appear in document area in webviewer when bulk-select is still unintenionally active 2024-10-22 17:23:32 +03:00
Valentin Mihai
289ee7f61d RED-9944 - Action Items don't appear in document area in webviewer when bulk-select is still unintenionally active 2024-10-22 16:42:15 +03:00
Nicoleta Panaghiu
bf1f25c0dd RED-10220: added support for justification technical name. 2024-10-22 12:46:48 +03:00
Valentin Mihai
773f2bfe9f RED-7340 - When a user has entered an invalid page range string, display a read border around the input field 2024-10-21 18:16:47 +03:00
Nicoleta Panaghiu
ac1780ade4 RED-3800: manual localazy sync. 2024-10-18 18:06:01 +03:00
Valentin Mihai
5f309bffe0 RED-9944 - Action Items don't appear in document area in webviewer when bulk-select is still unintenionally active 2024-10-18 14:35:52 +03:00
Nicoleta Panaghiu
611f293e64 RED-8277: made it possible to open dossiers and files in a new tab. 2024-10-17 18:10:25 +03:00
Valentin Mihai
bc7919551e Merge remote-tracking branch 'origin/release/4.951.x' into release/4.951.x 2024-10-16 23:12:59 +03:00
Valentin Mihai
4e3e64f2eb RED-9944 - cancel the bulk-selection mode when a user clicks somewhere else 2024-10-16 23:12:35 +03:00
Valentin Mihai
1233761ac3 RED-7340 - prefill the range fields in the edit and remove dialogs 2024-10-16 23:07:56 +03:00
Valentin Mihai
fd3b99a785 RED-7340 - prefill the range fields in the edit and remove dialogs 2024-10-16 14:42:40 +03:00
Nicoleta Panaghiu
f9361a2e82 RED-10180: sync localazy translation. 2024-10-16 14:10:23 +03:00
Nicoleta Panaghiu
4acb4d4eb7 RED-10190: fixed notification padding. 2024-10-16 14:01:22 +03:00
Valentin Mihai
7d4d2889da RED-7340 - Rectangle redactions: Use bulk-local redactions + New dialog design 2024-10-16 11:57:13 +03:00
31 changed files with 489 additions and 330 deletions

View File

@ -22,7 +22,7 @@
} }
.mat-mdc-menu-item.notification { .mat-mdc-menu-item.notification {
padding: 8px 26px 10px 8px; padding: 8px 26px 10px 8px !important;
margin: 2px 0 0 0; margin: 2px 0 0 0;
height: fit-content; height: fit-content;
position: relative; position: relative;

View File

@ -17,7 +17,7 @@ import { RouterHistoryService } from '@services/router-history.service';
import { auditCategoriesTranslations } from '@translations/audit-categories-translations'; import { auditCategoriesTranslations } from '@translations/audit-categories-translations';
import { Roles } from '@users/roles'; import { Roles } from '@users/roles';
import { applyIntervalConstraints } from '@utils/date-inputs-utils'; import { applyIntervalConstraints } from '@utils/date-inputs-utils';
import { Dayjs } from 'dayjs'; import dayjs, { Dayjs } from 'dayjs';
import { firstValueFrom } from 'rxjs'; import { firstValueFrom } from 'rxjs';
import { AdminDialogService } from '../../services/admin-dialog.service'; import { AdminDialogService } from '../../services/admin-dialog.service';
import { AuditService } from '../../services/audit.service'; import { AuditService } from '../../services/audit.service';
@ -139,16 +139,9 @@ export class AuditScreenComponent extends ListingComponent<Audit> implements OnI
const promises = []; const promises = [];
const category = this.form.get('category').value; const category = this.form.get('category').value;
const userId = this.form.get('userId').value; const userId = this.form.get('userId').value;
const from = this.form.get('from').value; const from = this.form.get('from').value ? dayjs(this.form.get('from').value).startOf('day').toISOString() : null;
let to = this.form.get('to').value; const to = this.form.get('to').value ? dayjs(this.form.get('to').value).endOf('day').toISOString() : null;
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 logsRequestBody: IAuditSearchRequest = { const logsRequestBody: IAuditSearchRequest = {
pageSize: PAGE_SIZE, pageSize: PAGE_SIZE,
page: page, page: page,

View File

@ -17,8 +17,17 @@
type="text" type="text"
/> />
</div> </div>
<div class="iqser-input-group">
<label translate="add-edit-entity.form.technical-name"></label>
<div class="technical-name">{{ this.technicalName() || '-' }}</div>
<span
[translateParams]="{ type: data.justification ? 'edit' : 'create' }"
[translate]="'add-edit-entity.form.technical-name-hint'"
class="hint"
></span>
</div>
<div class="iqser-input-group required w-400"> <div class="iqser-input-group w-400">
<label translate="add-edit-justification.form.reason"></label> <label translate="add-edit-justification.form.reason"></label>
<input <input
[placeholder]="'add-edit-justification.form.reason-placeholder' | translate" [placeholder]="'add-edit-justification.form.reason-placeholder' | translate"
@ -28,7 +37,7 @@
/> />
</div> </div>
<div class="iqser-input-group required w-400"> <div class="iqser-input-group w-400">
<label translate="add-edit-justification.form.description"></label> <label translate="add-edit-justification.form.description"></label>
<textarea <textarea
[placeholder]="'add-edit-justification.form.description-placeholder' | translate" [placeholder]="'add-edit-justification.form.description-placeholder' | translate"

View File

@ -1,11 +1,13 @@
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'; import { ChangeDetectionStrategy, Component, computed, Inject, untracked } from '@angular/core';
import { ReactiveFormsModule, UntypedFormGroup, Validators } from '@angular/forms'; import { ReactiveFormsModule, UntypedFormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Justification } from '@red/domain'; import { Justification } from '@red/domain';
import { JustificationsService } from '@services/entity-services/justifications.service'; import { JustificationsService } from '@services/entity-services/justifications.service';
import { BaseDialogComponent, CircleButtonComponent, IconButtonComponent } from '@iqser/common-ui'; import { BaseDialogComponent, CircleButtonComponent, HasScrollbarDirective, IconButtonComponent } from '@iqser/common-ui';
import { firstValueFrom } from 'rxjs'; import { firstValueFrom } from 'rxjs';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { formControlToSignal } from '@utils/functions';
import { toSignal } from '@angular/core/rxjs-interop';
interface DialogData { interface DialogData {
justification?: Justification; justification?: Justification;
@ -16,9 +18,29 @@ interface DialogData {
templateUrl: './add-edit-justification-dialog.component.html', templateUrl: './add-edit-justification-dialog.component.html',
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true, standalone: true,
imports: [TranslateModule, ReactiveFormsModule, IconButtonComponent, CircleButtonComponent], imports: [TranslateModule, ReactiveFormsModule, IconButtonComponent, CircleButtonComponent, HasScrollbarDirective],
}) })
export class AddEditJustificationDialogComponent extends BaseDialogComponent { export class AddEditJustificationDialogComponent extends BaseDialogComponent {
readonly form = this.#getForm();
readonly name = formControlToSignal(this.form.controls['name']);
readonly allJustifications = toSignal(this._justificationService.all$);
readonly technicalName = computed(() => {
if (this.data.justification) {
return this.data.justification.technicalName;
}
if (!this.name()) {
return null;
}
let currentTechnicalName = Justification.toTechnicalName(this.name());
const existingTechnicalNames = untracked(this.allJustifications).map(justification => justification.technicalName);
let suffix = 1;
while (existingTechnicalNames.includes(currentTechnicalName)) {
currentTechnicalName =
currentTechnicalName === '_' ? `${currentTechnicalName}${suffix++}` : [currentTechnicalName, suffix++].join('_');
}
return currentTechnicalName;
});
constructor( constructor(
private readonly _justificationService: JustificationsService, private readonly _justificationService: JustificationsService,
protected readonly _dialogRef: MatDialogRef<AddEditJustificationDialogComponent>, protected readonly _dialogRef: MatDialogRef<AddEditJustificationDialogComponent>,
@ -26,7 +48,6 @@ export class AddEditJustificationDialogComponent extends BaseDialogComponent {
) { ) {
super(_dialogRef, !!data.justification); super(_dialogRef, !!data.justification);
this.form = this._getForm();
this.initialFormValue = this.form.getRawValue(); this.initialFormValue = this.form.getRawValue();
} }
@ -34,7 +55,8 @@ export class AddEditJustificationDialogComponent extends BaseDialogComponent {
const dossierTemplateId = this.data.dossierTemplateId; const dossierTemplateId = this.data.dossierTemplateId;
this._loadingService.start(); this._loadingService.start();
try { try {
await firstValueFrom(this._justificationService.createOrUpdate(this.form.getRawValue() as Justification, dossierTemplateId)); const formValue = { ...this.form.getRawValue(), technicalName: this.technicalName() };
await firstValueFrom(this._justificationService.createOrUpdate(formValue as Justification, dossierTemplateId));
await firstValueFrom(this._justificationService.loadAll(dossierTemplateId)); await firstValueFrom(this._justificationService.loadAll(dossierTemplateId));
this._dialogRef.close(true); this._dialogRef.close(true);
} catch (error) { } catch (error) {
@ -43,11 +65,12 @@ export class AddEditJustificationDialogComponent extends BaseDialogComponent {
this._loadingService.stop(); this._loadingService.stop();
} }
private _getForm(): UntypedFormGroup { #getForm(): UntypedFormGroup {
return this._formBuilder.group({ return this._formBuilder.group({
name: [{ value: this.data.justification?.name, disabled: !!this.data.justification }, Validators.required], name: [{ value: this.data.justification?.name, disabled: !!this.data.justification }, Validators.required],
reason: [this.data.justification?.reason, Validators.required], reason: [this.data.justification?.reason],
description: [this.data.justification?.description, Validators.required], description: [this.data.justification?.description],
technicalName: [this.data.justification?.technicalName ?? null],
}); });
} }
} }

View File

@ -147,6 +147,7 @@ export class FileAttributeComponent extends BaseFormComponent implements OnDestr
handleClick($event: MouseEvent) { handleClick($event: MouseEvent) {
$event.stopPropagation(); $event.stopPropagation();
$event.preventDefault();
} }
ngOnDestroy() { ngOnDestroy() {
@ -154,12 +155,14 @@ export class FileAttributeComponent extends BaseFormComponent implements OnDestr
} }
handleFieldClick($event: MouseEvent) { handleFieldClick($event: MouseEvent) {
$event.preventDefault();
if (!this.fileNameColumn) { if (!this.fileNameColumn) {
this.editFileAttribute($event); this.editFileAttribute($event);
} }
} }
editFileAttribute($event: MouseEvent) { editFileAttribute($event: MouseEvent) {
$event.preventDefault();
if ( if (
!this.file.isInitialProcessing && !this.file.isInitialProcessing &&
this.permissionsService.canEditFileAttributes(this.file, this.dossier) && this.permissionsService.canEditFileAttributes(this.file, this.dossier) &&

View File

@ -588,4 +588,16 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
this.displayedPages.every((value, index) => value === newDisplayedPages[index]) this.displayedPages.every((value, index) => value === newDisplayedPages[index])
); );
} }
@HostListener('click', ['$event'])
clickInsideWorkloadView($event: MouseEvent) {
$event?.stopPropagation();
}
@HostListener('document: click')
clickOutsideWorkloadView() {
if (this.multiSelectService.active()) {
this.multiSelectService.deactivate();
}
}
} }

View File

@ -6,7 +6,7 @@
class="dialog-header heading-l" class="dialog-header heading-l"
></div> ></div>
<div [class.fixed-height]="isRedacted && isImage" class="dialog-content redaction"> <div [class.image-dialog]="isRedacted && isImage" [class.rectangle-dialog]="allRectangles" class="dialog-content redaction">
<div *ngIf="!isImage && redactedTexts.length && !allRectangles" class="iqser-input-group"> <div *ngIf="!isImage && redactedTexts.length && !allRectangles" class="iqser-input-group">
<redaction-selected-annotations-table <redaction-selected-annotations-table
[columns]="tableColumns" [columns]="tableColumns"
@ -107,7 +107,7 @@
formControlName="comment" formControlName="comment"
iqserHasScrollbar iqserHasScrollbar
name="comment" name="comment"
rows="4" rows="2"
type="text" type="text"
></textarea> ></textarea>
</div> </div>

View File

@ -1,8 +1,16 @@
.dialog-content { .dialog-content {
padding-top: 8px; padding-top: 8px;
&.fixed-height { &.rectangle-dialog {
height: 386px; height: 600px;
}
&.image-dialog {
height: 346px;
}
.rectangle-dialog,
.image-dialog {
overflow-y: auto; overflow-y: auto;
} }
} }

View File

@ -37,7 +37,7 @@ import {
import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component'; import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component';
import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option'; import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option';
import { validatePageRange } from '../../utils/form-validators'; import { validatePageRange } from '../../utils/form-validators';
import { parseRectanglePosition, parseSelectedPageNumbers } from '../../utils/enhance-manual-redaction-request.utils'; import { parseRectanglePosition, parseSelectedPageNumbers, prefillPageRange } from '../../utils/enhance-manual-redaction-request.utils';
interface TypeSelectOptions { interface TypeSelectOptions {
type: string; type: string;
@ -103,6 +103,14 @@ export class EditRedactionDialogComponent
private readonly _dictionaryService: DictionaryService, private readonly _dictionaryService: DictionaryService,
) { ) {
super(); super();
if (this.allRectangles) {
prefillPageRange(
this.data.annotations[0],
this.data.allFileAnnotations,
this.options as DetailsRadioOption<RectangleRedactOption>[],
);
}
} }
get displayedDictionaryLabel() { get displayedDictionaryLabel() {
@ -255,7 +263,10 @@ export class EditRedactionDialogComponent
disabled: this.isImported, disabled: this.isImported,
}), }),
section: new FormControl<string>({ value: sameSection ? this.annotations[0].section : null, disabled: this.isImported }), section: new FormControl<string>({ value: sameSection ? this.annotations[0].section : null, disabled: this.isImported }),
option: new FormControl<DetailsRadioOption<EditRedactionOption | RectangleRedactOption>>(this.options[0], validatePageRange()), option: new FormControl<DetailsRadioOption<EditRedactionOption | RectangleRedactOption>>(
this.options[0],
validatePageRange(this.data.file.numberOfPages),
),
value: new FormControl<string>(this.allRectangles ? this.annotations[0].value : null), value: new FormControl<string>(this.allRectangles ? this.annotations[0].value : null),
}); });
} }

View File

@ -140,7 +140,7 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen
request.legalBasis = !this.isDocumine ? this.form.get('reason').value.legalBasis : DOCUMINE_LEGAL_BASIS; request.legalBasis = !this.isDocumine ? this.form.get('reason').value.legalBasis : DOCUMINE_LEGAL_BASIS;
request.comment = this.form.get('comment').value; request.comment = this.form.get('comment').value;
request.reason = this.form.get('reason').value.description; request.reason = this.form.get('reason').value.description;
request.option = this.form.get('option').value.value; request.option = this.form.get('option').value?.value;
return request; return request;
} }

View File

@ -3,7 +3,7 @@
} }
.dialog-content { .dialog-content {
height: 650px; height: 610px;
overflow-y: auto; overflow-y: auto;
} }

View File

@ -130,7 +130,7 @@ export class RectangleAnnotationDialog
reason: [null, Validators.required], reason: [null, Validators.required],
comment: [null], comment: [null],
classification: [NON_READABLE_CONTENT], classification: [NON_READABLE_CONTENT],
option: [this.#getOption(SystemDefaults.RECTANGLE_REDACT_DEFAULT), validatePageRange()], option: [this.#getOption(SystemDefaults.RECTANGLE_REDACT_DEFAULT), validatePageRange(this.data.file.numberOfPages)],
}); });
} }

View File

@ -36,7 +36,7 @@ import {
} from '../../utils/dialog-types'; } from '../../utils/dialog-types';
import { isJustOne } from '@common-ui/utils'; import { isJustOne } from '@common-ui/utils';
import { validatePageRange } from '../../utils/form-validators'; import { validatePageRange } from '../../utils/form-validators';
import { parseRectanglePosition, parseSelectedPageNumbers } from '../../utils/enhance-manual-redaction-request.utils'; import { parseRectanglePosition, parseSelectedPageNumbers, prefillPageRange } from '../../utils/enhance-manual-redaction-request.utils';
@Component({ @Component({
templateUrl: './remove-redaction-dialog.component.html', templateUrl: './remove-redaction-dialog.component.html',
@ -112,7 +112,7 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent<
readonly redactedTexts = this.data.redactions.map(annotation => annotation.value); readonly redactedTexts = this.data.redactions.map(annotation => annotation.value);
form: UntypedFormGroup = this._formBuilder.group({ form: UntypedFormGroup = this._formBuilder.group({
comment: [null], comment: [null],
option: [this.defaultOption, validatePageRange(true)], option: [this.defaultOption, validatePageRange(this.data.file.numberOfPages, true)],
}); });
readonly selectedOption = toSignal(this.form.get('option').valueChanges.pipe(map(value => value.value))); readonly selectedOption = toSignal(this.form.get('option').valueChanges.pipe(map(value => value.value)));
@ -140,6 +140,14 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent<
private readonly _userPreferences: UserPreferenceService, private readonly _userPreferences: UserPreferenceService,
) { ) {
super(); super();
if (this.#allRectangles) {
prefillPageRange(
this.data.redactions[0],
this.data.allFileRedactions,
this.options as DetailsRadioOption<RectangleRedactOption>[],
);
}
} }
get hasFalsePositiveOption() { get hasFalsePositiveOption() {

View File

@ -248,11 +248,13 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
this._viewerHeaderService.enableLoadAllAnnotations(); // Reset the button state (since the viewer is reused between files) this._viewerHeaderService.enableLoadAllAnnotations(); // Reset the button state (since the viewer is reused between files)
super.ngOnDetach(); super.ngOnDetach();
this.pdf.instance.UI.hotkeys.off('esc'); this.pdf.instance.UI.hotkeys.off('esc');
this.pdf.instance.UI.iframeWindow.document.removeEventListener('click', this.handleViewerClick);
this._changeRef.markForCheck(); this._changeRef.markForCheck();
} }
ngOnDestroy() { ngOnDestroy() {
this.pdf.instance.UI.hotkeys.off('esc'); this.pdf.instance.UI.hotkeys.off('esc');
this.pdf.instance.UI.iframeWindow.document.removeEventListener('click', this.handleViewerClick);
super.ngOnDestroy(); super.ngOnDestroy();
} }
@ -277,6 +279,25 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
} }
} }
@Bind()
handleViewerClick(event: MouseEvent) {
this._ngZone.run(() => {
if (this._multiSelectService.active()) {
const clickedElement = event.target as HTMLElement;
if (
clickedElement.querySelector('#selectionrect') ||
clickedElement.id === `pageWidgetContainer${this.pdf.currentPage()}`
) {
if (!this._annotationManager.selected.length) {
this._multiSelectService.deactivate();
}
} else {
this._multiSelectService.deactivate();
}
}
});
}
async ngOnAttach(previousRoute: ActivatedRouteSnapshot) { async ngOnAttach(previousRoute: ActivatedRouteSnapshot) {
if (!this.state.file().canBeOpened) { if (!this.state.file().canBeOpened) {
return this.#navigateToDossier(); return this.#navigateToDossier();
@ -307,6 +328,8 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
this.#restoreOldFilters(); this.#restoreOldFilters();
this.pdf.instance.UI.hotkeys.on('esc', this.handleEscInsideViewer); this.pdf.instance.UI.hotkeys.on('esc', this.handleEscInsideViewer);
this._viewerHeaderService.resetLayers(); this._viewerHeaderService.resetLayers();
this.pdf.instance.UI.iframeWindow.document.removeEventListener('click', this.handleViewerClick);
this.pdf.instance.UI.iframeWindow.document.addEventListener('click', this.handleViewerClick);
} }
async openRectangleAnnotationDialog(manualRedactionEntryWrapper: ManualRedactionEntryWrapper) { async openRectangleAnnotationDialog(manualRedactionEntryWrapper: ManualRedactionEntryWrapper) {

View File

@ -86,7 +86,7 @@ export class AnnotationActionsService {
const data = { dossier: this._state.dossier(), annotations, hint }; const data = { dossier: this._state.dossier(), annotations, hint };
this._dialogService.openDialog('forceAnnotation', data, (request: ILegalBasisChangeRequest) => { this._dialogService.openDialog('forceAnnotation', data, (request: ILegalBasisChangeRequest) => {
let obs$: Observable<unknown>; let obs$: Observable<unknown>;
if (request.option === ForceAnnotationOptions.ONLY_HERE) { if (request.option === ForceAnnotationOptions.ONLY_HERE || hint) {
obs$ = this._manualRedactionService.bulkForce( obs$ = this._manualRedactionService.bulkForce(
annotations.map(a => ({ ...request, annotationId: a.id })), annotations.map(a => ({ ...request, annotationId: a.id })),
dossierId, dossierId,
@ -95,7 +95,7 @@ export class AnnotationActionsService {
); );
} else { } else {
const addAnnotationRequest = annotations.map(a => ({ const addAnnotationRequest = annotations.map(a => ({
comment: { text: request.comment }, comment: request.comment,
legalBasis: request.legalBasis, legalBasis: request.legalBasis,
reason: request.reason, reason: request.reason,
positions: a.positions, positions: a.positions,
@ -113,9 +113,11 @@ export class AnnotationActionsService {
async editRedaction(annotations: AnnotationWrapper[]) { async editRedaction(annotations: AnnotationWrapper[]) {
const { dossierId, file } = this._state; const { dossierId, file } = this._state;
const allFileAnnotations = this._fileDataService.annotations();
const includeUnprocessed = annotations.every(annotation => this.#includeUnprocessed(annotation, true)); const includeUnprocessed = annotations.every(annotation => this.#includeUnprocessed(annotation, true));
const data = { const data = {
annotations, annotations,
allFileAnnotations,
dossierId, dossierId,
file: file(), file: file(),
}; };
@ -184,9 +186,11 @@ export class AnnotationActionsService {
const dossierTemplate = this._dossierTemplatesService.find(this._state.dossierTemplateId); const dossierTemplate = this._dossierTemplatesService.find(this._state.dossierTemplateId);
const isApprover = this._permissionsService.isApprover(this._state.dossier()); const isApprover = this._permissionsService.isApprover(this._state.dossier());
const { file } = this._state; const { file } = this._state;
const allFileRedactions = this._fileDataService.annotations();
const data = { const data = {
redactions, redactions,
allFileRedactions,
file: file(), file: file(),
dossier: this._state.dossier(), dossier: this._state.dossier(),
falsePositiveContext: redactions.map(r => this.#getFalsePositiveText(r)), falsePositiveContext: redactions.map(r => this.#getFalsePositiveText(r)),

View File

@ -118,6 +118,7 @@ export const getRectangleRedactOptions = (action: 'add' | 'edit' | 'remove' = 'a
description: translations.multiplePages.extraOptionDescription, description: translations.multiplePages.extraOptionDescription,
placeholder: translations.multiplePages.extraOptionPlaceholder, placeholder: translations.multiplePages.extraOptionPlaceholder,
value: '', value: '',
errorCode: 'invalidRange',
}, },
}, },
]; ];

View File

@ -64,6 +64,7 @@ export interface RedactTextData {
export interface EditRedactionData { export interface EditRedactionData {
annotations: AnnotationWrapper[]; annotations: AnnotationWrapper[];
allFileAnnotations?: AnnotationWrapper[];
dossierId: string; dossierId: string;
file: File; file: File;
isApprover?: boolean; isApprover?: boolean;
@ -135,6 +136,7 @@ export interface RemoveRedactionPermissions {
export interface RemoveRedactionData { export interface RemoveRedactionData {
redactions: AnnotationWrapper[]; redactions: AnnotationWrapper[];
allFileRedactions?: AnnotationWrapper[];
dossier: Dossier; dossier: Dossier;
file?: File; file?: File;
falsePositiveContext: string[]; falsePositiveContext: string[];

View File

@ -1,7 +1,8 @@
import { Dictionary, File, IAddRedactionRequest, IEntityLogEntryPosition, SuperType } from '@red/domain'; import { Dictionary, File, IAddRedactionRequest, IEntityLogEntryPosition, SuperType } from '@red/domain';
import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper'; import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper';
import { LegalBasisOption } from './dialog-types'; import { LegalBasisOption, RectangleRedactOption, RectangleRedactOptions } from './dialog-types';
import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option';
export interface EnhanceRequestData { export interface EnhanceRequestData {
readonly type: SuperType | null; readonly type: SuperType | null;
@ -79,3 +80,60 @@ export const parseRectanglePosition = (annotation: AnnotationWrapper) => {
pageNumber: position.page, pageNumber: position.page,
} as IEntityLogEntryPosition; } as IEntityLogEntryPosition;
}; };
export const prefillPageRange = (
annotation: AnnotationWrapper,
allFileAnnotations: AnnotationWrapper[],
options: DetailsRadioOption<RectangleRedactOption>[],
) => {
const option = options.find(o => o.value === RectangleRedactOptions.MULTIPLE_PAGES);
const pages = extractPages(annotation, allFileAnnotations);
option.additionalInput.value = toRangeString(pages);
};
const extractPages = (annotation: AnnotationWrapper, allFileAnnotations: AnnotationWrapper[]): number[] => {
return allFileAnnotations.reduce((pages, a) => {
const position = a.positions[0];
const annotationPosition = annotation.positions[0];
if (
position.height === annotationPosition.height &&
position.width === annotationPosition.width &&
position.topLeft.x === annotationPosition.topLeft.x &&
position.topLeft.y === annotationPosition.topLeft.y
) {
pages.push(position.page);
}
return pages;
}, []);
};
const toRangeString = (pages: number[]): string => {
if (pages.length === 0) {
return '';
}
let ranges = [];
let start = pages[0];
let end = pages[0];
for (let i = 1; i < pages.length; i++) {
if (pages[i] === end + 1) {
end = pages[i];
} else {
if (start === end) {
ranges.push(`${start}`);
} else {
ranges.push(`${start}-${end}`);
}
start = end = pages[i];
}
}
if (start === end) {
ranges.push(`${start}`);
} else {
ranges.push(`${start}-${end}`);
}
return ranges.join(',');
};

View File

@ -1,12 +1,26 @@
import { AbstractControl, ValidatorFn } from '@angular/forms'; import { AbstractControl, ValidatorFn } from '@angular/forms';
export const validatePageRange = (allowEmpty = false): ValidatorFn => { export const validatePageRange = (numberOfPages: number, allowEmpty = false): ValidatorFn => {
return (control: AbstractControl): { [key: string]: any } | null => { return (control: AbstractControl): { [key: string]: any } | null => {
const option = control.value; const option = control.value;
if (option?.additionalInput) { if (option?.additionalInput) {
const value = option.additionalInput.value; const value = option.additionalInput.value;
const validRange = /^(\d+(-\d+)?)(,\d+(-\d+)?)*$/.test(value); const validRange = /^(\d+(-\d+)?)(,\d+(-\d+)?)*$/.test(value);
return validRange || (!value.length && allowEmpty) ? null : { invalidRange: true };
if (!validRange && !(value.length === 0 && allowEmpty)) {
return { invalidRange: true };
}
const ranges = value.split(',');
const isWithinRange = ranges.every(range => {
const [start, end] = range.split('-').map(Number);
if (end) {
return start >= 1 && end <= numberOfPages && start < end;
}
return start >= 1 && start <= numberOfPages;
});
return isWithinRange || (value.length === 0 && allowEmpty) ? null : { invalidRange: true };
} }
return null; return null;
}; };

View File

@ -78,24 +78,6 @@
></textarea> ></textarea>
</div> </div>
<div *ngIf="isIqserDevMode && form.get('aiCreationEnabled')" class="iqser-input-group">
<mat-slide-toggle color="primary" formControlName="aiCreationEnabled">
{{ 'add-edit-entity.form.ai-creation-enabled' | translate }}
</mat-slide-toggle>
</div>
<div *ngIf="isIqserDevMode && form.get('aiCreationEnabled')?.value && form.get('aiDescription')" class="iqser-input-group w-400">
<label translate="add-edit-entity.form.ai-description"></label>
<textarea
[placeholder]="'add-edit-entity.form.ai-description-placeholder' | translate"
formControlName="aiDescription"
iqserHasScrollbar
name="aiDescription"
rows="4"
type="text"
></textarea>
</div>
<div *ngIf="form.get('hasDictionary')" class="iqser-input-group"> <div *ngIf="form.get('hasDictionary')" class="iqser-input-group">
<mat-slide-toggle color="primary" formControlName="hasDictionary"> <mat-slide-toggle color="primary" formControlName="hasDictionary">
{{ 'add-edit-entity.form.has-dictionary' | translate }} {{ 'add-edit-entity.form.has-dictionary' | translate }}

View File

@ -9,7 +9,7 @@ import { MatSelect } from '@angular/material/select';
import { MatSlideToggle } from '@angular/material/slide-toggle'; import { MatSlideToggle } from '@angular/material/slide-toggle';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { RoundCheckboxComponent } from '@common-ui/inputs/round-checkbox/round-checkbox.component'; import { RoundCheckboxComponent } from '@common-ui/inputs/round-checkbox/round-checkbox.component';
import { BaseFormComponent, getConfig, isIqserDevMode, HasScrollbarDirective, LoadingService, Toaster } from '@iqser/common-ui'; import { BaseFormComponent, getConfig, HasScrollbarDirective, LoadingService, Toaster } from '@iqser/common-ui';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { Dictionary, IDictionary } from '@red/domain'; import { Dictionary, IDictionary } from '@red/domain';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service'; import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
@ -62,7 +62,6 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit
colors: Color[]; colors: Color[];
readonly isDocumine = getConfig().IS_DOCUMINE; readonly isDocumine = getConfig().IS_DOCUMINE;
readonly isIqserDevMode = isIqserDevMode();
constructor( constructor(
private readonly _dictionariesMapService: DictionariesMapService, private readonly _dictionariesMapService: DictionariesMapService,
@ -159,8 +158,6 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit
skippedHexColor: [this.entity?.skippedHexColor, [Validators.required, Validators.minLength(7)]], skippedHexColor: [this.entity?.skippedHexColor, [Validators.required, Validators.minLength(7)]],
type: [this.entity?.type], type: [this.entity?.type],
description: [this.entity?.description], description: [this.entity?.description],
aiCreationEnabled: [this.entity?.aiCreationEnabled],
aiDescription: [this.entity?.aiDescription],
rank: [{ value: this.entity?.rank, disabled: this.#isSystemManaged }, Validators.required], rank: [{ value: this.entity?.rank, disabled: this.#isSystemManaged }, Validators.required],
hint: [{ value: !!this.entity?.hint, disabled: this.#isSystemManaged }], hint: [{ value: !!this.entity?.hint, disabled: this.#isSystemManaged }],
hasDictionary: [ hasDictionary: [
@ -253,8 +250,6 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit
dossierTemplateId: this.dossierTemplateId, dossierTemplateId: this.dossierTemplateId,
type: this.form.get('type').value, type: this.form.get('type').value,
description: this.form.get('description').value, description: this.form.get('description').value,
aiCreationEnabled: this.form.get('aiCreationEnabled').value,
aiDescription: this.form.get('aiDescription').value,
hint: this.#isHint, hint: this.#isHint,
rank: this.form.get('rank').value, rank: this.form.get('rank').value,
caseInsensitive: !this.form.get('caseSensitive').value, caseInsensitive: !this.form.get('caseSensitive').value,

View File

@ -2,7 +2,7 @@ import { ITrackable } from '@iqser/common-ui';
import type { List } from '@iqser/common-ui/lib/utils'; import type { List } from '@iqser/common-ui/lib/utils';
import type { AnnotationWrapper } from '@models/file/annotation.wrapper'; import type { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { Dayjs } from 'dayjs'; import { Dayjs } from 'dayjs';
import { FormControl } from '@angular/forms'; import { AbstractControl } from '@angular/forms';
import { toSignal } from '@angular/core/rxjs-interop'; import { toSignal } from '@angular/core/rxjs-interop';
export function hexToRgb(hex: string) { export function hexToRgb(hex: string) {
@ -146,6 +146,6 @@ export function urlFileId() {
return fileId.split('?')[0]; return fileId.split('?')[0];
} }
export function formControlToSignal<T>(control: FormControl<T>) { export function formControlToSignal<T>(control: AbstractControl<T>) {
return toSignal(control.valueChanges, { initialValue: control.value }); return toSignal(control.valueChanges, { initialValue: control.value });
} }

View File

@ -112,6 +112,9 @@
} }
}, },
"add-edit-dossier-attribute": { "add-edit-dossier-attribute": {
"error": {
"generic": "Speichern des Attributs fehlgeschlagen."
},
"form": { "form": {
"label": "Name des Attributs", "label": "Name des Attributs",
"label-placeholder": "Namen eingeben", "label-placeholder": "Namen eingeben",
@ -135,9 +138,6 @@
}, },
"add-edit-entity": { "add-edit-entity": {
"form": { "form": {
"ai-creation-enabled": "AI Erzeugung aktivieren",
"ai-description": "AI Beschreibung",
"ai-description-placeholder": "AI Beschreibung eingeben",
"case-sensitive": "Groß-/Kleinschreibung beachten", "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": "Farbe {type, select, redaction{Schwärzung} hint{Hinweis} recommendation{Empfehlung} skipped{Ingorierte Schwärzung} ignored{Ignorierter Hinweis} other{}}",
"color-placeholder": "#", "color-placeholder": "#",
@ -1165,15 +1165,15 @@
"queued": "Ihr Download wurde zur Warteschlange hinzugefügt.<br><br>Hier finden Sie Ihre generierten Downloads: <a href=\"{downloadHref}\">Meine Downloads<a/>." "queued": "Ihr Download wurde zur Warteschlange hinzugefügt.<br><br>Hier finden Sie Ihre generierten Downloads: <a href=\"{downloadHref}\">Meine Downloads<a/>."
}, },
"download-type": { "download-type": {
"annotated": "Annotierte PDF", "annotated": "Annotiertes PDF",
"delta-preview": "Delta-PDF", "delta-preview": "Delta-PDF",
"flatten": "Verflachte PDF", "flatten": "Verflachtes PDF",
"label": "{length} Dokumenten{length, plural, one{typ} other{typen}}", "label": "{length} Dokumenten{length, plural, one{typ} other{typen}}",
"optimized-preview": "Optimierte Vorschau-PDF", "optimized-preview": "Optimiertes Vorschau-PDF",
"original": "Optimierte PDF", "original": "Optimiertes PDF",
"preview": "Vorschau-PDF", "preview": "Vorschau-PDF",
"redacted": "Geschwärzte PDF", "redacted": "Geschwärztes PDF",
"redacted-only": "Geschwärzte PDF (nur freigegebene Dateien)" "redacted-only": "Geschwärztes PDF (nur freigegebene Dateien)"
}, },
"downloads-list": { "downloads-list": {
"actions": { "actions": {
@ -1278,15 +1278,15 @@
"content": { "content": {
"options": { "options": {
"multiple-pages": { "multiple-pages": {
"description": "", "description": "Schwärzung auf folgenden Seiten bearbeiten",
"extraOptionDescription": "", "extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.",
"extraOptionLabel": "", "extraOptionLabel": "Seitenbereich",
"extraOptionPlaceholder": "", "extraOptionPlaceholder": "z. B. 1-20,22,32",
"label": "" "label": "Auf allen Seiten ändern"
}, },
"only-this-page": { "only-this-page": {
"description": "", "description": "Schwärzung nur an dieser Position in diesem Dokument bearbeiten",
"label": "" "label": "Nur auf dieser Seite ändern"
} }
} }
} }
@ -1309,7 +1309,7 @@
}, },
"only-here": { "only-here": {
"description": "Bearbeiten Sie die Schwärzung nur an dieser Stelle im Dokument.", "description": "Bearbeiten Sie die Schwärzung nur an dieser Stelle im Dokument.",
"label": "Typ nur hier ändern" "label": "Nur hier ändern"
} }
}, },
"reason": "Grund", "reason": "Grund",
@ -1794,8 +1794,8 @@
}, },
"import-only-for-pages": "Nur für diese Seiten importieren", "import-only-for-pages": "Nur für diese Seiten importieren",
"range": { "range": {
"label": "Minus (-) für Spanne und Komma (,) für Aufzählung.", "label": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.",
"placeholder": "Beispiel: 1-20,22,32" "placeholder": "z. B. 1-20,22,32"
}, },
"title": "Dokument mit Schwärzungen importieren" "title": "Dokument mit Schwärzungen importieren"
}, },
@ -1889,15 +1889,15 @@
"legalBasis": "Rechtsgrundlage", "legalBasis": "Rechtsgrundlage",
"options": { "options": {
"multiple-pages": { "multiple-pages": {
"description": "", "description": "Schwärzung auf folgenden Seiten hinzufügen",
"extraOptionDescription": "", "extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.",
"extraOptionLabel": "", "extraOptionLabel": "Seitenbereich",
"extraOptionPlaceholder": "", "extraOptionPlaceholder": "z. B. 1-20,22,32",
"label": "" "label": "Auf mehreren Seiten anwenden"
}, },
"only-this-page": { "only-this-page": {
"description": "", "description": "Schwärzung nur an dieser Position in diesem Dokument hinzufügen",
"label": "" "label": "Auf dieser Seite anwenden"
} }
}, },
"reason": "Grund", "reason": "Grund",
@ -2134,7 +2134,7 @@
"type": "Typ", "type": "Typ",
"type-placeholder": "Typ auswählen...", "type-placeholder": "Typ auswählen...",
"unchanged": "Ungeändert", "unchanged": "Ungeändert",
"value": "" "value": "Wert"
}, },
"title": "Text schwärzen" "title": "Text schwärzen"
} }
@ -2184,15 +2184,15 @@
"content": { "content": {
"options": { "options": {
"multiple-pages": { "multiple-pages": {
"description": "", "description": "Schwärzung auf folgenden Seiten entfernen",
"extraOptionDescription": "", "extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.",
"extraOptionLabel": "", "extraOptionLabel": "Seitenbereich",
"extraOptionPlaceholder": "", "extraOptionPlaceholder": "z. B. 1-20,22,32",
"label": "" "label": "Auf allen Seiten entfernen"
}, },
"only-this-page": { "only-this-page": {
"description": "", "description": "Schwärzung nur an dieser Stelle in diesem Dokument entfernen",
"label": "" "label": "Nur auf dieser Seite entfernen"
} }
} }
} }

View File

@ -112,6 +112,9 @@
} }
}, },
"add-edit-dossier-attribute": { "add-edit-dossier-attribute": {
"error": {
"generic": "Failed to save attribute."
},
"form": { "form": {
"label": "Attribute name", "label": "Attribute name",
"label-placeholder": "Enter name", "label-placeholder": "Enter name",
@ -135,9 +138,6 @@
}, },
"add-edit-entity": { "add-edit-entity": {
"form": { "form": {
"ai-creation-enabled": "Enable AI creation",
"ai-description": "AI Description",
"ai-description-placeholder": "Enter AI description",
"case-sensitive": "Case-sensitive", "case-sensitive": "Case-sensitive",
"color": "{type, select, redaction{Redaction} hint{Hint} recommendation{Recommendation} skipped{Skipped redaction} ignored{Ignored hint} other{}} color", "color": "{type, select, redaction{Redaction} hint{Hint} recommendation{Recommendation} skipped{Skipped redaction} ignored{Ignored hint} other{}} color",
"color-placeholder": "#", "color-placeholder": "#",

View File

@ -112,6 +112,9 @@
} }
}, },
"add-edit-dossier-attribute": { "add-edit-dossier-attribute": {
"error": {
"generic": "Speichern des Attributs fehlgeschlagen."
},
"form": { "form": {
"label": "Name des Attributs", "label": "Name des Attributs",
"label-placeholder": "Namen eingeben", "label-placeholder": "Namen eingeben",
@ -135,9 +138,6 @@
}, },
"add-edit-entity": { "add-edit-entity": {
"form": { "form": {
"ai-creation-enabled": "AI Erzeugung aktivieren",
"ai-description": "AI Beschreibung",
"ai-description-placeholder": "AI Beschreibung eingeben",
"case-sensitive": "Groß-/Kleinschreibung beachten", "case-sensitive": "Groß-/Kleinschreibung beachten",
"color": "Farbe {type, select, redaction{Annotation} hint{Hinweis} recommendation{Empfehlung} skipped{Übersprungene Annotation} ignored{Ignorierter Hinweis} other{}}", "color": "Farbe {type, select, redaction{Annotation} hint{Hinweis} recommendation{Empfehlung} skipped{Übersprungene Annotation} ignored{Ignorierter Hinweis} other{}}",
"color-placeholder": "#", "color-placeholder": "#",
@ -1305,7 +1305,7 @@
"options": { "options": {
"in-document": { "in-document": {
"description": "", "description": "",
"label": "" "label": "In Dokument ändern"
}, },
"only-here": { "only-here": {
"description": "", "description": "",
@ -1749,21 +1749,21 @@
"label": "Convert only on this page" "label": "Convert only on this page"
} }
}, },
"save": "Convert earmarks", "save": "Markierungen konvertieren",
"title": "Convert earmarks to imported annotations" "title": "Markierungen in importierte Annotationen konvertieren"
}, },
"form": { "form": {
"color": { "color": {
"label": "Earmark HEX color" "label": "HEX-Code der Markierung"
} }
}, },
"remove": { "remove": {
"confirmation": "The {count} selected {count, plural, one{earmark} other{earmarks}} will be removed from the document", "confirmation": "{count} ausgewählte {count, plural, one{Markierung wird} other{Markierungen werden}} aus dem Dokument entfernt",
"details": "Removing earmarks from the document will delete all the rectangles and leave a white background behind the highlighted text.", "details": "Beim Entfernen von Markierungen werden die entsprechenden farbigen Kästen gelöscht. An die Stelle der Hervorhebung tritt ein weißer Hintergrund.",
"options": { "options": {
"all-pages": { "all-pages": {
"description": "The earmarks in the selected HEX color will be removed on all pages of the document.", "description": "Die Markierungen in der ausgewählten HEX-Farbe werden auf allen Seiten des Dokuments entfernt.",
"label": "Remove on all pages" "label": "Auf allen Seiten entfernen"
}, },
"this-page": { "this-page": {
"description": "The earmarks in the selected HEX color will be removed only on the current page in view.", "description": "The earmarks in the selected HEX color will be removed only on the current page in view.",
@ -1784,23 +1784,23 @@
}, },
"import-redactions-dialog": { "import-redactions-dialog": {
"actions": { "actions": {
"cancel": "Cancel", "cancel": "Abbrechen\n",
"import": "Import" "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": { "http": {
"error": "Failed to import components! {error}", "error": "Import der Schwärzungen fehlgeschlagen: {error}",
"success": "Annotations have been imported!" "success": "Annotationen wurden importiert."
}, },
"import-only-for-pages": "Import only for pages", "import-only-for-pages": "Nur für diese Seiten importieren",
"range": { "range": {
"label": "Minus(-) for range and comma(,) for enumeration.", "label": "Minus (-) für Spanne und Komma (,) für Aufzählung.",
"placeholder": "e.g. 1-20,22,32" "placeholder": "Beispiel: 1-20,22,32"
}, },
"title": "Import document with annotations" "title": "Dokument mit Annotationen importieren"
}, },
"initials-avatar": { "initials-avatar": {
"unassigned": "Unbekannt", "unassigned": "Nicht zugewiesen",
"you": "Sie" "you": "Sie"
}, },
"justifications-listing": { "justifications-listing": {
@ -1808,7 +1808,7 @@
"delete": "Begründung löschen", "delete": "Begründung löschen",
"edit": "Begründung bearbeiten" "edit": "Begründung bearbeiten"
}, },
"add-new": "Neue Begründung hinzufügen", "add-new": "Neue Begründung erstellen",
"bulk": { "bulk": {
"delete": "Ausgewählte Begründungen löschen" "delete": "Ausgewählte Begründungen löschen"
}, },
@ -1818,66 +1818,66 @@
"table-col-names": { "table-col-names": {
"description": "Beschreibung", "description": "Beschreibung",
"name": "Name", "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": { "license-info-screen": {
"analysis-capacity-usage": { "analysis-capacity-usage": {
"analyzed-cumulative": "Cumulative analyzed data volume", "analyzed-cumulative": "Kumuliertes analysiertes Datenvolumen",
"analyzed-per-month": "Analyzed data volume per month", "analyzed-per-month": "Analysiertes Datenvolumen pro Monat\n",
"licensed": "Licensed capacity", "licensed": "Lizenzierte Kapazität",
"section-title": "Analysis capacity details", "section-title": "Angaben zur Analysekapazität",
"total-analyzed-data": "Total analyzed data", "total-analyzed-data": "Analysiertes Datenvolumen (Gesamt)",
"used-in-period": "Analysis capacity used in licensing period", "used-in-period": "Genutzte Analysekapazität<br>(Lizenzzeitraum)",
"used-in-total": "Total analysis capacity used" "used-in-total": "Insgesamt genutzte Analysekapazität"
}, },
"backend-version": "Backend-Version der Anwendung", "backend-version": "Backend-Version der Anwendung",
"copyright-claim-text": "Copyright © 2020 - {currentYear} knecon AG (powered by IQSER)", "copyright-claim-text": "Copyright © 2020 - {currentYear} knecon AG (powered by IQSER)",
"copyright-claim-title": "Copyright", "copyright-claim-title": "Copyright",
"custom-app-title": "Name der Anwendung", "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", "end-user-license-title": "Endbenutzer-Lizenzvereinbarung",
"licensing-details": { "licensing-details": {
"license-title": "License title", "license-title": "Titel der Lizenz",
"licensed-analysis-capacity": "Licensed analysis capacity", "licensed-analysis-capacity": "Lizenzierte Analysekapazität",
"licensed-page-count": "Licensed pages", "licensed-page-count": "Lizenzierte Seiten",
"licensed-retention-capacity": "Licensed retention capacity", "licensed-retention-capacity": "Lizenzierte Speicherkapazität",
"licensed-to": "Licensed to", "licensed-to": "Lizenziert für",
"licensing-period": "Licensing period", "licensing-period": "Lizenzzeitraum",
"section-title": "Licensing details" "section-title": "Lizenzdetails"
}, },
"page-usage": { "page-usage": {
"cumulative-pages": "Cumulative pages", "cumulative-pages": "Kumulierte Seiten",
"current-analyzed-pages": "Analyzed pages in licensing period", "current-analyzed-pages": "Analysierte Seiten (Lizenzzeitraum)",
"ocr-analyzed-pages": "OCR-processed pages in licensing period", "ocr-analyzed-pages": "OCR-verarbeitete Seiten (Lizenzzeitraum)",
"pages-per-month": "Pages per month", "pages-per-month": "Seiten pro Monat",
"section-title": "Page usage details", "section-title": "Details zur Seitenanzahl",
"total-analyzed": "Total analyzed pages", "total-analyzed": "Analysierte Seiten<br>(Gesamt)",
"total-ocr-analyzed": "Total OCR-processed pages", "total-ocr-analyzed": "OCR-verarbeitete Seiten (Gesamt)",
"total-pages": "Total pages", "total-pages": "Lizenzierte Seiten",
"unlicensed-analyzed": "Unlicensed analyzed pages" "unlicensed-analyzed": "Ohne Lizenz analysierte Seiten"
}, },
"retention-capacity-usage": { "retention-capacity-usage": {
"active-documents": "Active documents", "active-documents": "Aktive Dokumente",
"archived-documents": "Archived documents", "archived-documents": "Archivierte Dokumente",
"exceeded-capacity": "Exceeded capacity", "exceeded-capacity": "Kapazitätsüberschreitung",
"section-title": "Retention capacity details", "section-title": "Details zur Speicherkapazität",
"storage-capacity": "Capacity", "storage-capacity": "Kapazität",
"trash-documents": "Documents in trash", "trash-documents": "Dokumente im Papierkorb",
"unused": "Unused retention capacity", "unused": "Ungenutzte Speicherkapazität",
"used-capacity": "Retention capacity used" "used-capacity": "Genutzte Speicherkapazität"
}, },
"status": { "status": {
"active": "Aktiv", "active": "Aktiv",
"inactive": "Inactive" "inactive": "Inaktiv"
} }
}, },
"license-information": "Lizenzinformationen", "license-information": "Lizenzinformationen",
"load-all-annotations-success": "All annotations were loaded and are now visible in the document thumbnails", "load-all-annotations-success": "Alle Anmerkungen wurden geladen und sind jetzt in der Miniaturansicht des Dokuments sichtbar.",
"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": "<strong>Achtung:</strong> 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": "Do not show this warning again", "load-all-annotations-threshold-exceeded-checkbox": "Diese Warnung nicht mehr anzeigen",
"loading": "Loading", "loading": "Wird geladen...",
"manual-annotation": { "manual-annotation": {
"dialog": { "dialog": {
"actions": { "actions": {
@ -1889,82 +1889,90 @@
"legalBasis": "Rechtsgrundlage", "legalBasis": "Rechtsgrundlage",
"options": { "options": {
"multiple-pages": { "multiple-pages": {
"description": "", "description": "Annotation auf folgenden Seiten bearbeiten",
"extraOptionDescription": "", "extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.",
"extraOptionLabel": "", "extraOptionLabel": "Seitenbereich",
"extraOptionPlaceholder": "", "extraOptionPlaceholder": "z. B. 1-20,22,32",
"label": "" "label": "Auf mehreren Seiten anwenden"
}, },
"only-this-page": { "only-this-page": {
"description": "", "description": "Annotation nur an dieser Position im Dokument bearbeiten",
"label": "" "label": "Auf dieser Seite anwenden"
} }
}, },
"reason": "Begründung", "reason": "Grund",
"reason-placeholder": "Wählen Sie eine Begründung aus ...", "reason-placeholder": "Grund auswählen ...",
"section": "Absatz / Ort" "section": "Absatz / Textstelle"
}, },
"error": "Error! Invalid page selection", "error": "Fehler: Ungültige Seitenauswahl",
"header": { "header": {
"false-positive": "Set false positive", "false-positive": "Als falsch-positiv markieren",
"force-hint": "Hinweis erzwingen", "force-hint": "Hinweis erzwingen",
"force-redaction": "Schwärzung erzwingen", "force-redaction": "Annotation erzwingen",
"force-redaction-image-hint": "Redact image", "force-redaction-image-hint": "Bild schwärzen",
"hint": "Add hint", "hint": "HInweis hinzufügen",
"redact": "Annotation", "redact": "Annotation",
"redaction": "Redaction" "redaction": "Schwärzung"
} }
} }
}, },
"minutes": "minutes", "minutes": "Minuten",
"no-active-license": "Invalid or corrupt license Please contact your administrator", "no-active-license": "Ungültige oder beschädigte Lizenz — Bitte wenden Sie sich an Ihren Administrator",
"notification": { "notification": {
"assign-approver": "Sie wurden dem Dokument <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> im Dossier <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}<b> als Genehmiger zugewiesen!", "assign-approver": "Sie wurden einem Dokument als Genehmiger zugewiesen. <br>Dokument: <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> <br>Dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>",
"assign-reviewer": "Sie wurden dem Dokument <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> im Dossier <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}<b> als Reviewer zugewiesen!", "assign-reviewer": "Sie wurden einem Dokument als Prüfer zugewiesen. <br>Dokument: <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> <br>Dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>",
"document-approved": "<b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> wurde genehmigt!", "document-approved": "<b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> wurde genehmigt!",
"dossier-deleted": "Dossier: <b>{dossierName}</b> wurde gelöscht!", "dossier-deleted": "Dossier: <b>{dossierName}</b> wurde gelöscht!",
"dossier-owner-deleted": "The owner of dossier: <b>{dossierName}</b> has been deleted!", "dossier-owner-deleted": "Der Besitzer des Dossiers wurde gelöscht: <b>{dossierName}</b>",
"dossier-owner-removed": "Der Dossier-Owner von <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> wurde entfernt!", "dossier-owner-removed": "Der Dossier-Owner von <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> wurde entfernt!",
"dossier-owner-set": "Eigentümer von <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> geändert zu <b>{user}</b>!", "dossier-owner-set": "Sie sind jetzt Besitzer des Dossiers <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>.",
"download-ready": "Ihr <b><a href=\"{downloadHref}\", target=\"_blank\">Download</a></b> ist fertig!", "download-ready": "Ihr <b><a href=\"{downloadHref}\", target=\"_self\">Download</a></b> steht bereit.",
"no-data": "Du hast aktuell keine Benachrichtigungen", "no-data": "Du hast aktuell keine Benachrichtigungen",
"unassigned-from-file": "Sie wurden vom Dokument <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> im Dossier <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}<b> entfernt!", "unassigned-from-file": "Sie wurden von einem Dokument entfernt. <br>Dokument: <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> <br>Dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>",
"user-becomes-dossier-member": "<b>{user}</b> ist jetzt Mitglied des Dossiers <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!", "user-becomes-dossier-member": "<b>{user}</b> ist jetzt Mitglied des Dossiers <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
"user-demoted-to-reviewer": "<b>{user}</b> wurde im Dossier <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> auf die Reviewer-Berechtigung heruntergestuft!", "user-demoted-to-reviewer": "<b>{user}</b> wurde im Dossier <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> auf die Reviewer-Berechtigung heruntergestuft!",
"user-promoted-to-approver": "<b>{user}</b> wurde im Dossier <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> zum Genehmiger ernannt!", "user-promoted-to-approver": "<b>{user}</b> wurde im Dossier <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> zum Genehmiger ernannt!",
"user-removed-as-dossier-member": "<b>{user}</b> wurde als Mitglied von: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> entfernt!" "user-removed-as-dossier-member": "<b>{user}</b> wurde als Mitglied von: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> entfernt!"
}, },
"notifications": {
"button-text": "Benachrichtigungen",
"deleted-dossier": "Gelöschtes Dossier",
"label": "Benachrichtigungen",
"mark-all-as-read": "Alle als gelesen markieren",
"mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren"
},
"notifications-screen": { "notifications-screen": {
"category": { "category": {
"email-notifications": "E-Mail Benachrichtigungen", "email-notifications": "E-Mail Benachrichtigungen",
"in-app-notifications": "In-App-Benachrichtigungen" "in-app-notifications": "In-App-Benachrichtigungen"
}, },
"error": { "error": {
"generic": "Ein Fehler ist aufgetreten... Aktualisierung der Einstellungen fehlgeschlagen!" "generic": "Fehler: Aktualisierung der Präferenzen fehlgeschlagen."
}, },
"groups": { "groups": {
"document": "Dokumentbezogene Benachrichtigungen", "document": "Benachrichtigungen zu Dokumenten",
"dossier": "Dossierbezogene Benachrichtigungen", "dossier": "Benachrichtigungen zu Dossiers",
"other": "Andere Benachrichtigungen" "other": "Andere Benachrichtigungen"
}, },
"options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten", "options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten",
"options": { "options": {
"ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen bin", "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen bin",
"ASSIGN_REVIEWER": "Wenn ich einem Dokument als Überprüfer zugewiesen bin", "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Prüfer zugewiesen werde",
"DOCUMENT_APPROVED": "Wenn sich der Dokumentstatus in Genehmigt ändert", "DOCUMENT_APPROVED": "Wenn sich der Dokumentstatus zu \"Freigegeben\" ändert (Nur für Dossier-Besitzer verfügbar)",
"DOCUMENT_UNDER_APPROVAL": "Wenn sich der Dokumentstatus in „In Genehmigung“ ändert", "DOCUMENT_UNDER_APPROVAL": "Wenn sich der Dokumentstatus zu „In Genehmigung“ ändert",
"DOCUMENT_UNDER_REVIEW": "Wenn sich der Dokumentstatus in Wird überprüft ändert", "DOCUMENT_UNDER_REVIEW": "Wenn sich der Dokumentstatus zu \"In Bearbeitung\" ändert",
"DOSSIER_DELETED": "Wenn ein Dossier gelöscht wurde", "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_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", "DOWNLOAD_READY": "Wenn ein Download bereit ist",
"UNASSIGNED_FROM_FILE": "Wenn die Zuweisung zu einem Dokument aufgehoben wird", "UNASSIGNED_FROM_FILE": "Wenn ich als Bearbeiter von einem Dokument entfernt werde",
"USER_BECOMES_DOSSIER_MEMBER": "Wenn ein Benutzer zu meinem Dossier hinzugefügt wurde", "USER_BECOMES_DOSSIER_MEMBER": "Wenn ich zu einem Dossier hinzugefügt wurde",
"USER_DEGRADED_TO_REVIEWER": "Wenn ich Gutachter in einem Dossier werde", "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_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde",
"USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere" "USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere"
}, },
"options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten",
"schedule": { "schedule": {
"daily": "Tägliche Zusammenfassung", "daily": "Tägliche Zusammenfassung",
"instant": "Sofortig", "instant": "Sofortig",
@ -1981,44 +1989,44 @@
}, },
"ocr": { "ocr": {
"confirmation-dialog": { "confirmation-dialog": {
"cancel": "Cancel", "cancel": "Abbrechen",
"question": "Manual changes could get lost if OCR makes changes at those positions. Are you sure you want to proceed?", "question": "Manuelle Änderungen können überschrieben werden, wenn die OCR an den jeweiligen Stellen Änderungen vornimmt. Möchten Sie dennoch fortfahren?",
"title": "Warning: the file has manual adjustments!" "title": "Warnung: Die Datei enthält manuelle Änderungen!"
} }
}, },
"overwrite-files-dialog": { "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": "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": "Uploading a ZIP archive", "archive-title": "ZIP-Archiv hochladen",
"file-question": "<b>{filename}</b> ist bereits vorhanden. Wie möchten Sie fortfahren?", "file-question": "<b>{filename}</b> ist bereits vorhanden. Wie möchten Sie vorgehen?",
"file-title": "Das Dokument existiert bereits!", "file-title": "Datei existiert bereits.",
"options": { "options": {
"all-files": "Apply to all files of current upload", "all-files": "Auf alle Dateien des Uploads anwenden",
"cancel": "Alle Uploads abbrechen", "cancel": "Alle Uploads abbrechen",
"current-files": "Apply to current file", "current-files": "Auf aktuelle Datei anwenden",
"full-overwrite": { "full-overwrite": {
"description": "Manual changes done to the existing file will be removed and you are able to start over.", "description": "Verwerfen Sie alle manuellen Änderungen und beginnen Sie mit der frisch verarbeiteten Datei.",
"label": "Overwrite and start over" "label": "Überschreiben und manuelle Änderungen beibehalten"
}, },
"partial-overwrite": { "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": "Behalten Sie manuelle Änderungen, sofern die Schwärzungen an der ursprünglichen Positionen bleiben.<br>Bei geändertem Inhalt könnten Schwärzungen sonst falsch platziert werden.",
"label": "Overwrite and keep manual changes" "label": "Überschreiben und manuelle Änderungen beibehalten"
}, },
"proceed": "Proceed", "proceed": "Fortfahren",
"skip": { "skip": {
"description": "The upload will be skipped and the existing file will not be replaced.", "description": "Behalten Sie die vorhandene Datei und überspringen Sie den Upload.",
"label": "Keep the existing file and do not overwrite" "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": { "page-rotation": {
"apply": "APPLY", "apply": "BESTÄTIGEN",
"confirmation-dialog": { "confirmation-dialog": {
"question": "You have unapplied page rotations. Choose how to proceed:", "question": "Sie haben eine unbestätigte Seitendrehung. Wie möchten Sie vorgehen?",
"title": "Pending page rotations" "title": "Drehung der Seite steht aus"
}, },
"discard": "DISCARD" "discard": "VERWERFEN"
}, },
"pagination": { "pagination": {
"next": "Nächste", "next": "Nächste",
@ -2030,153 +2038,157 @@
"compare-button": "Vergleichen", "compare-button": "Vergleichen",
"layers-panel-button": "Ebenen", "layers-panel-button": "Ebenen",
"left-panel-button": "Panel", "left-panel-button": "Panel",
"load-all-annotations": "Alle Annotationen laden", "load-all-annotations": "Alle Annotationen geladen",
"no-outlines-text": "Keine Gliederung verfügbar", "no-outlines-text": "Keine Gliederung verfügbar",
"no-signatures-text": "In diesem Dokument gibt es keine Unterschriftenfelder", "no-signatures-text": "Dieses Dokument enthält keine Unterschriftenfelder.",
"outline-multi-select": "Bearbeiten", "outline-multi-select": "Bearbeiten",
"outlines-panel-button": "Gliederung", "outlines-panel-button": "Gliederung",
"pan-tool-button": "Verschieben", "pan-tool-button": "Verschieben",
"rectangle-tool-button": "Bereichsschwärzung", "rectangle-tool-button": "Bereich schwärzen",
"rotate-left-button": "Seite nach links drehen", "rotate-left-button": "Seite nach links drehen",
"rotate-right-button": "Seite nach rechts drehen", "rotate-right-button": "Seite nach rechts drehen",
"select-tool-button": "Auswählen", "select-tool-button": "Auswählen",
"signature-panel-button": "Unterschriften", "signature-panel-button": "Unterschriften",
"thumbnails-panel-button": "Miniaturansicht", "thumbnails-panel-button": "Miniaturansicht",
"toggle-layers": "Layout-Raster {active, select, true{deaktivieren} false{aktivieren} other{}}", "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-readable-redactions": "Schwärzungen {active, select, true{wie im finalen Dokument} false{in Preview-Farbe anzeigen} other{}}",
"toggle-tooltips": "Tooltips zu Annotationen {active, select, true{deaktivieren} false{aktivieren} other{}}", "toggle-tooltips": "Tooltips für Annotationen {active, select, true{deaktivieren} false{aktivieren} other{}}",
"zoom-in-button": "Vergrößern", "zoom-in-button": "Vergrößern",
"zoom-out-button": "Verkleinern" "zoom-out-button": "Verkleinern"
}, },
"text-popup": { "text-popup": {
"actions": { "actions": {
"search": "Search for selected text" "search": "Ausgewählten Text suchen"
} }
} }
}, },
"permissions-screen": { "permissions-screen": {
"dossier": { "dossier": {
"access": "Access dossier", "access": "Dossier öffnen",
"view": "View dossier" "view": "Dossiers sehen"
}, },
"label": "{targetObject, select, Dossier{Dossier} other{}} permissions", "label": "{targetObject, select, Dossier{Dossier} other{}}-Berechtigungen",
"mapped": { "mapped": {
"approve": "Dossier members", "approve": "Dossier-Mitglieder",
"everyone-else": "Everyone else", "everyone-else": "Sonstige",
"owner": "Owner", "owner": "Besitzer",
"review": "" "review": ""
}, },
"table-col-names": { "table-col-names": {
"permission": "Permission" "permission": "Berechtigung"
}, },
"table-header": { "table-header": {
"title": "{length} {length, plural, one{permission} other{permissions}}" "title": "{length} {length, plural, one{Berechtigung} other{Berechtigungen}}"
} }
}, },
"preferences-screen": { "preferences-screen": {
"actions": { "actions": {
"save": "Save changes" "save": "Änderungen speichern"
}, },
"form": { "form": {
"auto-expand-filters-on-action": "Auto expand filters on my actions", "auto-expand-filters-on-action": "Filter ausgehend von meinen Aktionen automatisch anpassen",
"help-mode-dialog": "Help Mode Dialog", "help-mode-dialog": "Dialog zur Aktivierung des Hilfemodus",
"load-all-annotations-warning": "Warning regarding loading all annotations at once in file preview", "load-all-annotations-warning": "Warnung bei gleichzeitigem Laden aller Annotationen in der Miniaturansicht",
"overwrite-file-option": "Preferred action when re-uploading an already existing file", "overwrite-file-option": "Bevorzugte Aktion beim erneuten Hochladen einer bereits vorhandenen Datei",
"table-extraction-type": "Table extraction type" "table-extraction-type": "Art der Tabellenextraktion"
}, },
"label": "Preferences", "label": "Präferenzen",
"title": "Edit preferences", "title": "Präferenzen bearbeiten",
"warnings-description": "Selecting the 'Do not show this message again' checkbox will skip the warning dialog the next time you trigger it.", "warnings-description": "Wenn Sie das Kontrollkästchen „Diese Nachricht nicht mehr anzeigen“ aktivieren, wird dieser Dialog beim nächsten Mal übersprungen.",
"warnings-label": "Prompts and dialogs", "warnings-label": "Dialoge und Meldungen",
"warnings-subtitle": "Do not show again options" "warnings-subtitle": "„Nicht mehr anzeigen“-Optionen"
},
"processing": {
"basic": "Verarbeitung läuft",
"ocr": "OCR"
}, },
"processing-status": { "processing-status": {
"ocr": "OCR", "ocr": "OCR",
"pending": "Pending", "pending": "Ausstehend",
"processed": "Processed", "processed": "Verarbeitet",
"processing": "Processing" "processing": "Verarbeitung läuft"
}, },
"processing": { "processing": {
"basic": "Processing", "basic": "Processing",
"ocr": "OCR" "ocr": "OCR"
}, },
"readonly": "Lesemodus", "readonly": "Lesemodus",
"readonly-archived": "Read only (archived)", "readonly-archived": "Lesemodus (archiviert)",
"redact-text": { "redact-text": {
"dialog": { "dialog": {
"actions": { "actions": {
"cancel": "Cancel", "cancel": "Abbrechen",
"save": "Save" "save": "Speichern"
}, },
"content": { "content": {
"comment": "Comment", "comment": "Kommentar",
"comment-placeholder": "Add remarks or mentions...", "comment-placeholder": "Bemerkungen oder Notizen hinzufügen...",
"edit-text": "", "edit-text": "",
"legal-basis": "Legal basis", "legal-basis": "Rechtsgrundlage",
"options": { "options": {
"in-document": { "in-document": {
"description": "Fügen Sie die Schwärzung an allen Stellen in diesem Dokument hinzu.", "description": "Fügen Sie die Schwärzung an allen Stellen in diesem Dokument hinzu.",
"label": "Im Dokument schwärzen" "label": "Im Dokument schwärzen"
}, },
"in-dossier": { "in-dossier": {
"description": "Add redaction in every document in {dossierName}.", "description": "Fügen Sie die Schwärzung zu jedem Dokument in {dossierName} hinzu.",
"extraOptionLabel": "Apply to all dossiers", "extraOptionLabel": "In alle Dossiers übernehmen",
"label": "Redact in dossier" "label": "Im Dossier schwärzen"
}, },
"only-here": { "only-here": {
"description": "Add redaction only at this position in this document.", "description": "Fügen Sie die Schwärzung zu jedem Dokument in {dossierName} hinzu.",
"label": "Redact only here" "label": "Nur hier schwärzen"
} }
}, },
"reason": "Reason", "reason": "Grund",
"reason-placeholder": "Select a reasons...", "reason-placeholder": "Grund auswählen...",
"revert-text": "", "revert-text": "",
"type": "Type", "type": "Typ",
"type-placeholder": "Select type...", "type-placeholder": "Typ auswählen...",
"unchanged": "", "unchanged": "",
"value": "" "value": "Wert"
}, },
"title": "Redact text" "title": "Text schwärzen"
} }
}, },
"redaction-abbreviation": "C", "redaction-abbreviation": "A",
"references": "{count} {count, plural, one{reference} other{references}}", "references": "{count} {count, plural, one{Verweis} other{Verweise}}",
"remove-annotation": { "remove-annotation": {
"dialog": { "dialog": {
"actions": { "actions": {
"cancel": "Cancel", "cancel": "Abbrechen",
"save": "Save" "save": "Speichern"
}, },
"content": { "content": {
"comment": "Comment", "comment": "Kommentar",
"comment-placeholder": "Add remarks or mentions...", "comment-placeholder": "Bemerkungen oder Notizen hinzufügen...",
"list-item": "{text}", "list-item": "{text}",
"list-item-false-positive": "''{text}'' in the context: ''{context}''", "list-item-false-positive": "\"{text} im Kontext: \"{context}\"",
"options": { "options": {
"false-positive": { "false-positive": {
"description": "''{value}'' is not a ''{type}'' in this context: ''{context}''.", "description": "''{value}''ist kein ''{type}'' in diesem Kontext: ''{context}''.",
"description-bulk": "The selected items should not be annotated in their respective contexts.", "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": "False positive" "label": "Falsch-Positiv"
}, },
"in-document": { "in-document": {
"description": "", "description": "",
"label": "" "label": "Aus Dokument entfernen"
}, },
"in-dossier": { "in-dossier": {
"description": "Do not annotate ''{value}'' as ''{type}'' in any dossier.", "description": "Der Begriff wird in keinem Dossier annotiert.",
"description-bulk": "Do not annotate the selected terms as their respective types in any dossier.", "description-bulk": "Der Begriff wird in keinem Dossiers mit dem entsprechenden Typ annotiert.",
"label": "No longer annotate as ''{type}''", "label": "Aus Dossier entfernen",
"label-bulk": "No longer annotate in any dossier" "label-bulk": "Aus Dossier entfernen"
}, },
"only-here": { "only-here": {
"description": "Do not annotate ''{value}'' at this position in the current document.", "description": "Annotieren Sie den Begriff an dieser Stelle im Dokument nicht.",
"description-bulk": "Do not annotate the selected terms at this position in the current document.", "description-bulk": "Annotieren Sie den Begriff an dieser Stelle im Dokument nicht.",
"label": "Remove here" "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": { "remove-rectangle": {
@ -2201,11 +2213,11 @@
"remove-redaction": { "remove-redaction": {
"dialog": { "dialog": {
"actions": { "actions": {
"cancel": "Cancel", "cancel": "Abbrechen",
"save": "Save" "save": "Speichern"
}, },
"content": { "content": {
"comment": "Comment", "comment": "Kommentar",
"comment-placeholder": "Add remarks or mentions...", "comment-placeholder": "Add remarks or mentions...",
"options": { "options": {
"do-not-recommend": { "do-not-recommend": {
@ -2222,11 +2234,11 @@
"label": "False positive" "label": "False positive"
}, },
"in-document": { "in-document": {
"description": "{isImage, select, image{Das Bild} other{der Begriff}} wird auf keiner Seite dieses Dokuments automatisch geschwärzt.", "description": "",
"label": "Aus Dokument entfernen" "label": "Aus Dokument entfernen"
}, },
"in-dossier": { "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": "", "description-bulk": "",
"extraOptionLabel": "Apply to all dossiers", "extraOptionLabel": "Apply to all dossiers",
"label": "Remove from dossier", "label": "Remove from dossier",

View File

@ -112,6 +112,9 @@
} }
}, },
"add-edit-dossier-attribute": { "add-edit-dossier-attribute": {
"error": {
"generic": "Failed to save attribute!"
},
"form": { "form": {
"label": "Attribute name", "label": "Attribute name",
"label-placeholder": "Enter name", "label-placeholder": "Enter name",
@ -135,9 +138,6 @@
}, },
"add-edit-entity": { "add-edit-entity": {
"form": { "form": {
"ai-creation-enabled": "Enable AI creation",
"ai-description": "AI Description",
"ai-description-placeholder": "Enter AI description",
"case-sensitive": "Case-sensitive", "case-sensitive": "Case-sensitive",
"color": "{type, select, redaction{Annotation} hint{Hint} recommendation{Recommendation} skipped{Skipped annotation} ignored{Ignored hint} other{}} Color", "color": "{type, select, redaction{Annotation} hint{Hint} recommendation{Recommendation} skipped{Skipped annotation} ignored{Ignored hint} other{}} Color",
"color-placeholder": "#", "color-placeholder": "#",
@ -1305,7 +1305,7 @@
"options": { "options": {
"in-document": { "in-document": {
"description": "", "description": "",
"label": "" "label": "In Dokument ändern"
}, },
"only-here": { "only-here": {
"description": "", "description": "",
@ -1874,8 +1874,8 @@
} }
}, },
"license-information": "License Information", "license-information": "License Information",
"load-all-annotations-success": "All annotations were loaded and are now visible in the document thumbnails", "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": "<strong>Alert:</strong> 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", "load-all-annotations-threshold-exceeded-checkbox": "Do not show this warning again",
"loading": "Loading", "loading": "Loading",
"manual-annotation": { "manual-annotation": {
@ -1889,14 +1889,14 @@
"legalBasis": "Legal Basis", "legalBasis": "Legal Basis",
"options": { "options": {
"multiple-pages": { "multiple-pages": {
"description": "Edit redaction the range of pages", "description": "Edit annotation the range of pages",
"extraOptionDescription": "Minus(-) for range and comma(,) for enumeration", "extraOptionDescription": "Minus(-) for range and comma(,) for enumeration",
"extraOptionLabel": "Range", "extraOptionLabel": "Range",
"extraOptionPlaceholder": "e.g. 1-20,22,32", "extraOptionPlaceholder": "e.g. 1-20,22,32",
"label": "Apply on multiple pages" "label": "Apply on multiple pages"
}, },
"only-this-page": { "only-this-page": {
"description": "Edit redaction only at this position in this document", "description": "Edit annotation only at this position in this document",
"label": "Apply only on this page" "label": "Apply only on this page"
} }
}, },
@ -1919,16 +1919,16 @@
"minutes": "minutes", "minutes": "minutes",
"no-active-license": "Invalid or corrupt license Please contact your administrator", "no-active-license": "Invalid or corrupt license Please contact your administrator",
"notification": { "notification": {
"assign-approver": "You have been assigned to <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!", "assign-approver": "You have been assigned as approver for a document. <br>Document: <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> <br> Dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>",
"assign-reviewer": "You have been assigned to <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!", "assign-reviewer": "You have been assigned as reviewer for a document. <br>Document: <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> <br>\nDossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>",
"document-approved": " <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> has been moved to Done!", "document-approved": " <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> has been moved to Done!",
"dossier-deleted": "Dossier: <b>{dossierName}</b> has been deleted!", "dossier-deleted": "Dossier: <b>{dossierName}</b> has been deleted!",
"dossier-owner-deleted": "The owner of dossier: <b>{dossierName}</b> has been deleted!", "dossier-owner-deleted": "The owner of dossier: <b>{dossierName}</b> has been deleted!",
"dossier-owner-removed": "You have been removed as dossier owner from <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!", "dossier-owner-removed": "You have been removed as dossier owner from <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
"dossier-owner-set": "You are now the dossier owner of <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!", "dossier-owner-set": "You are now the dossier owner of <b>{dossierHref, select, null{{dossierName}} other\n{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
"download-ready": "Your <b><a href=\"{downloadHref}\", target=\"_self\">download</a></b> is ready!", "download-ready": "Your <b><a href=\"{downloadHref}\", target=\"_self\">download</a></b> is ready!",
"no-data": "You currently have no notifications", "no-data": "You currently have no notifications",
"unassigned-from-file": "You have been unassigned from <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> in dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>!", "unassigned-from-file": "You have been unassigned from a document. <br>Document: <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> <br>Dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>\n}}}}</b>",
"user-becomes-dossier-member": "You have been added to dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!", "user-becomes-dossier-member": "You have been added to dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
"user-demoted-to-reviewer": "You have been demoted to reviewer in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!", "user-demoted-to-reviewer": "You have been demoted to reviewer in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
"user-promoted-to-approver": "You have been promoted to approver in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!", "user-promoted-to-approver": "You have been promoted to approver in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
@ -1982,12 +1982,12 @@
"ocr": { "ocr": {
"confirmation-dialog": { "confirmation-dialog": {
"cancel": "Cancel", "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!" "title": "Warning: the file has manual adjustments!"
} }
}, },
"overwrite-files-dialog": { "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", "archive-title": "Uploading a ZIP archive",
"file-question": "<b>{filename}</b> already exists. Choose how to proceed:", "file-question": "<b>{filename}</b> already exists. Choose how to proceed:",
"file-title": "File already exists!", "file-title": "File already exists!",
@ -1996,16 +1996,16 @@
"cancel": "Cancel upload", "cancel": "Cancel upload",
"current-files": "Apply to current file", "current-files": "Apply to current file",
"full-overwrite": { "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" "label": "Overwrite and start over"
}, },
"partial-overwrite": { "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" "label": "Overwrite and keep manual changes"
}, },
"proceed": "Proceed", "proceed": "Proceed",
"skip": { "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" "label": "Keep the existing file and do not overwrite"
} }
}, },
@ -2079,14 +2079,14 @@
}, },
"form": { "form": {
"auto-expand-filters-on-action": "Auto expand filters on my actions", "auto-expand-filters-on-action": "Auto expand filters on my actions",
"help-mode-dialog": "Help Mode Dialog", "help-mode-dialog": "Help mode activation dialog",
"load-all-annotations-warning": "Warning regarding loading all annotations at once in file preview", "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", "overwrite-file-option": "Preferred action when re-uploading an already existing file",
"table-extraction-type": "Table extraction type" "table-extraction-type": "Table extraction type"
}, },
"label": "Preferences", "label": "Preferences",
"title": "Edit 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-label": "Prompts and dialogs",
"warnings-subtitle": "Do not show again options" "warnings-subtitle": "Do not show again options"
}, },
@ -2155,21 +2155,21 @@
"options": { "options": {
"false-positive": { "false-positive": {
"description": "''{value}'' is not a ''{type}'' in this context: ''{context}''.", "description": "''{value}'' is not a ''{type}'' in this context: ''{context}''.",
"description-bulk": "The selected items should not be annotated in their respective contexts.", "description-bulk": "Mark this redaction as a false-positive. The term will not be redacted in this dossier if it occurs in the same context.",
"label": "False positive" "label": "False positive"
}, },
"in-document": { "in-document": {
"description": "", "description": "",
"label": "" "label": "Aus Dokument entfernen"
}, },
"in-dossier": { "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.", "description-bulk": "Do not annotate the selected terms as their respective types in any dossier.",
"label": "No longer annotate as ''{type}''", "label": "No longer annotate as ''{type}''",
"label-bulk": "No longer annotate in any dossier" "label-bulk": "Do not annotate as <i>{type}</i>"
}, },
"only-here": { "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.", "description-bulk": "Do not annotate the selected terms at this position in the current document.",
"label": "Remove here" "label": "Remove here"
} }
@ -2223,10 +2223,10 @@
}, },
"in-document": { "in-document": {
"description": "", "description": "",
"label": "" "label": "Aus Dokument entfernen"
}, },
"in-dossier": { "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": "", "description-bulk": "",
"extraOptionLabel": "Apply to all dossiers", "extraOptionLabel": "Apply to all dossiers",
"label": "Remove from dossier", "label": "Remove from dossier",

@ -1 +1 @@
Subproject commit e88929f0d48e54298d85ef05ea467980be11524b Subproject commit a3f931e4bcbb2d99e38de01c253ec7e0c54c8001

View File

@ -7,8 +7,6 @@ export class Dictionary extends Entity<IDictionary> implements IDictionary {
readonly addToDictionaryAction: boolean; readonly addToDictionaryAction: boolean;
readonly caseInsensitive: boolean; readonly caseInsensitive: boolean;
readonly description: string; readonly description: string;
readonly aiCreationEnabled: boolean;
readonly aiDescription: string;
readonly dossierTemplateId?: string; readonly dossierTemplateId?: string;
readonly hexColor?: string; readonly hexColor?: string;
readonly recommendationHexColor?: string; readonly recommendationHexColor?: string;
@ -35,8 +33,6 @@ export class Dictionary extends Entity<IDictionary> implements IDictionary {
this.addToDictionaryAction = !!entity.addToDictionaryAction; this.addToDictionaryAction = !!entity.addToDictionaryAction;
this.caseInsensitive = !!entity.caseInsensitive; this.caseInsensitive = !!entity.caseInsensitive;
this.description = entity.description ?? ''; this.description = entity.description ?? '';
this.aiCreationEnabled = !!entity.aiCreationEnabled;
this.aiDescription = entity.aiDescription ?? '';
this.dossierTemplateId = entity.dossierTemplateId; this.dossierTemplateId = entity.dossierTemplateId;
this.entries = entity.entries ?? []; this.entries = entity.entries ?? [];
this.falsePositiveEntries = entity.falsePositiveEntries ?? []; this.falsePositiveEntries = entity.falsePositiveEntries ?? [];

View File

@ -16,14 +16,6 @@ export interface IDictionary {
* The description of the dictionary type * The description of the dictionary type
*/ */
readonly description?: string; 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 * The DossierTemplate Id for this type
*/ */

View File

@ -1,15 +1,18 @@
import { IListable } from '@iqser/common-ui'; import { IListable } from '@iqser/common-ui';
import { ILegalBasis } from './legal-basis'; import { ILegalBasis } from './legal-basis';
import { toSnakeCase } from '@utils/functions';
export class Justification implements ILegalBasis, IListable { export class Justification implements ILegalBasis, IListable {
readonly description?: string; readonly description?: string;
readonly name: string; readonly name: string;
readonly reason?: string; readonly reason?: string;
readonly technicalName?: string;
constructor(justification: ILegalBasis) { constructor(justification: ILegalBasis) {
this.description = justification.description; this.description = justification.description;
this.name = justification.name; this.name = justification.name;
this.reason = justification.reason; this.reason = justification.reason;
this.technicalName = justification.technicalName;
} }
get id(): string { get id(): string {
@ -19,4 +22,13 @@ export class Justification implements ILegalBasis, IListable {
get searchKey(): string { get searchKey(): string {
return this.name; 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;
}
} }

View File

@ -2,4 +2,5 @@ export interface ILegalBasis {
readonly name: string; readonly name: string;
readonly description?: string; readonly description?: string;
readonly reason?: string; readonly reason?: string;
readonly technicalName?: string;
} }