Compare commits

...

23 Commits

Author SHA1 Message Date
Valentin Mihai
9d18113f56 RED-7340 - Rectangle redactions: Use bulk-local redactions + New dialog design 2024-10-23 23:48:02 +03:00
Valentin Mihai
d04f1b7b0b RED-9585 - Incorrect capitalization in German translation + missing singular/plural distinction 2024-10-23 22:25:10 +03:00
Nicoleta Panaghiu
b1948622fe RED-8277: update common ui. 2024-10-23 16:11:06 +03:00
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
35 changed files with 515 additions and 356 deletions

View File

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

View File

@ -23,7 +23,7 @@
<div class="mt-44">
<redaction-donut-chart
[config]="chartConfig"
[config]="chartConfig()"
[radius]="63"
[strokeWidth]="15"
[subtitles]="['user-stats.chart.users' | translate]"

View File

@ -1,4 +1,4 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { Component, EventEmitter, input, Input, output, Output } from '@angular/core';
import { DonutChartConfig } from '@red/domain';
import { CircleButtonComponent } from '@iqser/common-ui';
import { TranslateModule } from '@ngx-translate/core';
@ -12,6 +12,6 @@ import { DonutChartComponent } from '@shared/components/donut-chart/donut-chart.
imports: [CircleButtonComponent, TranslateModule, DonutChartComponent],
})
export class UsersStatsComponent {
@Output() toggleCollapse = new EventEmitter();
@Input() chartConfig: DonutChartConfig[];
readonly chartConfig = input.required<DonutChartConfig[]>();
readonly toggleCollapse = output();
}

View File

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

View File

@ -17,8 +17,17 @@
type="text"
/>
</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>
<input
[placeholder]="'add-edit-justification.form.reason-placeholder' | translate"
@ -28,7 +37,7 @@
/>
</div>
<div class="iqser-input-group required w-400">
<div class="iqser-input-group w-400">
<label translate="add-edit-justification.form.description"></label>
<textarea
[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 { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Justification } from '@red/domain';
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 { TranslateModule } from '@ngx-translate/core';
import { formControlToSignal } from '@utils/functions';
import { toSignal } from '@angular/core/rxjs-interop';
interface DialogData {
justification?: Justification;
@ -16,9 +18,29 @@ interface DialogData {
templateUrl: './add-edit-justification-dialog.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [TranslateModule, ReactiveFormsModule, IconButtonComponent, CircleButtonComponent],
imports: [TranslateModule, ReactiveFormsModule, IconButtonComponent, CircleButtonComponent, HasScrollbarDirective],
})
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(
private readonly _justificationService: JustificationsService,
protected readonly _dialogRef: MatDialogRef<AddEditJustificationDialogComponent>,
@ -26,7 +48,6 @@ export class AddEditJustificationDialogComponent extends BaseDialogComponent {
) {
super(_dialogRef, !!data.justification);
this.form = this._getForm();
this.initialFormValue = this.form.getRawValue();
}
@ -34,7 +55,8 @@ export class AddEditJustificationDialogComponent extends BaseDialogComponent {
const dossierTemplateId = this.data.dossierTemplateId;
this._loadingService.start();
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));
this._dialogRef.close(true);
} catch (error) {
@ -43,11 +65,12 @@ export class AddEditJustificationDialogComponent extends BaseDialogComponent {
this._loadingService.stop();
}
private _getForm(): UntypedFormGroup {
#getForm(): UntypedFormGroup {
return this._formBuilder.group({
name: [{ value: this.data.justification?.name, disabled: !!this.data.justification }, Validators.required],
reason: [this.data.justification?.reason, Validators.required],
description: [this.data.justification?.description, Validators.required],
reason: [this.data.justification?.reason],
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) {
$event.stopPropagation();
$event.preventDefault();
}
ngOnDestroy() {
@ -154,12 +155,14 @@ export class FileAttributeComponent extends BaseFormComponent implements OnDestr
}
handleFieldClick($event: MouseEvent) {
$event.preventDefault();
if (!this.fileNameColumn) {
this.editFileAttribute($event);
}
}
editFileAttribute($event: MouseEvent) {
$event.preventDefault();
if (
!this.file.isInitialProcessing &&
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])
);
}
@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"
></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">
<redaction-selected-annotations-table
[columns]="tableColumns"
@ -107,7 +107,7 @@
formControlName="comment"
iqserHasScrollbar
name="comment"
rows="4"
rows="3"
type="text"
></textarea>
</div>

View File

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

View File

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

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.comment = this.form.get('comment').value;
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;
}

View File

@ -2,7 +2,7 @@
<form (submit)="save()" [formGroup]="form">
<div [translate]="'manual-annotation.dialog.header.redaction'" class="dialog-header heading-l"></div>
<div class="dialog-content">
<div class="dialog-content redaction">
<iqser-details-radio
[options]="options"
(extraOptionChanged)="extraOptionChanged($event)"
@ -43,7 +43,7 @@
<div class="iqser-input-group w-450">
<label [translate]="'manual-annotation.dialog.content.comment'"></label>
<textarea formControlName="comment" iqserHasScrollbar name="comment" rows="4" type="text"></textarea>
<textarea formControlName="comment" iqserHasScrollbar name="comment" rows="3" type="text"></textarea>
</div>
</div>

View File

@ -3,8 +3,8 @@
}
.dialog-content {
height: 650px;
overflow-y: auto;
height: 600px;
padding-top: 8px;
}
.apply-on-multiple-pages {

View File

@ -130,7 +130,7 @@ export class RectangleAnnotationDialog
reason: [null, Validators.required],
comment: [null],
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';
import { isJustOne } from '@common-ui/utils';
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({
templateUrl: './remove-redaction-dialog.component.html',
@ -112,7 +112,7 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent<
readonly redactedTexts = this.data.redactions.map(annotation => annotation.value);
form: UntypedFormGroup = this._formBuilder.group({
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)));
@ -140,6 +140,14 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent<
private readonly _userPreferences: UserPreferenceService,
) {
super();
if (this.#allRectangles) {
prefillPageRange(
this.data.redactions[0],
this.data.allFileRedactions,
this.options as DetailsRadioOption<RectangleRedactOption>[],
);
}
}
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)
super.ngOnDetach();
this.pdf.instance.UI.hotkeys.off('esc');
this.pdf.instance.UI.iframeWindow.document.removeEventListener('click', this.handleViewerClick);
this._changeRef.markForCheck();
}
ngOnDestroy() {
this.pdf.instance.UI.hotkeys.off('esc');
this.pdf.instance.UI.iframeWindow.document.removeEventListener('click', this.handleViewerClick);
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) {
if (!this.state.file().canBeOpened) {
return this.#navigateToDossier();
@ -307,6 +328,8 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
this.#restoreOldFilters();
this.pdf.instance.UI.hotkeys.on('esc', this.handleEscInsideViewer);
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) {

View File

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

View File

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

View File

@ -1,7 +1,8 @@
import { Dictionary, File, IAddRedactionRequest, IEntityLogEntryPosition, SuperType } from '@red/domain';
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 { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option';
export interface EnhanceRequestData {
readonly type: SuperType | null;
@ -79,3 +80,60 @@ export const parseRectanglePosition = (annotation: AnnotationWrapper) => {
pageNumber: position.page,
} 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';
export const validatePageRange = (allowEmpty = false): ValidatorFn => {
export const validatePageRange = (numberOfPages: number, allowEmpty = false): ValidatorFn => {
return (control: AbstractControl): { [key: string]: any } | null => {
const option = control.value;
if (option?.additionalInput) {
const value = option.additionalInput.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;
};

View File

@ -78,24 +78,6 @@
></textarea>
</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">
<mat-slide-toggle color="primary" formControlName="hasDictionary">
{{ '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 { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
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 { Dictionary, IDictionary } from '@red/domain';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
@ -62,7 +62,6 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit
colors: Color[];
readonly isDocumine = getConfig().IS_DOCUMINE;
readonly isIqserDevMode = isIqserDevMode();
constructor(
private readonly _dictionariesMapService: DictionariesMapService,
@ -159,8 +158,6 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit
skippedHexColor: [this.entity?.skippedHexColor, [Validators.required, Validators.minLength(7)]],
type: [this.entity?.type],
description: [this.entity?.description],
aiCreationEnabled: [this.entity?.aiCreationEnabled],
aiDescription: [this.entity?.aiDescription],
rank: [{ value: this.entity?.rank, disabled: this.#isSystemManaged }, Validators.required],
hint: [{ value: !!this.entity?.hint, disabled: this.#isSystemManaged }],
hasDictionary: [
@ -253,8 +250,6 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit
dossierTemplateId: this.dossierTemplateId,
type: this.form.get('type').value,
description: this.form.get('description').value,
aiCreationEnabled: this.form.get('aiCreationEnabled').value,
aiDescription: this.form.get('aiDescription').value,
hint: this.#isHint,
rank: this.form.get('rank').value,
caseInsensitive: !this.form.get('caseSensitive').value,

View File

@ -57,7 +57,7 @@ export class TranslateChartService {
translateRoles(config: DonutChartConfig[]): DonutChartConfig[] {
return config.map(val => ({
...val,
label: this._translateService.instant(rolesTranslations[val.label]).toLowerCase(),
label: this._translateService.instant(rolesTranslations[val.label], { length: val.value }),
}));
}
}

View File

@ -2,7 +2,7 @@ import { ITrackable } from '@iqser/common-ui';
import type { List } from '@iqser/common-ui/lib/utils';
import type { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { Dayjs } from 'dayjs';
import { FormControl } from '@angular/forms';
import { AbstractControl } from '@angular/forms';
import { toSignal } from '@angular/core/rxjs-interop';
export function hexToRgb(hex: string) {
@ -146,6 +146,6 @@ export function urlFileId() {
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 });
}

View File

@ -112,6 +112,9 @@
}
},
"add-edit-dossier-attribute": {
"error": {
"generic": "Speichern des Attributs fehlgeschlagen."
},
"form": {
"label": "Name des Attributs",
"label-placeholder": "Namen eingeben",
@ -135,9 +138,6 @@
},
"add-edit-entity": {
"form": {
"ai-creation-enabled": "AI Erzeugung aktivieren",
"ai-description": "AI Beschreibung",
"ai-description-placeholder": "AI Beschreibung eingeben",
"case-sensitive": "Groß-/Kleinschreibung beachten",
"color": "Farbe {type, select, redaction{Schwärzung} hint{Hinweis} recommendation{Empfehlung} skipped{Ingorierte Schwärzung} ignored{Ignorierter Hinweis} other{}}",
"color-placeholder": "#",
@ -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/>."
},
"download-type": {
"annotated": "Annotierte PDF",
"annotated": "Annotiertes PDF",
"delta-preview": "Delta-PDF",
"flatten": "Verflachte PDF",
"flatten": "Verflachtes PDF",
"label": "{length} Dokumenten{length, plural, one{typ} other{typen}}",
"optimized-preview": "Optimierte Vorschau-PDF",
"original": "Optimierte PDF",
"optimized-preview": "Optimiertes Vorschau-PDF",
"original": "Optimiertes PDF",
"preview": "Vorschau-PDF",
"redacted": "Geschwärzte PDF",
"redacted-only": "Geschwärzte PDF (nur freigegebene Dateien)"
"redacted": "Geschwärztes PDF",
"redacted-only": "Geschwärztes PDF (nur freigegebene Dateien)"
},
"downloads-list": {
"actions": {
@ -1278,15 +1278,15 @@
"content": {
"options": {
"multiple-pages": {
"description": "",
"extraOptionDescription": "",
"extraOptionLabel": "",
"extraOptionPlaceholder": "",
"label": ""
"description": "Schwärzung auf folgenden Seiten bearbeiten",
"extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.",
"extraOptionLabel": "Seitenbereich",
"extraOptionPlaceholder": "z. B. 1-20,22,32",
"label": "Auf allen Seiten ändern"
},
"only-this-page": {
"description": "",
"label": ""
"description": "Schwärzung nur an dieser Position in diesem Dokument bearbeiten",
"label": "Nur auf dieser Seite ändern"
}
}
}
@ -1309,7 +1309,7 @@
},
"only-here": {
"description": "Bearbeiten Sie die Schwärzung nur an dieser Stelle im Dokument.",
"label": "Typ nur hier ändern"
"label": "Nur hier ändern"
}
},
"reason": "Grund",
@ -1794,8 +1794,8 @@
},
"import-only-for-pages": "Nur für diese Seiten importieren",
"range": {
"label": "Minus (-) für Spanne und Komma (,) für Aufzählung.",
"placeholder": "Beispiel: 1-20,22,32"
"label": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.",
"placeholder": "z. B. 1-20,22,32"
},
"title": "Dokument mit Schwärzungen importieren"
},
@ -1889,15 +1889,15 @@
"legalBasis": "Rechtsgrundlage",
"options": {
"multiple-pages": {
"description": "",
"extraOptionDescription": "",
"extraOptionLabel": "",
"extraOptionPlaceholder": "",
"label": ""
"description": "Schwärzung auf folgenden Seiten hinzufügen",
"extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.",
"extraOptionLabel": "Seitenbereich",
"extraOptionPlaceholder": "z. B. 1-20,22,32",
"label": "Auf mehreren Seiten anwenden"
},
"only-this-page": {
"description": "",
"label": ""
"description": "Schwärzung nur an dieser Position in diesem Dokument hinzufügen",
"label": "Auf dieser Seite anwenden"
}
},
"reason": "Grund",
@ -2134,7 +2134,7 @@
"type": "Typ",
"type-placeholder": "Typ auswählen...",
"unchanged": "Ungeändert",
"value": ""
"value": "Wert"
},
"title": "Text schwärzen"
}
@ -2184,15 +2184,15 @@
"content": {
"options": {
"multiple-pages": {
"description": "",
"extraOptionDescription": "",
"extraOptionLabel": "",
"extraOptionPlaceholder": "",
"label": ""
"description": "Schwärzung auf folgenden Seiten entfernen",
"extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.",
"extraOptionLabel": "Seitenbereich",
"extraOptionPlaceholder": "z. B. 1-20,22,32",
"label": "Auf allen Seiten entfernen"
},
"only-this-page": {
"description": "",
"label": ""
"description": "Schwärzung nur an dieser Stelle in diesem Dokument entfernen",
"label": "Nur auf dieser Seite entfernen"
}
}
}
@ -2359,13 +2359,13 @@
},
"roles": {
"inactive": "Inaktiv",
"manager-admin": "Manager & Admin",
"manager-admin": "Manager & {length, plural, one{Admin} other{Admins}}",
"no-role": "Keine Rolle definiert",
"red-admin": "Anwendungsadmin",
"red-admin": "{length, plural, one{Anwendungsadmin} other{Anwendungsadmins}}",
"red-manager": "Manager",
"red-user": "Benutzer",
"red-user-admin": "Benutzeradmin",
"regular": "regulärer Benutzer"
"red-user-admin": "{length, plural, one{Benutzeradmin} other{Benutzeradmins}}",
"regular": "{length, plural, one{regulärer} other{reguläre}} Benutzer"
},
"search-screen": {
"cols": {

View File

@ -112,6 +112,9 @@
}
},
"add-edit-dossier-attribute": {
"error": {
"generic": "Failed to save attribute."
},
"form": {
"label": "Attribute name",
"label-placeholder": "Enter name",
@ -135,9 +138,6 @@
},
"add-edit-entity": {
"form": {
"ai-creation-enabled": "Enable AI creation",
"ai-description": "AI Description",
"ai-description-placeholder": "Enter AI description",
"case-sensitive": "Case-sensitive",
"color": "{type, select, redaction{Redaction} hint{Hint} recommendation{Recommendation} skipped{Skipped redaction} ignored{Ignored hint} other{}} color",
"color-placeholder": "#",
@ -2359,12 +2359,12 @@
},
"roles": {
"inactive": "Inactive",
"manager-admin": "Manager & admin",
"manager-admin": "Manager & {length, plural, one{Admin} other{Admins}}",
"no-role": "No role defined",
"red-admin": "Application admin",
"red-manager": "Manager",
"red-user": "User",
"red-user-admin": "Users admin",
"red-admin": "Application {length, plural, one{admin} other{admins}}",
"red-manager": "{length, plural, one{Manager} other{Managers}}",
"red-user": "{length, plural, one{User} other{Users}}",
"red-user-admin": "{length, plural, one{User} other{Users}} admin",
"regular": "Regular"
},
"search-screen": {

View File

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

View File

@ -112,6 +112,9 @@
}
},
"add-edit-dossier-attribute": {
"error": {
"generic": "Failed to save attribute!"
},
"form": {
"label": "Attribute name",
"label-placeholder": "Enter name",
@ -135,9 +138,6 @@
},
"add-edit-entity": {
"form": {
"ai-creation-enabled": "Enable AI creation",
"ai-description": "AI Description",
"ai-description-placeholder": "Enter AI description",
"case-sensitive": "Case-sensitive",
"color": "{type, select, redaction{Annotation} hint{Hint} recommendation{Recommendation} skipped{Skipped annotation} ignored{Ignored hint} other{}} Color",
"color-placeholder": "#",
@ -1305,7 +1305,7 @@
"options": {
"in-document": {
"description": "",
"label": ""
"label": "In Dokument ändern"
},
"only-here": {
"description": "",
@ -1874,8 +1874,8 @@
}
},
"license-information": "License Information",
"load-all-annotations-success": "All annotations were loaded and are now visible in the document thumbnails",
"load-all-annotations-threshold-exceeded": "Caution, document contains more than {threshold} annotations. Drawing all annotations will affect the performance of the app and could even block it. Do you want to proceed?",
"load-all-annotations-success": "All annotations were loaded and are now visible in the document thumbnails.",
"load-all-annotations-threshold-exceeded": "<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",
"loading": "Loading",
"manual-annotation": {
@ -1889,14 +1889,14 @@
"legalBasis": "Legal Basis",
"options": {
"multiple-pages": {
"description": "Edit redaction the range of pages",
"description": "Edit annotation the range of pages",
"extraOptionDescription": "Minus(-) for range and comma(,) for enumeration",
"extraOptionLabel": "Range",
"extraOptionPlaceholder": "e.g. 1-20,22,32",
"label": "Apply on multiple pages"
},
"only-this-page": {
"description": "Edit redaction only at this position in this document",
"description": "Edit annotation only at this position in this document",
"label": "Apply only on this page"
}
},
@ -1919,16 +1919,16 @@
"minutes": "minutes",
"no-active-license": "Invalid or corrupt license Please contact your administrator",
"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-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-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 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!",
"dossier-deleted": "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-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!",
"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-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>!",
@ -1982,12 +1982,12 @@
"ocr": {
"confirmation-dialog": {
"cancel": "Cancel",
"question": "Manual changes could get lost if OCR makes changes at those positions. Are you sure you want to proceed?",
"question": "Manual changes may be overwritten if the OCR makes changes at the respective positions. Do you still want to proceed?",
"title": "Warning: the file has manual adjustments!"
}
},
"overwrite-files-dialog": {
"archive-question": "Dossier is not empty, so files might overlap with the contents of the archive you are uploading. Choose how to proceed in case of duplicates:",
"archive-question": "Dossier already contains files. Files might overlap with the contents of the folder you are uploading. Select how to handle duplicates:",
"archive-title": "Uploading a ZIP archive",
"file-question": "<b>{filename}</b> already exists. Choose how to proceed:",
"file-title": "File already exists!",
@ -1996,16 +1996,16 @@
"cancel": "Cancel upload",
"current-files": "Apply to current file",
"full-overwrite": {
"description": "Manual changes done to the existing file will be removed and you are able to start over.",
"description": "Remove all manual changes made to the file, and start reviewing a freshly processed file.",
"label": "Overwrite and start over"
},
"partial-overwrite": {
"description": "Manual changes are kept only if the affected annotations are still at the same position in the file. Some annotations could be misplaced if the content of the file changed.",
"description": "Keep manual changes if the affected redactions remain in their original positions. Some redactions could be misplaced if the content has changed.",
"label": "Overwrite and keep manual changes"
},
"proceed": "Proceed",
"skip": {
"description": "The upload will be skipped and the existing file will not be replaced.",
"description": "Skip the file upload and do not replace the existing file.",
"label": "Keep the existing file and do not overwrite"
}
},
@ -2079,14 +2079,14 @@
},
"form": {
"auto-expand-filters-on-action": "Auto expand filters on my actions",
"help-mode-dialog": "Help Mode Dialog",
"load-all-annotations-warning": "Warning regarding loading all annotations at once in file preview",
"help-mode-dialog": "Help mode activation dialog",
"load-all-annotations-warning": "Warning regarding simultaneous loading of all annotations in thumbnails",
"overwrite-file-option": "Preferred action when re-uploading an already existing file",
"table-extraction-type": "Table extraction type"
},
"label": "Preferences",
"title": "Edit preferences",
"warnings-description": "Selecting the 'Do not show this message again' checkbox will skip the warning dialog the next time you trigger it.",
"warnings-description": "Selecting the 'Do not show this message again' checkbox will skip the dialog the next time you trigger it.",
"warnings-label": "Prompts and dialogs",
"warnings-subtitle": "Do not show again options"
},
@ -2155,21 +2155,21 @@
"options": {
"false-positive": {
"description": "''{value}'' is not a ''{type}'' in this context: ''{context}''.",
"description-bulk": "The selected items should not be annotated in their respective contexts.",
"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"
},
"in-document": {
"description": "",
"label": ""
"label": "Aus Dokument entfernen"
},
"in-dossier": {
"description": "Do not annotate ''{value}'' as ''{type}'' in any dossier.",
"description": "Do not annotate the term in any dossier.",
"description-bulk": "Do not annotate the selected terms as their respective types in any dossier.",
"label": "No longer annotate as ''{type}''",
"label-bulk": "No longer annotate in any dossier"
"label-bulk": "Do not annotate as <i>{type}</i>"
},
"only-here": {
"description": "Do not annotate ''{value}'' at this position in the current document.",
"description": "Do not annotate the term at this position in this document.",
"description-bulk": "Do not annotate the selected terms at this position in the current document.",
"label": "Remove here"
}
@ -2223,10 +2223,10 @@
},
"in-document": {
"description": "",
"label": ""
"label": "Aus Dokument entfernen"
},
"in-dossier": {
"description": "Do not {type} \"{value}\" in any document of the current dossier.",
"description": "Do not annotate the term in this dossier.",
"description-bulk": "",
"extraOptionLabel": "Apply to all dossiers",
"label": "Remove from dossier",
@ -2359,12 +2359,12 @@
},
"roles": {
"inactive": "Inactive",
"manager-admin": "Manager & admin",
"manager-admin": "Manager & {length, plural, one{Admin} other{Admins}}",
"no-role": "No role defined",
"red-admin": "Application admin",
"red-manager": "Manager",
"red-user": "User",
"red-user-admin": "Users admin",
"red-admin": "Application {length, plural, one{admin} other{admins}}",
"red-manager": "{length, plural, one{Manager} other{Managers}}",
"red-user": "{length, plural, one{User} other{Users}}",
"red-user-admin": "{length, plural, one{User} other{Users}} admin",
"regular": "Regular"
},
"search-screen": {

@ -1 +1 @@
Subproject commit e88929f0d48e54298d85ef05ea467980be11524b
Subproject commit 074f88e66abc765b0ef8654eb56a552d88e1bbda

View File

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

View File

@ -16,14 +16,6 @@ export interface IDictionary {
* The description of the dictionary type
*/
readonly description?: string;
/**
* True if the entries in this type should also be created via AI, default is false.
*/
readonly aiCreationEnabled?: boolean;
/**
* The AI description of the dictionary type
*/
readonly aiDescription?: string;
/**
* The DossierTemplate Id for this type
*/

View File

@ -1,15 +1,18 @@
import { IListable } from '@iqser/common-ui';
import { ILegalBasis } from './legal-basis';
import { toSnakeCase } from '@utils/functions';
export class Justification implements ILegalBasis, IListable {
readonly description?: string;
readonly name: string;
readonly reason?: string;
readonly technicalName?: string;
constructor(justification: ILegalBasis) {
this.description = justification.description;
this.name = justification.name;
this.reason = justification.reason;
this.technicalName = justification.technicalName;
}
get id(): string {
@ -19,4 +22,13 @@ export class Justification implements ILegalBasis, IListable {
get searchKey(): string {
return this.name;
}
static toTechnicalName(value: string) {
const baseTechnicalName = toSnakeCase(value.trim());
let technicalName = baseTechnicalName.replaceAll(/[^A-Za-z0-9_-]/g, '');
if (!technicalName.length && baseTechnicalName.length) {
technicalName = '_';
}
return technicalName;
}
}

View File

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