Compare commits

...

26 Commits

Author SHA1 Message Date
Nicoleta Panaghiu
aa171f992b RED-10144: fixed multi-selection randomly activating. 2024-10-09 16:55:14 +03:00
Dan Percic
33bacfd967 Merge branch 'RED-10084-bp' into 'release/4.830.x'
RED-10084: All members of a dossier are able to reanalyse files in error...

See merge request redactmanager/red-ui!596
2024-10-02 09:52:00 +02:00
Dominique Eifländer
ce262a5f3a RED-10084: All members of a dossier are able to reanalyse files in error state, no only the owner or assignee 2024-10-02 09:19:01 +02:00
Nicoleta Panaghiu
c6ec428bc4 RED-9486: fixed naming of images in remove dialog. 2024-09-25 14:56:47 +03:00
Nicoleta Panaghiu
edf9e61132 RED-9993: fixed license labels. 2024-09-23 15:57:50 +03:00
Nicoleta Panaghiu
e57d54a755 RED-10028: added OPTIMIZED_PREVIEW file type in download selection. 2024-09-23 12:52:21 +03:00
Nicoleta Panaghiu
036bfa2878 RED-9993: fixed license information. 2024-09-13 11:01:26 +03:00
Nicoleta Panaghiu
bf9e6816f8 RED-9372: update common ui. 2024-09-10 11:46:24 +03:00
Nicoleta Panaghiu
0bff02a3e7 RED-9372: fixed scrolling on dossier details. 2024-09-10 11:45:34 +03:00
Marius Schummer
9016ff91b3 RED-9937 - Backport of the tooltip label change for the document preview 2024-09-09 16:47:18 +02:00
Nicoleta Panaghiu
afa399baf1 RED-9372: fixed annotation details moving on hover. 2024-09-05 17:22:17 +03:00
Nicoleta Panaghiu
41b8407862 RED-9372: update common ui. 2024-09-05 17:22:04 +03:00
Nicoleta Panaghiu
303aa0a1a4 RED-9937: made preview tab available & trigger reanalysis when required. 2024-09-04 13:32:03 +03:00
Valentin Mihai
262e30e2c0 RED-9454 - Differences between Add Hint- and Add Redaction-Dialog 2024-09-03 17:55:01 +03:00
Nicoleta Panaghiu
901ba934af RED-9987: added sendSetPasswordMail flag in add user dialog. 2024-09-03 14:51:06 +03:00
Nicoleta Panaghiu
ca0fe4cf13 RED-9893: show missing type toaster only once. 2024-08-21 10:55:34 +03:00
Valentin Mihai
5d3eb3751c RED-9862 - Broken resize dialog for imported redaction from preview file with disabled auto-analysis on upload 2024-08-15 17:02:17 +03:00
Nicoleta Panaghiu
1db68cbb7a RED-9589: removed FP option for locally removed and forced redactions. 2024-08-14 11:25:37 +03:00
Nicoleta Panaghiu
c9b25e2af4 RED-9874: added user preference for overwrite file option. 2024-08-13 17:22:59 +03:00
Nicoleta Panaghiu
9881c3e321 RED-9504: fix some translations. 2024-08-02 10:54:51 +03:00
Nicoleta Panaghiu
e4cb33978c RED-9731: fixed help button position on resize. 2024-08-01 14:42:26 +03:00
Nicoleta Panaghiu
1376e1a486 RED-9516: fixed filter options alignment. 2024-08-01 13:17:56 +03:00
Nicoleta Panaghiu
1894a378b5 RED-9742: fixed logo router link. 2024-07-31 13:21:03 +03:00
Nicoleta Panaghiu
701a69db95 RED-9571: fixed initials-avatar not updating in some cases. 2024-07-31 12:48:44 +03:00
Nicoleta Panaghiu
77f94a7983 RED-9589: enabled false positive option for some annotation configs. 2024-07-29 12:20:06 +03:00
Nicoleta Panaghiu
108a3315da RED-9657: additional fixes for help mode links. 2024-07-23 12:46:30 +03:00
49 changed files with 569 additions and 350 deletions

View File

@ -9,7 +9,7 @@
<redaction-breadcrumbs></redaction-breadcrumbs> <redaction-breadcrumbs></redaction-breadcrumbs>
</div> </div>
<a [matTooltip]="'top-bar.navigation-items.back-to-dashboard' | translate" [routerLink]="['/']" class="logo"> <a [matTooltip]="'top-bar.navigation-items.back-to-dashboard' | translate" [routerLink]="['/main']" class="logo">
<div [attr.help-mode-key]="'home'" class="actions"> <div [attr.help-mode-key]="'home'" class="actions">
<iqser-logo (iqserHiddenAction)="userPreferenceService.toggleDevFeatures()" icon="iqser:logo"></iqser-logo> <iqser-logo (iqserHiddenAction)="userPreferenceService.toggleDevFeatures()" icon="iqser:logo"></iqser-logo>
<div class="app-name">{{ titleService.getTitle() }}</div> <div class="app-name">{{ titleService.getTitle() }}</div>

View File

@ -1,6 +1,6 @@
import { AnnotationPermissions } from '@models/file/annotation.permissions'; import { AnnotationPermissions } from '@models/file/annotation.permissions';
import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { Dictionary, LogEntryEngines, SuperTypes } from '@red/domain'; import { Dictionary, SuperTypes } from '@red/domain';
export const canUndo = (annotation: AnnotationWrapper, isApprover: boolean) => !isApprover && annotation.pending; export const canUndo = (annotation: AnnotationWrapper, isApprover: boolean) => !isApprover && annotation.pending;
@ -17,8 +17,9 @@ export const canAcceptRecommendation = (annotation: AnnotationWrapper) => annota
export const canMarkAsFalsePositive = (annotation: AnnotationWrapper, annotationEntity: Dictionary) => export const canMarkAsFalsePositive = (annotation: AnnotationWrapper, annotationEntity: Dictionary) =>
annotation.canBeMarkedAsFalsePositive && annotation.canBeMarkedAsFalsePositive &&
!annotation.hasBeenForcedRedaction &&
!annotation.hasBeenResizedLocally && !annotation.hasBeenResizedLocally &&
!annotation.isRemovedLocally &&
!annotation.hasBeenForcedRedaction &&
annotationEntity?.hasDictionary; annotationEntity?.hasDictionary;
export const canRemoveOnlyHere = (annotation: AnnotationWrapper, canAddRedaction: boolean, autoAnalysisDisabled: boolean) => export const canRemoveOnlyHere = (annotation: AnnotationWrapper, canAddRedaction: boolean, autoAnalysisDisabled: boolean) =>
@ -30,7 +31,7 @@ export const canRemoveFromDictionary = (annotation: AnnotationWrapper, autoAnaly
annotation.isModifyDictionary && annotation.isModifyDictionary &&
(annotation.isRedacted || annotation.isSkipped || annotation.isHint || (annotation.isIgnoredHint && !annotation.isRuleBased)) && (annotation.isRedacted || annotation.isSkipped || annotation.isHint || (annotation.isIgnoredHint && !annotation.isRuleBased)) &&
(autoAnalysisDisabled || !annotation.pending) && (autoAnalysisDisabled || !annotation.pending) &&
[LogEntryEngines.DICTIONARY, LogEntryEngines.DOSSIER_DICTIONARY].some(engine => annotation.engines.includes(engine)); annotation.isDictBased;
export const canRemoveRedaction = (annotation: AnnotationWrapper, permissions: AnnotationPermissions) => export const canRemoveRedaction = (annotation: AnnotationWrapper, permissions: AnnotationPermissions) =>
(!annotation.isIgnoredHint || !annotation.isRuleBased) && (!annotation.isIgnoredHint || !annotation.isRuleBased) &&

View File

@ -74,7 +74,7 @@ export class AnnotationWrapper implements IListable {
} }
get isDictBased() { get isDictBased() {
return this.engines.includes(LogEntryEngines.DICTIONARY); return [LogEntryEngines.DICTIONARY, LogEntryEngines.DOSSIER_DICTIONARY].some(engine => this.engines.includes(engine));
} }
get isRedactedImageHint() { get isRedactedImageHint() {

View File

@ -37,6 +37,11 @@
{{ 'preferences-screen.form.help-mode-dialog' | translate }} {{ 'preferences-screen.form.help-mode-dialog' | translate }}
</mat-checkbox> </mat-checkbox>
</div> </div>
<div class="iqser-input-group">
<mat-checkbox color="primary" formControlName="overwriteFileOption">
{{ 'preferences-screen.form.overwrite-file-option' | translate }}
</mat-checkbox>
</div>
</ng-container> </ng-container>
</div> </div>
</div> </div>

View File

@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms'; import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { import {
@ -28,6 +28,7 @@ interface PreferencesForm {
// warnings preferences // warnings preferences
loadAllAnnotationsWarning: boolean; loadAllAnnotationsWarning: boolean;
helpModeDialog: boolean; helpModeDialog: boolean;
overwriteFileOption: boolean;
[k: string]: any; [k: string]: any;
} }
@ -58,6 +59,12 @@ const Screens = {
], ],
}) })
export class PreferencesComponent extends BaseFormComponent implements OnInit { export class PreferencesComponent extends BaseFormComponent implements OnInit {
readonly #formBuilder = inject(FormBuilder);
readonly #permissionsService = inject(IqserPermissionsService);
readonly #changeRef = inject(ChangeDetectorRef);
readonly #loadingService = inject(LoadingService);
readonly #userPreferenceService = inject(UserPreferenceService);
readonly form: FormGroup<AsControl<PreferencesForm>>; readonly form: FormGroup<AsControl<PreferencesForm>>;
readonly currentScreen: Screen; readonly currentScreen: Screen;
readonly screens = Screens; readonly screens = Screens;
@ -66,81 +73,92 @@ export class PreferencesComponent extends BaseFormComponent implements OnInit {
readonly config = getConfig(); readonly config = getConfig();
readonly isIqserDevMode = isIqserDevMode(); readonly isIqserDevMode = isIqserDevMode();
constructor( get #isOverwriteFileOptionActive() {
route: ActivatedRoute, return !(this.#userPreferenceService.getOverwriteFileOption() === 'undefined');
readonly userPreferenceService: UserPreferenceService, }
private readonly _formBuilder: FormBuilder,
private readonly _permissionsService: IqserPermissionsService, constructor(route: ActivatedRoute) {
private readonly _changeRef: ChangeDetectorRef,
private readonly _loadingService: LoadingService,
) {
super(); super();
this.form = this._formBuilder.group({ this.form = this.#formBuilder.group({
// preferences // preferences
autoExpandFiltersOnActions: [this.userPreferenceService.getAutoExpandFiltersOnActions()], autoExpandFiltersOnActions: [this.#userPreferenceService.getAutoExpandFiltersOnActions()],
openScmDialogByDefault: [this.userPreferenceService.getOpenScmDialogByDefault()], openScmDialogByDefault: [this.#userPreferenceService.getOpenScmDialogByDefault()],
tableExtractionType: [this.userPreferenceService.getTableExtractionType()], tableExtractionType: [this.#userPreferenceService.getTableExtractionType()],
// warnings preferences // warnings preferences
loadAllAnnotationsWarning: [this.userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning)], loadAllAnnotationsWarning: [this.#userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning)],
helpModeDialog: [this.userPreferenceService.getBool(KEYS.helpModeDialog)], helpModeDialog: [this.#userPreferenceService.getBool(KEYS.helpModeDialog)],
overwriteFileOption: [this.#isOverwriteFileOptionActive],
}); });
if (!this._permissionsService.has(Roles.managePreferences)) { if (!this.#permissionsService.has(Roles.managePreferences)) {
this.form.disable(); this.form.disable();
} }
if (!this._permissionsService.has(Roles.getTables)) { if (!this.#permissionsService.has(Roles.getTables)) {
this.form.controls.tableExtractionType.disable(); this.form.controls.tableExtractionType.disable();
} }
if (!this.#isOverwriteFileOptionActive) {
this.form.controls.overwriteFileOption.disable();
}
this.initialFormValue = this.form.getRawValue(); this.initialFormValue = this.form.getRawValue();
this.currentScreen = route.snapshot.data.screen; this.currentScreen = route.snapshot.data.screen;
} }
ngOnInit() { ngOnInit() {
this._loadingService.stop(); this.#loadingService.stop();
} }
async save(): Promise<any> { async save(): Promise<any> {
if (this.form.controls.autoExpandFiltersOnActions.value !== this.userPreferenceService.getAutoExpandFiltersOnActions()) { if (this.form.controls.autoExpandFiltersOnActions.value !== this.#userPreferenceService.getAutoExpandFiltersOnActions()) {
await this.userPreferenceService.toggleAutoExpandFiltersOnActions(); await this.#userPreferenceService.toggleAutoExpandFiltersOnActions();
} }
if (this.form.controls.openScmDialogByDefault.value !== this.userPreferenceService.getOpenScmDialogByDefault()) { if (this.form.controls.openScmDialogByDefault.value !== this.#userPreferenceService.getOpenScmDialogByDefault()) {
await this.userPreferenceService.toggleOpenScmDialogByDefault(); await this.#userPreferenceService.toggleOpenScmDialogByDefault();
} }
if (this.form.controls.tableExtractionType.value !== this.userPreferenceService.getTableExtractionType()) { if (this.form.controls.tableExtractionType.value !== this.#userPreferenceService.getTableExtractionType()) {
await this.userPreferenceService.save(PreferencesKeys.tableExtractionType, this.form.controls.tableExtractionType.value); await this.#userPreferenceService.save(PreferencesKeys.tableExtractionType, this.form.controls.tableExtractionType.value);
} }
if ( if (
this.form.controls.loadAllAnnotationsWarning.value !== this.form.controls.loadAllAnnotationsWarning.value !==
this.userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning) this.#userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning)
) { ) {
await this.userPreferenceService.save( await this.#userPreferenceService.save(
PreferencesKeys.loadAllAnnotationsWarning, PreferencesKeys.loadAllAnnotationsWarning,
String(this.form.controls.loadAllAnnotationsWarning.value), String(this.form.controls.loadAllAnnotationsWarning.value),
); );
} }
if (this.form.controls.helpModeDialog.value !== this.userPreferenceService.getBool(KEYS.helpModeDialog)) { if (this.form.controls.helpModeDialog.value !== this.#userPreferenceService.getBool(KEYS.helpModeDialog)) {
await this.userPreferenceService.save(KEYS.helpModeDialog, String(this.form.controls.helpModeDialog.value)); await this.#userPreferenceService.save(KEYS.helpModeDialog, String(this.form.controls.helpModeDialog.value));
} }
await this.userPreferenceService.reload(); if (this.form.controls.overwriteFileOption.enabled && !this.form.controls.overwriteFileOption.value) {
await this.#userPreferenceService.saveOverwriteFileOption('undefined');
}
await this.#userPreferenceService.reload();
this.#patchValues(); this.#patchValues();
this.initialFormValue = this.form.getRawValue(); this.initialFormValue = this.form.getRawValue();
this._changeRef.markForCheck(); this.#changeRef.markForCheck();
} }
#patchValues() { #patchValues() {
this.form.patchValue({ this.form.patchValue({
autoExpandFiltersOnActions: this.userPreferenceService.getAutoExpandFiltersOnActions(), autoExpandFiltersOnActions: this.#userPreferenceService.getAutoExpandFiltersOnActions(),
openScmDialogByDefault: this.userPreferenceService.getOpenScmDialogByDefault(), openScmDialogByDefault: this.#userPreferenceService.getOpenScmDialogByDefault(),
tableExtractionType: this.userPreferenceService.getTableExtractionType(), tableExtractionType: this.#userPreferenceService.getTableExtractionType(),
loadAllAnnotationsWarning: this.userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning), loadAllAnnotationsWarning: this.#userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning),
helpModeDialog: this.userPreferenceService.getBool(KEYS.helpModeDialog), helpModeDialog: this.#userPreferenceService.getBool(KEYS.helpModeDialog),
overwriteFileOption: this.#isOverwriteFileOptionActive,
}); });
if (!this.#isOverwriteFileOptionActive) {
this.form.controls.overwriteFileOption.disable();
}
} }
} }

View File

@ -1,6 +1,6 @@
<div <div
[translateParams]="{ [translateParams]="{
type: user ? 'edit' : 'create' type: !!user() ? 'edit' : 'create',
}" }"
[translate]="'add-edit-user.title'" [translate]="'add-edit-user.title'"
class="dialog-header heading-l" class="dialog-header heading-l"
@ -37,9 +37,17 @@
</div> </div>
</div> </div>
@if (!user()) {
<div class="iqser-input-group">
<label [translate]="'add-edit-user.form.account-setup'"></label>
<mat-checkbox formControlName="sendSetPasswordMail">{{ 'add-edit-user.form.send-email' | translate }}</mat-checkbox>
<span [translate]="'add-edit-user.form.send-email-explanation'" class="hint"></span>
</div>
}
<div <div
(click)="toggleResetPassword.emit()" (click)="toggleResetPassword.emit()"
*ngIf="!!user" *ngIf="!!user()"
[translate]="'add-edit-user.form.reset-password'" [translate]="'add-edit-user.form.reset-password'"
class="mt-24 fit-content link-action" class="mt-24 fit-content link-action"
></div> ></div>
@ -48,14 +56,14 @@
<div class="dialog-actions"> <div class="dialog-actions">
<iqser-icon-button <iqser-icon-button
[disabled]="form.invalid || !changed" [disabled]="form.invalid || !changed"
[label]="(user ? 'add-edit-user.actions.save-changes' : 'add-edit-user.actions.save') | translate" [label]="(user() ? 'add-edit-user.actions.save-changes' : 'add-edit-user.actions.save') | translate"
[submit]="true" [submit]="true"
[type]="iconButtonTypes.primary" [type]="iconButtonTypes.primary"
></iqser-icon-button> ></iqser-icon-button>
<iqser-icon-button <iqser-icon-button
(action)="delete()" (action)="delete()"
*ngIf="user && !disabledDelete(user)" *ngIf="user() && !disabledDelete(user())"
[label]="'add-edit-user.actions.delete' | translate" [label]="'add-edit-user.actions.delete' | translate"
[type]="iconButtonTypes.dark" [type]="iconButtonTypes.dark"
icon="iqser:trash" icon="iqser:trash"

View File

@ -5,3 +5,7 @@
margin-top: 8px; margin-top: 8px;
width: 300px; width: 300px;
} }
.hint {
margin-left: 23px;
}

View File

@ -1,4 +1,4 @@
import { Component, EventEmitter, Input, OnChanges, Output } from '@angular/core'; import { Component, input, OnInit, output } from '@angular/core';
import { ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { AdminDialogService } from '../../../services/admin-dialog.service'; import { AdminDialogService } from '../../../services/admin-dialog.service';
import { BaseFormComponent, IconButtonComponent, LoadingService, Toaster } from '@iqser/common-ui'; import { BaseFormComponent, IconButtonComponent, LoadingService, Toaster } from '@iqser/common-ui';
@ -20,15 +20,15 @@ import { NgForOf, NgIf } from '@angular/common';
standalone: true, standalone: true,
imports: [TranslateModule, ReactiveFormsModule, MatCheckbox, NgForOf, IconButtonComponent, NgIf], imports: [TranslateModule, ReactiveFormsModule, MatCheckbox, NgForOf, IconButtonComponent, NgIf],
}) })
export class UserDetailsComponent extends BaseFormComponent implements OnChanges { export class UserDetailsComponent extends BaseFormComponent implements OnInit {
/** e.g. a RED_ADMIN is automatically a RED_USER_ADMIN => can't disable RED_USER_ADMIN as long as RED_ADMIN is checked */ user = input<User>();
private readonly _ROLE_REQUIREMENTS = { RED_MANAGER: 'RED_USER', RED_ADMIN: 'RED_USER_ADMIN' }; readonly toggleResetPassword = output();
@Input() user: User; readonly closeDialog = output<boolean>();
@Output() readonly toggleResetPassword = new EventEmitter(); readonly cancel = output();
@Output() readonly closeDialog = new EventEmitter();
@Output() readonly cancel = new EventEmitter();
readonly ROLES = ['RED_USER', 'RED_MANAGER', 'RED_USER_ADMIN', 'RED_ADMIN']; readonly ROLES = ['RED_USER', 'RED_MANAGER', 'RED_USER_ADMIN', 'RED_ADMIN'];
readonly translations = rolesTranslations; readonly translations = rolesTranslations;
/** e.g. a RED_ADMIN is automatically a RED_USER_ADMIN => can't disable RED_USER_ADMIN as long as RED_ADMIN is checked */
readonly #ROLE_REQUIREMENTS = { RED_MANAGER: 'RED_USER', RED_ADMIN: 'RED_USER_ADMIN' };
constructor( constructor(
private readonly _formBuilder: UntypedFormBuilder, private readonly _formBuilder: UntypedFormBuilder,
@ -49,13 +49,17 @@ export class UserDetailsComponent extends BaseFormComponent implements OnChanges
}, []); }, []);
} }
private get _rolesControls(): any { get sendSetPasswordMail() {
return !this.form.controls.sendSetPasswordMail.value;
}
get #rolesControls() {
return this.ROLES.reduce( return this.ROLES.reduce(
(prev, role) => ({ (prev, role) => ({
...prev, ...prev,
[role]: [ [role]: [
{ {
value: this.user && this.user.has(role), value: this.user() && this.user().has(role),
disabled: this.shouldBeDisabled(role), disabled: this.shouldBeDisabled(role),
}, },
], ],
@ -64,20 +68,20 @@ export class UserDetailsComponent extends BaseFormComponent implements OnChanges
); );
} }
ngOnChanges() { ngOnInit() {
this.form = this._getForm(); this.form = this.#getForm();
this.initialFormValue = this.form.getRawValue(); this.initialFormValue = this.form.getRawValue();
} }
shouldBeDisabled(role: string): boolean { shouldBeDisabled(role: string): boolean {
const isCurrentAdminUser = this.user && this.user.isAdmin && this.user.id === this._userService.currentUser.id; const isCurrentAdminUser = this.user() && this.user().isAdmin && this.user().id === this._userService.currentUser.id;
return ( return (
// RED_ADMIN can't remove own RED_ADMIN role // RED_ADMIN can't remove own RED_ADMIN role
(role === 'RED_ADMIN' && isCurrentAdminUser) || (role === 'RED_ADMIN' && isCurrentAdminUser) ||
// only RED_ADMINs can edit RED_ADMIN roles // only RED_ADMINs can edit RED_ADMIN roles
(role === 'RED_ADMIN' && !this._userService.currentUser.isAdmin) || (role === 'RED_ADMIN' && !this._userService.currentUser.isAdmin) ||
Object.keys(this._ROLE_REQUIREMENTS).reduce( Object.keys(this.#ROLE_REQUIREMENTS).reduce(
(value, key) => value || (role === this._ROLE_REQUIREMENTS[key] && this.user?.roles.includes(key)), (value, key) => value || (role === this.#ROLE_REQUIREMENTS[key] && this.user()?.roles.includes(key)),
false, false,
) )
); );
@ -85,9 +89,13 @@ export class UserDetailsComponent extends BaseFormComponent implements OnChanges
async save() { async save() {
this._loadingService.start(); this._loadingService.start();
const userData: IProfileUpdateRequest = { ...this.form.getRawValue(), roles: this.activeRoles }; const userData: IProfileUpdateRequest = {
...this.form.getRawValue(),
roles: this.activeRoles,
sendSetPasswordMail: this.sendSetPasswordMail,
};
if (!this.user) { if (!this.user()) {
await firstValueFrom(this._userService.create(userData)) await firstValueFrom(this._userService.create(userData))
.then(() => { .then(() => {
this.closeDialog.emit(true); this.closeDialog.emit(true);
@ -101,22 +109,22 @@ export class UserDetailsComponent extends BaseFormComponent implements OnChanges
this._loadingService.stop(); this._loadingService.stop();
}); });
} else { } else {
await firstValueFrom(this._userService.updateProfile(userData, this.user.id)); await firstValueFrom(this._userService.updateProfile(userData, this.user().id));
this.closeDialog.emit(true); this.closeDialog.emit(true);
} }
} }
delete() { delete() {
this._dialogService.deleteUsers([this.user.id], () => this.closeDialog.emit(true)); this._dialogService.deleteUsers([this.user().id], () => this.closeDialog.emit(true));
} }
setRolesRequirements(checked: boolean, role: string): void { setRolesRequirements(checked: boolean, role: string): void {
if (Object.keys(this._ROLE_REQUIREMENTS).includes(role)) { if (Object.keys(this.#ROLE_REQUIREMENTS).includes(role)) {
if (checked) { if (checked) {
this.form.patchValue({ [this._ROLE_REQUIREMENTS[role]]: true }); this.form.patchValue({ [this.#ROLE_REQUIREMENTS[role]]: true });
this.form.controls[this._ROLE_REQUIREMENTS[role]].disable(); this.form.controls[this.#ROLE_REQUIREMENTS[role]].disable();
} else { } else {
this.form.controls[this._ROLE_REQUIREMENTS[role]].enable(); this.form.controls[this.#ROLE_REQUIREMENTS[role]].enable();
} }
} }
} }
@ -127,18 +135,19 @@ export class UserDetailsComponent extends BaseFormComponent implements OnChanges
return user.id === this._userService.currentUser.id || (userAdmin && !currentUserAdmin); return user.id === this._userService.currentUser.id || (userAdmin && !currentUserAdmin);
} }
private _getForm(): UntypedFormGroup { #getForm(): UntypedFormGroup {
return this._formBuilder.group({ return this._formBuilder.group({
firstName: [this.user?.firstName, Validators.required], firstName: [this.user()?.firstName, Validators.required],
lastName: [this.user?.lastName, Validators.required], lastName: [this.user()?.lastName, Validators.required],
email: [ email: [
{ {
value: this.user?.email, value: this.user()?.email,
disabled: !!this.user?.email, disabled: !!this.user()?.email,
}, },
[Validators.required, Validators.email], [Validators.required, Validators.email],
], ],
...this._rolesControls, ...this.#rolesControls,
sendSetPasswordMail: [false],
}); });
} }
} }

View File

@ -1,7 +1,7 @@
<div class="content-container" iqserHasScrollbar> <div class="content-container" iqserHasScrollbar>
<div class="dialog"> <div class="dialog">
<div class="dialog-header"> <div class="dialog-header">
<div [translate]="'entity.info.heading'" [attr.help-mode-key]="'entity_info'" class="heading-l"></div> <div [translate]="'entity.info.heading'" [attr.help-mode-key]="'entity_info'" class="heading-l w-full"></div>
<div *ngIf="!permissionsService.canEditEntities()" class="read-only-indicator all-caps-label primary"> <div *ngIf="!permissionsService.canEditEntities()" class="read-only-indicator all-caps-label primary">
<mat-icon class="mr-8" svgIcon="red:read-only"></mat-icon> <mat-icon class="mr-8" svgIcon="red:read-only"></mat-icon>
@ -26,8 +26,6 @@
></iqser-icon-button> ></iqser-icon-button>
<div (click)="revert()" [translate]="'entity.info.actions.revert'" class="all-caps-label cancel"></div> <div (click)="revert()" [translate]="'entity.info.actions.revert'" class="all-caps-label cancel"></div>
<iqser-help-button *ngIf="!config.IS_DOCUMINE"></iqser-help-button>
</div> </div>
</div> </div>
</div> </div>

View File

@ -26,3 +26,7 @@
min-height: unset; min-height: unset;
} }
} }
.w-full {
width: 100%;
}

View File

@ -27,7 +27,7 @@ import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatIcon } from '@angular/material/icon'; import { MatIcon } from '@angular/material/icon';
import { SelectComponent } from '@shared/components/select/select.component'; import { SelectComponent } from '@shared/components/select/select.component';
const downloadTypes = ['ORIGINAL', 'PREVIEW', 'DELTA_PREVIEW', 'REDACTED'].map(type => ({ const downloadTypes = ['ORIGINAL', 'PREVIEW', 'OPTIMIZED_PREVIEW', 'DELTA_PREVIEW', 'REDACTED'].map(type => ({
key: type, key: type,
label: downloadTypesTranslations[type], label: downloadTypesTranslations[type],
})); }));

View File

@ -3,7 +3,7 @@ import { LicenseService } from '@services/license.service';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { ChartDataset } from 'chart.js'; import { ChartDataset } from 'chart.js';
import { ChartBlue, ChartGreen, ChartRed } from '../../utils/constants'; import { ChartBlue, ChartGreen, ChartRed } from '../../utils/constants';
import { getDataUntilCurrentMonth, getLabelsFromLicense, getLineConfig, isCurrentMonthAndYear } from '../../utils/functions'; import { getDataUntilCurrentMonth, getLabelsFromLicense, getLineConfig, isCurrentMonth } from '../../utils/functions';
import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { size } from '@iqser/common-ui/lib/utils'; import { size } from '@iqser/common-ui/lib/utils';
@ -43,7 +43,7 @@ export class LicenseAnalysisCapacityUsageComponent {
#getCapacityDatasets(): ChartDataset[] { #getCapacityDatasets(): ChartDataset[] {
const monthlyData = [...this.licenseService.selectedLicenseReport.monthlyData]; const monthlyData = [...this.licenseService.selectedLicenseReport.monthlyData];
const dataUntilCurrentMonth = getDataUntilCurrentMonth(monthlyData); const dataUntilCurrentMonth = getDataUntilCurrentMonth(monthlyData);
if (monthlyData.length === 1 || isCurrentMonthAndYear(monthlyData[0].startDate)) { if (monthlyData.length === 1 || isCurrentMonth(monthlyData[0].startDate)) {
const empty = { analysedFilesBytes: null } as ILicenseData; const empty = { analysedFilesBytes: null } as ILicenseData;
dataUntilCurrentMonth.splice(0, 0, empty); dataUntilCurrentMonth.splice(0, 0, empty);
monthlyData.splice(0, 0, empty); monthlyData.splice(0, 0, empty);
@ -60,11 +60,8 @@ export class LicenseAnalysisCapacityUsageComponent {
}, },
{ {
data: dataUntilCurrentMonth.map((month, monthIndex) => data: dataUntilCurrentMonth.map((_, monthIndex) =>
month.analysedFilesBytes monthlyData.slice(0, monthIndex + 1).reduce((acc, curr) => acc + (curr.analysedFilesBytes ?? 0), 0),
? month.analysedFilesBytes +
monthlyData.slice(0, monthIndex).reduce((acc, curr) => acc + (curr.analysedFilesBytes ?? 0), 0)
: 0,
), ),
label: this._translateService.instant('license-info-screen.analysis-capacity-usage.analyzed-cumulative'), label: this._translateService.instant('license-info-screen.analysis-capacity-usage.analyzed-cumulative'),
yAxisID: 'y1', yAxisID: 'y1',

View File

@ -3,7 +3,7 @@ import { LicenseService } from '@services/license.service';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { ChartDataset } from 'chart.js'; import { ChartDataset } from 'chart.js';
import { ChartBlue, ChartGreen, ChartRed } from '../../utils/constants'; import { ChartBlue, ChartGreen, ChartRed } from '../../utils/constants';
import { getDataUntilCurrentMonth, getLabelsFromLicense, getLineConfig, isCurrentMonthAndYear } from '../../utils/functions'; import { getDataUntilCurrentMonth, getLabelsFromLicense, getLineConfig, isCurrentMonth } from '../../utils/functions';
import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { ILicenseData } from '@red/domain'; import { ILicenseData } from '@red/domain';
@ -40,7 +40,7 @@ export class LicensePageUsageComponent {
#getPagesDatasets(): ChartDataset[] { #getPagesDatasets(): ChartDataset[] {
const monthlyData = [...this.licenseService.selectedLicenseReport.monthlyData]; const monthlyData = [...this.licenseService.selectedLicenseReport.monthlyData];
const dataUntilCurrentMonth = getDataUntilCurrentMonth(monthlyData); const dataUntilCurrentMonth = getDataUntilCurrentMonth(monthlyData);
if (monthlyData.length === 1 || isCurrentMonthAndYear(monthlyData[0].startDate)) { if (monthlyData.length === 1 || isCurrentMonth(monthlyData[0].startDate)) {
const empty = { numberOfAnalyzedPages: null } as ILicenseData; const empty = { numberOfAnalyzedPages: null } as ILicenseData;
dataUntilCurrentMonth.splice(0, 0, empty); dataUntilCurrentMonth.splice(0, 0, empty);
monthlyData.splice(0, 0, empty); monthlyData.splice(0, 0, empty);
@ -63,11 +63,8 @@ export class LicensePageUsageComponent {
order: 1, order: 1,
}, },
{ {
data: dataUntilCurrentMonth.map((month, monthIndex) => data: dataUntilCurrentMonth.map((_, monthIndex) =>
month.numberOfAnalyzedPages monthlyData.slice(0, monthIndex + 1).reduce((acc, curr) => acc + (curr.numberOfAnalyzedPages ?? 0), 0),
? month.numberOfAnalyzedPages +
monthlyData.slice(0, monthIndex).reduce((acc, curr) => acc + (curr.numberOfAnalyzedPages ?? 0), 0)
: 0,
), ),
label: this._translateService.instant('license-info-screen.page-usage.cumulative-pages'), label: this._translateService.instant('license-info-screen.page-usage.cumulative-pages'),
yAxisID: 'y1', yAxisID: 'y1',

View File

@ -6,7 +6,6 @@ import { ComplexFillTarget } from 'chart.js/dist/types';
const monthNames = dayjs.monthsShort(); const monthNames = dayjs.monthsShort();
const currentMonth = dayjs(Date.now()).month(); const currentMonth = dayjs(Date.now()).month();
const currentYear = dayjs(Date.now()).year();
export const verboseDate = (date: Dayjs) => `${monthNames[date.month()]} ${date.year()}`; export const verboseDate = (date: Dayjs) => `${monthNames[date.month()]} ${date.year()}`;
@ -45,7 +44,7 @@ export const getLabelsFromLicense = (license: ILicenseReport) => {
monthIterator = monthIterator.add(1, 'month'); monthIterator = monthIterator.add(1, 'month');
} }
if (startMonth.month() === endMonth.month() || startMonth.month() === currentMonth) { if (startMonth.isSame(endMonth, 'month') || isCurrentMonth(startMonth.toDate())) {
result.splice(0, 0, ''); result.splice(0, 0, '');
} }
@ -53,9 +52,9 @@ export const getLabelsFromLicense = (license: ILicenseReport) => {
}; };
export const getDataUntilCurrentMonth = (monthlyData: ILicenseData[]) => { export const getDataUntilCurrentMonth = (monthlyData: ILicenseData[]) => {
return monthlyData.filter(data => dayjs(data.startDate).month() <= currentMonth && dayjs(data.startDate).year() <= currentYear); return monthlyData.filter(data => dayjs(data.startDate).isSameOrBefore(dayjs(Date.now()), 'month'));
}; };
export const isCurrentMonthAndYear = (date: Date | string) => { export const isCurrentMonth = (date: Date | string) => {
return dayjs(date).month() === currentMonth && dayjs(date).year() === currentYear; return dayjs(date).isSame(dayjs(Date.now()), 'month');
}; };

View File

@ -158,6 +158,7 @@ export class AdminSideNavComponent implements OnInit {
{ {
screen: 'info', screen: 'info',
label: _('admin-side-nav.entity-info'), label: _('admin-side-nav.entity-info'),
helpModeKey: 'entity_info',
show: true, show: true,
}, },
{ {

View File

@ -3,7 +3,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
export const digitalSignatureDialogTranslations = { export const digitalSignatureDialogTranslations = {
title: { title: {
beforeConfiguration: _('digital-signature-dialog.title.before-configuration'), beforeConfiguration: _('digital-signature-dialog.title.before-configuration'),
pkcs: _('digital-signature-dialog.title.pkcs'), PKCS: _('digital-signature-dialog.title.pkcs'),
kms: _('digital-signature-dialog.title.kms'), KMS: _('digital-signature-dialog.title.kms'),
}, },
} as const; } as const;

View File

@ -116,7 +116,7 @@ export class ConfigService {
return [ return [
{ {
id: 'editDossier', id: 'editDossier',
label: this._translateService.instant('dossier-overview.header-actions.edit'), label: _('dossier-overview.header-actions.edit'),
action: () => this.#openEditDossierDialog(dossierId), action: () => this.#openEditDossierDialog(dossierId),
icon: 'iqser:edit', icon: 'iqser:edit',
hide: !this.#currentUser.isManager && !this._iqserPermissionsService.has(Roles.dossiers.edit), hide: !this.#currentUser.isManager && !this._iqserPermissionsService.has(Roles.dossiers.edit),

View File

@ -56,7 +56,7 @@
</iqser-workflow> </iqser-workflow>
</div> </div>
<div *ngIf="dossierAttributes$ | async" [class.collapsed]="collapsedDetails" class="right-container" iqserHasScrollbar> <div *ngIf="dossierAttributes$ | async" [class.collapsed]="collapsedDetails" class="right-container">
<redaction-dossier-details <redaction-dossier-details
(toggleCollapse)="collapsedDetails = !collapsedDetails" (toggleCollapse)="collapsedDetails = !collapsedDetails"
[dossierAttributes]="dossierAttributes" [dossierAttributes]="dossierAttributes"

View File

@ -25,10 +25,7 @@
width: 375px; width: 375px;
min-width: 375px; min-width: 375px;
padding: 16px 24px 16px 24px; padding: 16px 24px 16px 24px;
overflow-y: auto;
&.has-scrollbar:hover {
padding-right: 13px;
}
redaction-dossier-details { redaction-dossier-details {
width: 100%; width: 100%;

View File

@ -2,7 +2,7 @@
display: flex; display: flex;
position: absolute; position: absolute;
top: 6px; top: 6px;
right: 19px; right: 8px;
} }
.popover { .popover {

View File

@ -3,21 +3,13 @@
:host { :host {
width: 100%; width: 100%;
position: relative; position: relative;
overflow: hidden; overflow-y: auto;
@include common-mixins.scroll-bar;
&:hover {
overflow-y: auto;
@include common-mixins.scroll-bar;
}
&.has-scrollbar:hover redaction-annotation-wrapper::ng-deep, &.has-scrollbar:hover redaction-annotation-wrapper::ng-deep,
&::ng-deep.documine-wrapper { &::ng-deep.documine-wrapper {
.annotation { .annotation {
padding-right: 5px; padding-right: 5px;
} }
redaction-annotation-details {
right: 8px;
}
} }
} }

View File

@ -46,6 +46,7 @@ import { PageExclusionComponent } from '../page-exclusion/page-exclusion.compone
import { PagesComponent } from '../pages/pages.component'; import { PagesComponent } from '../pages/pages.component';
import { ReadonlyBannerComponent } from '../readonly-banner/readonly-banner.component'; import { ReadonlyBannerComponent } from '../readonly-banner/readonly-banner.component';
import { DocumentInfoComponent } from '../document-info/document-info.component'; import { DocumentInfoComponent } from '../document-info/document-info.component';
import { getLast } from '@utils/functions';
const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape']; const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape'];
const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown']; const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
@ -322,6 +323,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
this.pdf.navigateTo(this.#nextPageWithAnnotations()); this.pdf.navigateTo(this.#nextPageWithAnnotations());
} }
@Debounce(15)
navigateAnnotations($event: KeyboardEvent) { navigateAnnotations($event: KeyboardEvent) {
const currentPage = this.pdf.currentPage(); const currentPage = this.pdf.currentPage();
if (!this._firstSelectedAnnotation || currentPage !== this._firstSelectedAnnotation.pageNumber) { if (!this._firstSelectedAnnotation || currentPage !== this._firstSelectedAnnotation.pageNumber) {
@ -339,7 +341,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
const prevPage = this.#prevPageWithAnnotations(); const prevPage = this.#prevPageWithAnnotations();
const prevPageAnnotations = this.displayedAnnotations.get(prevPage); const prevPageAnnotations = this.displayedAnnotations.get(prevPage);
return this.listingService.selectAnnotations(prevPageAnnotations[prevPageAnnotations.length - 1]); return this.listingService.selectAnnotations(getLast(prevPageAnnotations));
} }
const page = this._firstSelectedAnnotation.pageNumber; const page = this._firstSelectedAnnotation.pageNumber;
@ -376,7 +378,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
for (let i = previousPageIdx; i >= 0; i--) { for (let i = previousPageIdx; i >= 0; i--) {
const prevPageAnnotations = this.displayedAnnotations.get(this.displayedPages[i]); const prevPageAnnotations = this.displayedAnnotations.get(this.displayedPages[i]);
if (prevPageAnnotations) { if (prevPageAnnotations) {
this.listingService.selectAnnotations(prevPageAnnotations[prevPageAnnotations.length - 1]); this.listingService.selectAnnotations(getLast(prevPageAnnotations));
break; break;
} }
} }

View File

@ -1,3 +1,5 @@
@use 'common-mixins';
.components-header { .components-header {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -26,6 +28,7 @@ mat-icon {
font-size: 12px; font-size: 12px;
overflow: scroll; overflow: scroll;
height: calc(100% - 40px); height: calc(100% - 40px);
@include common-mixins.scroll-bar;
.component-row { .component-row {
display: flex; display: flex;
@ -47,6 +50,7 @@ mat-icon {
&:not(:last-child) { &:not(:last-child) {
border-bottom: 1px solid var(--iqser-separator); border-bottom: 1px solid var(--iqser-separator);
} }
border-bottom: 1px solid var(--iqser-separator); border-bottom: 1px solid var(--iqser-separator);
margin-left: 26px; margin-left: 26px;
margin-right: 26px; margin-right: 26px;

View File

@ -27,7 +27,7 @@ export class ViewSwitchComponent {
}); });
protected readonly canSwitchToRedactedView = computed(() => { protected readonly canSwitchToRedactedView = computed(() => {
const file = this._state.file(); const file = this._state.file();
return !file.analysisRequired && !file.excluded && !file.isError; return !file.excluded && !file.isError;
}); });
protected readonly canSwitchToEarmarksView = computed(() => { protected readonly canSwitchToEarmarksView = computed(() => {
const file = this._state.file(); const file = this._state.file();

View File

@ -3,9 +3,56 @@
<div [translate]="'add-hint.dialog.title'" class="dialog-header heading-l"></div> <div [translate]="'add-hint.dialog.title'" class="dialog-header heading-l"></div>
<div class="dialog-content redaction"> <div class="dialog-content redaction">
<div class="iqser-input-group w-450"> <div class="iqser-input-group w-full selected-text-group">
<label class="selected-text" [translate]="'add-hint.dialog.content.selected-text'"></label> <div
{{ form.get('selectedText').value }} [class.fixed-height-36]="dictionaryRequest"
[ngClass]="isEditingSelectedText ? 'flex relative' : 'flex-align-items-center'"
>
<div class="table">
<label>Value</label>
<div class="row">
<span
*ngIf="!isEditingSelectedText"
[innerHTML]="form.controls.selectedText.value"
[ngStyle]="{
'min-width': textWidth > maximumSelectedTextWidth ? '95%' : 'unset',
'max-width': textWidth > maximumSelectedTextWidth ? 0 : 'unset',
}"
></span>
<textarea
*ngIf="isEditingSelectedText"
[rows]="selectedTextRows"
[ngStyle]="{ width: maximumTextAreaWidth + 'px' }"
formControlName="selectedText"
iqserHasScrollbar
name="value"
type="text"
></textarea>
<iqser-circle-button
(action)="toggleEditingSelectedText()"
*ngIf="dictionaryRequest && !isEditingSelectedText"
[tooltip]="'redact-text.dialog.content.edit-text' | translate"
[size]="20"
[iconSize]="13"
icon="iqser:edit"
tooltipPosition="below"
></iqser-circle-button>
<iqser-circle-button
(action)="undoTextChange(); toggleEditingSelectedText()"
*ngIf="isEditingSelectedText"
[showDot]="initialText !== form.get('selectedText').value"
[tooltip]="'redact-text.dialog.content.revert-text' | translate"
[size]="20"
[iconSize]="13"
class="undo-button"
icon="red:undo"
tooltipPosition="below"
></iqser-circle-button>
</div>
</div>
</div>
</div> </div>
<iqser-details-radio <iqser-details-radio

View File

@ -1,3 +1,67 @@
.dialog-content { .dialog-content {
height: 400px; height: 493px;
overflow-y: auto;
}
.selected-text-group > div {
gap: 0.5rem;
span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
iqser-circle-button {
padding-left: 10px;
&.undo-button {
margin-left: 8px;
}
::ng-deep mat-icon {
padding: 2px;
}
}
.w-full {
width: 100%;
}
.fixed-height-36 {
min-height: 36px;
}
textarea[name='value'] {
margin-top: 0;
min-height: 0;
line-height: 1;
}
.table {
display: flex;
flex-direction: column;
min-width: calc(100% - 26px);
padding: 0 13px;
label {
opacity: 0.7;
font-weight: normal;
}
.row {
display: inline-flex;
flex-direction: row;
align-items: center;
background-color: var(--iqser-alt-background);
min-width: 100%;
span {
white-space: nowrap;
text-overflow: ellipsis;
list-style-position: inside;
overflow: hidden;
}
}
} }

View File

@ -1,4 +1,4 @@
import { NgForOf, NgIf } from '@angular/common'; import { NgClass, NgForOf, NgIf, NgStyle } from '@angular/common';
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormBuilder, ReactiveFormsModule, UntypedFormGroup } from '@angular/forms'; import { FormBuilder, ReactiveFormsModule, UntypedFormGroup } from '@angular/forms';
@ -23,12 +23,14 @@ import { ActiveDossiersService } from '@services/dossiers/active-dossiers.servic
import { DictionaryService } from '@services/entity-services/dictionary.service'; import { DictionaryService } from '@services/entity-services/dictionary.service';
import { Roles } from '@users/roles'; import { Roles } from '@users/roles';
import { UserPreferenceService } from '@users/user-preference.service'; import { UserPreferenceService } from '@users/user-preference.service';
import { stringToBoolean } from '@utils/functions'; import { calcTextWidthInPixels, stringToBoolean } from '@utils/functions';
import { tap } from 'rxjs/operators'; import { tap } from 'rxjs/operators';
import { SystemDefaultOption, SystemDefaults } from '../../../account/utils/dialog-defaults'; import { SystemDefaultOption, SystemDefaults } from '../../../account/utils/dialog-defaults';
import { getRedactOrHintOptions } from '../../utils/dialog-options'; import { getRedactOrHintOptions } from '../../utils/dialog-options';
import { AddHintData, AddHintResult, RedactOrHintOption, RedactOrHintOptions } from '../../utils/dialog-types'; import { AddHintData, AddHintResult, RedactOrHintOption, RedactOrHintOptions } from '../../utils/dialog-types';
const MAXIMUM_TEXT_AREA_WIDTH = 421;
@Component({ @Component({
templateUrl: './add-hint-dialog.component.html', templateUrl: './add-hint-dialog.component.html',
styleUrls: ['./add-hint-dialog.component.scss'], styleUrls: ['./add-hint-dialog.component.scss'],
@ -49,6 +51,8 @@ import { AddHintData, AddHintResult, RedactOrHintOption, RedactOrHintOptions } f
CircleButtonComponent, CircleButtonComponent,
MatDialogClose, MatDialogClose,
NgForOf, NgForOf,
NgClass,
NgStyle,
], ],
}) })
export class AddHintDialogComponent extends IqserDialogComponent<AddHintDialogComponent, AddHintData, AddHintResult> implements OnInit { export class AddHintDialogComponent extends IqserDialogComponent<AddHintDialogComponent, AddHintData, AddHintResult> implements OnInit {
@ -58,9 +62,15 @@ export class AddHintDialogComponent extends IqserDialogComponent<AddHintDialogCo
readonly roles = Roles; readonly roles = Roles;
readonly iconButtonTypes = IconButtonTypes; readonly iconButtonTypes = IconButtonTypes;
readonly options: DetailsRadioOption<RedactOrHintOption>[]; readonly options: DetailsRadioOption<RedactOrHintOption>[];
readonly initialText = this.data?.manualRedactionEntryWrapper?.manualRedactionEntry?.value;
readonly maximumTextAreaWidth = MAXIMUM_TEXT_AREA_WIDTH;
readonly maximumSelectedTextWidth = 567;
dictionaryRequest = false; dictionaryRequest = false;
dictionaries: Dictionary[] = []; dictionaries: Dictionary[] = [];
form!: UntypedFormGroup; form!: UntypedFormGroup;
isEditingSelectedText = false;
selectedTextRows = 1;
textWidth: number;
constructor( constructor(
private readonly _activeDossiersService: ActiveDossiersService, private readonly _activeDossiersService: ActiveDossiersService,
@ -83,6 +93,7 @@ export class AddHintDialogComponent extends IqserDialogComponent<AddHintDialogCo
); );
this.form = this.#getForm(); this.form = this.#getForm();
this.textWidth = calcTextWidthInPixels(this.form.controls.selectedText.value);
this.form this.form
.get('option') .get('option')
@ -97,6 +108,18 @@ export class AddHintDialogComponent extends IqserDialogComponent<AddHintDialogCo
.subscribe(); .subscribe();
} }
toggleEditingSelectedText() {
this.isEditingSelectedText = !this.isEditingSelectedText;
if (this.isEditingSelectedText) {
const width = calcTextWidthInPixels(this.form.controls.selectedText.value);
this.selectedTextRows = Math.ceil(width / MAXIMUM_TEXT_AREA_WIDTH);
}
}
undoTextChange() {
this.form.patchValue({ selectedText: this.initialText });
}
get displayedDictionaryLabel() { get displayedDictionaryLabel() {
const dictType = this.form.get('dictionary').value; const dictType = this.form.get('dictionary').value;
if (dictType) { if (dictType) {

View File

@ -30,7 +30,7 @@
<mat-form-field> <mat-form-field>
<mat-select formControlName="dictionary"> <mat-select formControlName="dictionary">
<mat-select-trigger>{{ displayedDictionaryLabel }}</mat-select-trigger> <mat-select-trigger>{{ displayedDictionaryLabel }}</mat-select-trigger>
<mat-option [value]="entity.type"> <mat-option [value]="entity?.type">
<span> {{ redaction.typeLabel }} </span> <span> {{ redaction.typeLabel }} </span>
</mat-option> </mat-option>
</mat-select> </mat-select>

View File

@ -152,6 +152,13 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
this._fileDataService.loadAnnotations(file).then(); this._fileDataService.loadAnnotations(file).then();
}); });
effect(() => {
const file = this.state.file();
if (file.analysisRequired && !file.excludedFromAutomaticAnalysis) {
this._reanalysisService.reanalyzeFilesForDossier([file], file.dossierId, { force: true }).then();
}
});
effect( effect(
() => { () => {
if (this._documentViewer.loaded()) { if (this._documentViewer.loaded()) {
@ -350,10 +357,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
this.userPreferenceService.saveLastOpenedFileForDossier(this.dossierId, this.fileId).then(); this.userPreferenceService.saveLastOpenedFileForDossier(this.dossierId, this.fileId).then();
this.#subscribeToFileUpdates(); this.#subscribeToFileUpdates();
if (file?.analysisRequired && !file.excludedFromAutomaticAnalysis) {
await this._reanalysisService.reanalyzeFilesForDossier([file], this.dossierId, { force: true });
}
this.pdfProxyService.configureElements(); this.pdfProxyService.configureElements();
this.#restoreOldFilters(); this.#restoreOldFilters();
this.pdf.instance.UI.hotkeys.on('esc', this.handleEscInsideViewer); this.pdf.instance.UI.hotkeys.on('esc', this.handleEscInsideViewer);

View File

@ -1,17 +1,16 @@
import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { Injectable, OnDestroy } from '@angular/core'; import { effect, Injectable, untracked } from '@angular/core';
import { EntitiesService, ListingService, SearchService } from '@iqser/common-ui'; import { EntitiesService, ListingService, SearchService } from '@iqser/common-ui';
import { filter, tap } from 'rxjs/operators';
import { MultiSelectService } from './multi-select.service'; import { MultiSelectService } from './multi-select.service';
import { PdfViewer } from '../../pdf-viewer/services/pdf-viewer.service'; import { PdfViewer } from '../../pdf-viewer/services/pdf-viewer.service';
import { REDAnnotationManager } from '../../pdf-viewer/services/annotation-manager.service'; import { REDAnnotationManager } from '../../pdf-viewer/services/annotation-manager.service';
import { Subscription } from 'rxjs';
import { FilterService } from '@iqser/common-ui/lib/filtering'; import { FilterService } from '@iqser/common-ui/lib/filtering';
import { SortingService } from '@iqser/common-ui/lib/sorting'; import { SortingService } from '@iqser/common-ui/lib/sorting';
import { toSignal } from '@angular/core/rxjs-interop';
@Injectable() @Injectable()
export class AnnotationsListingService extends ListingService<AnnotationWrapper> implements OnDestroy { export class AnnotationsListingService extends ListingService<AnnotationWrapper> {
readonly #subscriptions: Subscription; readonly selectedLength = toSignal(this.selectedLength$);
constructor( constructor(
protected readonly _filterService: FilterService, protected readonly _filterService: FilterService,
@ -24,23 +23,22 @@ export class AnnotationsListingService extends ListingService<AnnotationWrapper>
) { ) {
super(_filterService, _searchService, _entitiesService, _sortingService); super(_filterService, _searchService, _entitiesService, _sortingService);
this.#subscriptions = this.selectedLength$ effect(
.pipe( () => {
filter(length => length > 1), if (this.selectedLength() > 1) {
tap(() => this._multiSelectService.activate()), this._multiSelectService.activate();
) }
.subscribe(); },
} { allowSignalWrites: true },
);
ngOnDestroy() {
this.#subscriptions.unsubscribe();
} }
selectAnnotations(annotations: AnnotationWrapper[] | AnnotationWrapper) { selectAnnotations(annotations: AnnotationWrapper[] | AnnotationWrapper) {
annotations = Array.isArray(annotations) ? annotations : [annotations]; annotations = Array.isArray(annotations) ? annotations : [annotations];
const pageNumber = annotations[annotations.length - 1].pageNumber; const pageNumber = annotations[annotations.length - 1].pageNumber;
const annotationsToSelect = this._multiSelectService.active() ? [...this.selected, ...annotations] : annotations; const multiSelectActive = untracked(this._multiSelectService.active);
const annotationsToSelect = multiSelectActive ? [...this.selected, ...annotations] : annotations;
this.#selectAnnotations(annotationsToSelect, pageNumber); this.#selectAnnotations(annotationsToSelect, pageNumber);
} }
@ -49,16 +47,18 @@ export class AnnotationsListingService extends ListingService<AnnotationWrapper>
return; return;
} }
if (this._multiSelectService.inactive()) { const multiSelectInactive = untracked(this._multiSelectService.inactive);
if (multiSelectInactive) {
this._annotationManager.deselect(); this._annotationManager.deselect();
} }
if (pageNumber === this._pdf.currentPage()) { const currentPage = untracked(this._pdf.currentPage);
if (pageNumber === currentPage) {
return this._annotationManager.jumpAndSelect(annotations); return this._annotationManager.jumpAndSelect(annotations);
} }
this._pdf.navigateTo(pageNumber); this._pdf.navigateTo(pageNumber);
// wait for page to be loaded and to draw annotations // wait for page to be loaded and to draw annotations
setTimeout(() => this._annotationManager.jumpAndSelect(annotations), 300); setTimeout(() => this._annotationManager.jumpAndSelect(annotations), 10);
} }
} }

View File

@ -137,7 +137,7 @@ export class FileDataService extends EntitiesService<AnnotationWrapper, Annotati
this.#logger.info('[REDACTION_LOG] Redaction log loaded', redactionLog); this.#logger.info('[REDACTION_LOG] Redaction log loaded', redactionLog);
let annotations = await this.#convertData(redactionLog); let annotations = await this.#convertData(redactionLog);
this.#checkMissingTypes(); if (!this.#annotations().length && annotations.length !== this.missingTypes.size) this.#checkMissingTypes();
annotations = this.#isIqserDevMode ? annotations : annotations.filter(a => !a.isFalsePositive); annotations = this.#isIqserDevMode ? annotations : annotations.filter(a => !a.isFalsePositive);
this.#annotations.set(annotations); this.#annotations.set(annotations);
} }

View File

@ -1,4 +1,4 @@
import { computed, Injectable, Signal, signal } from '@angular/core'; import { computed, Injectable, Signal, signal, untracked } from '@angular/core';
import { ViewModeService } from './view-mode.service'; import { ViewModeService } from './view-mode.service';
import { FilePreviewStateService } from './file-preview-state.service'; import { FilePreviewStateService } from './file-preview-state.service';
import { ViewMode, ViewModes } from '@red/domain'; import { ViewMode, ViewModes } from '@red/domain';
@ -13,13 +13,17 @@ export class MultiSelectService {
readonly #active = signal(false); readonly #active = signal(false);
constructor(protected readonly _viewModeService: ViewModeService, protected readonly _state: FilePreviewStateService) { constructor(
protected readonly _viewModeService: ViewModeService,
protected readonly _state: FilePreviewStateService,
) {
this.active = this.#active.asReadonly(); this.active = this.#active.asReadonly();
this.inactive = computed(() => !this.#active()); this.inactive = computed(() => !this.#active());
} }
activate() { activate() {
if (this.enabled()) { const enabled = untracked(this.enabled);
if (enabled) {
this.#active.set(true); this.#active.set(true);
} }
} }

View File

@ -152,6 +152,7 @@ export const getRemoveRedactionOptions = (
descriptionParams: { descriptionParams: {
value: redactions[0].value, value: redactions[0].value,
type: redactions[0].HINT ? 'hint' : redactions[0].typeLabel, type: redactions[0].HINT ? 'hint' : redactions[0].typeLabel,
isImage: redactions[0].isImage ? 'image' : redactions[0].typeLabel,
}, },
icon: PIN_ICON, icon: PIN_ICON,
value: RemoveRedactionOptions.ONLY_HERE, value: RemoveRedactionOptions.ONLY_HERE,
@ -161,7 +162,11 @@ export const getRemoveRedactionOptions = (
options.push({ options.push({
label: isBulk ? translations.IN_DOSSIER.labelBulk : translations.IN_DOSSIER.label, label: isBulk ? translations.IN_DOSSIER.labelBulk : translations.IN_DOSSIER.label,
description: isBulk ? translations.IN_DOSSIER.descriptionBulk : translations.IN_DOSSIER.description, description: isBulk ? translations.IN_DOSSIER.descriptionBulk : translations.IN_DOSSIER.description,
descriptionParams: { value: redactions[0].value, type: redactions[0].HINT ? 'hint' : redactions[0].typeLabel }, descriptionParams: {
value: redactions[0].value,
type: redactions[0].HINT ? 'hint' : redactions[0].typeLabel,
isImage: redactions[0].isImage ? 'image' : redactions[0].typeLabel,
},
icon: FOLDER_ICON, icon: FOLDER_ICON,
value: RemoveRedactionOptions.IN_DOSSIER, value: RemoveRedactionOptions.IN_DOSSIER,
extraOption: !isDocumine extraOption: !isDocumine
@ -182,6 +187,7 @@ export const getRemoveRedactionOptions = (
value: redactions[0].value, value: redactions[0].value,
type: redactions[0].typeLabel, type: redactions[0].typeLabel,
context: falsePositiveContext[0], context: falsePositiveContext[0],
isImage: redactions[0].isImage ? 'image' : redactions[0].typeLabel,
}, },
icon: FOLDER_ICON, icon: FOLDER_ICON,
value: RemoveRedactionOptions.DO_NOT_RECOMMEND, value: RemoveRedactionOptions.DO_NOT_RECOMMEND,
@ -201,6 +207,7 @@ export const getRemoveRedactionOptions = (
value: redactions[0].value, value: redactions[0].value,
type: redactions[0].typeLabel, type: redactions[0].typeLabel,
context: falsePositiveContext[0], context: falsePositiveContext[0],
isImage: redactions[0].isImage ? 'image' : redactions[0].typeLabel,
}, },
icon: REMOVE_FROM_DICT_ICON, icon: REMOVE_FROM_DICT_ICON,
value: RemoveRedactionOptions.FALSE_POSITIVE, value: RemoveRedactionOptions.FALSE_POSITIVE,

View File

@ -42,12 +42,16 @@ export class EditDossierDownloadPackageComponent
{ {
#existsWatermarks$: Observable<boolean>; #existsWatermarks$: Observable<boolean>;
form: FormGroup; form: FormGroup;
downloadTypes: { key: DownloadFileType; label: string }[] = ['ORIGINAL', 'PREVIEW', 'DELTA_PREVIEW', 'REDACTED'].map( downloadTypes: { key: DownloadFileType; label: string }[] = [
(type: DownloadFileType) => ({ 'ORIGINAL',
key: type, 'PREVIEW',
label: downloadTypesTranslations[type], 'OPTIMIZED_PREVIEW',
}), 'DELTA_PREVIEW',
); 'REDACTED',
].map((type: DownloadFileType) => ({
key: type,
label: downloadTypesTranslations[type],
}));
availableReportTypes: IReportTemplate[] = []; availableReportTypes: IReportTemplate[] = [];
readonly roles = Roles; readonly roles = Roles;
@Input() dossier: Dossier; @Input() dossier: Dossier;

View File

@ -10,6 +10,7 @@ import utc from 'dayjs/plugin/utc';
import localeData from 'dayjs/plugin/localeData'; import localeData from 'dayjs/plugin/localeData';
import localizedFormat from 'dayjs/plugin/localizedFormat'; import localizedFormat from 'dayjs/plugin/localizedFormat';
import customParseFormat from 'dayjs/plugin/customParseFormat'; import customParseFormat from 'dayjs/plugin/customParseFormat';
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
export interface DayJsDateAdapterOptions { export interface DayJsDateAdapterOptions {
/** /**
@ -232,6 +233,7 @@ export class CustomDateAdapter extends DateAdapter<Dayjs> {
dayjs.extend(localizedFormat); dayjs.extend(localizedFormat);
dayjs.extend(customParseFormat); dayjs.extend(customParseFormat);
dayjs.extend(localeData); dayjs.extend(localeData);
dayjs.extend(isSameOrBefore);
this.setLocale(dateLocale); this.setLocale(dateLocale);
} }

View File

@ -1,7 +1,5 @@
<ng-container *ngIf="!filter.icon"> <ng-container *ngIf="!filter.icon">
<div *ngIf="filter.id === 'comment'"> <mat-icon *ngIf="filter.id === 'comment'" svgIcon="red:comment"></mat-icon>
<mat-icon svgIcon="red:comment"></mat-icon>
</div>
<redaction-annotation-icon <redaction-annotation-icon
*ngIf="filter.id !== 'comment'" *ngIf="filter.id !== 'comment'"

View File

@ -12,6 +12,6 @@
height: 16px; height: 16px;
margin-right: 8px; margin-right: 8px;
opacity: 50%; opacity: 50%;
line-height: 16px; line-height: 8px;
} }
} }

View File

@ -71,12 +71,16 @@ export class AddDossierDialogComponent extends BaseDialogComponent implements On
readonly roles = Roles; readonly roles = Roles;
readonly iconButtonTypes = IconButtonTypes; readonly iconButtonTypes = IconButtonTypes;
hasDueDate = false; hasDueDate = false;
readonly downloadTypes: { key: DownloadFileType; label: string }[] = ['ORIGINAL', 'PREVIEW', 'DELTA_PREVIEW', 'REDACTED'].map( readonly downloadTypes: { key: DownloadFileType; label: string }[] = [
(type: DownloadFileType) => ({ 'ORIGINAL',
key: type, 'PREVIEW',
label: downloadTypesTranslations[type], 'OPTIMIZED_PREVIEW',
}), 'DELTA_PREVIEW',
); 'REDACTED',
].map((type: DownloadFileType) => ({
key: type,
label: downloadTypesTranslations[type],
}));
dossierTemplates: IDossierTemplate[]; dossierTemplates: IDossierTemplate[];
availableReportTypes: IReportTemplate[] = []; availableReportTypes: IReportTemplate[] = [];
dossierTemplateId: string; dossierTemplateId: string;

View File

@ -90,7 +90,7 @@ export class DownloadDialogComponent extends IqserDialogComponent<DownloadDialog
} }
get #formDownloadTypes() { get #formDownloadTypes() {
return ['ORIGINAL', 'PREVIEW', 'DELTA_PREVIEW', 'REDACTED'] return ['ORIGINAL', 'PREVIEW', 'OPTIMIZED_PREVIEW', 'DELTA_PREVIEW', 'REDACTED']
.map((type: DownloadFileType) => ({ .map((type: DownloadFileType) => ({
key: type, key: type,
label: downloadTypesForDownloadTranslations[type], label: downloadTypesForDownloadTranslations[type],

View File

@ -15,6 +15,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { HeadersConfiguration } from '@iqser/common-ui/lib/utils'; import { HeadersConfiguration } from '@iqser/common-ui/lib/utils';
import { LicenseService } from '@services/license.service'; import { LicenseService } from '@services/license.service';
import { LicenseFeatures } from '../../admin/screens/license/utils/constants'; import { LicenseFeatures } from '../../admin/screens/license/utils/constants';
import { UserPreferenceService } from '@users/user-preference.service';
export interface ActiveUpload { export interface ActiveUpload {
subscription: Subscription; subscription: Subscription;
@ -43,6 +44,7 @@ export class FileUploadService extends GenericService<IFileUploadResult> impleme
private readonly _errorMessageService: ErrorMessageService, private readonly _errorMessageService: ErrorMessageService,
private readonly _licenseService: LicenseService, private readonly _licenseService: LicenseService,
private readonly _toaster: Toaster, private readonly _toaster: Toaster,
private readonly _userPreferenceService: UserPreferenceService,
) { ) {
super(); super();
const fileFetch$ = this.#fetchFiles$.pipe( const fileFetch$ = this.#fetchFiles$.pipe(
@ -76,7 +78,7 @@ export class FileUploadService extends GenericService<IFileUploadResult> impleme
const maxSizeBytes = maxSizeMB * 1024 * 1024; const maxSizeBytes = maxSizeMB * 1024 * 1024;
const dossierFiles = this._filesMapService.get(dossierId); const dossierFiles = this._filesMapService.get(dossierId);
const supportMsOfficeFormats = this._licenseService.getFeature(LicenseFeatures.SUPPORT_MS_OFFICE_FORMATS)?.value as boolean; const supportMsOfficeFormats = this._licenseService.getFeature(LicenseFeatures.SUPPORT_MS_OFFICE_FORMATS)?.value as boolean;
let option: OverwriteFileOption = localStorage.getItem('overwriteFileOption') as OverwriteFileOption; let option: OverwriteFileOption | 'undefined' = this._userPreferenceService.getOverwriteFileOption();
for (let idx = 0; idx < files.length; ++idx) { for (let idx = 0; idx < files.length; ++idx) {
const file = files[idx]; const file = files[idx];
let currentOption = option; let currentOption = option;
@ -95,14 +97,14 @@ export class FileUploadService extends GenericService<IFileUploadResult> impleme
} }
} }
} else if (dossierFiles.find(pf => pf.filename === file.file.name)) { } else if (dossierFiles.find(pf => pf.filename === file.file.name)) {
if (!option) { if (option === 'undefined') {
const res = await this._dialogService.openOverwriteFileDialog(file.file.name); const res = await this._dialogService.openOverwriteFileDialog(file.file.name);
if (res.cancel) { if (res.cancel) {
return; return;
} }
if (res.rememberChoice) { if (res.rememberChoice) {
localStorage.setItem('overwriteFileOption', res.option); await this._userPreferenceService.saveOverwriteFileOption(res.option);
} }
currentOption = res.option; currentOption = res.option;

View File

@ -409,11 +409,7 @@ export class PermissionsService {
} }
#canReanalyseFile(file: File, dossier: Dossier): boolean { #canReanalyseFile(file: File, dossier: Dossier): boolean {
return ( return dossier.isActive && ((this.isAssigneeOrApprover(file, dossier) && file.analysisRequired) || file.isError);
dossier.isActive &&
((this.isAssigneeOrApprover(file, dossier) && file.analysisRequired) ||
(file.isError && (this.isOwner(dossier) || this.isFileAssignee(file))))
);
} }
#canEnableAutoAnalysis(file: File, dossier: Dossier): boolean { #canEnableAutoAnalysis(file: File, dossier: Dossier): boolean {

View File

@ -4,6 +4,7 @@ import { DownloadFileType } from '@red/domain';
export const downloadTypesTranslations: { [key in DownloadFileType]: string } = { export const downloadTypesTranslations: { [key in DownloadFileType]: string } = {
ORIGINAL: _('download-type.original'), ORIGINAL: _('download-type.original'),
PREVIEW: _('download-type.preview'), PREVIEW: _('download-type.preview'),
OPTIMIZED_PREVIEW: _('download-type.optimized-preview'),
REDACTED: _('download-type.redacted'), REDACTED: _('download-type.redacted'),
ANNOTATED: _('download-type.annotated'), ANNOTATED: _('download-type.annotated'),
FLATTEN: _('download-type.flatten'), FLATTEN: _('download-type.flatten'),
@ -13,6 +14,7 @@ export const downloadTypesTranslations: { [key in DownloadFileType]: string } =
export const downloadTypesForDownloadTranslations: { [key in DownloadFileType]: string } = { export const downloadTypesForDownloadTranslations: { [key in DownloadFileType]: string } = {
ORIGINAL: _('download-type.original'), ORIGINAL: _('download-type.original'),
PREVIEW: _('download-type.preview'), PREVIEW: _('download-type.preview'),
OPTIMIZED_PREVIEW: _('download-type.optimized-preview'),
REDACTED: _('download-type.redacted-only'), REDACTED: _('download-type.redacted-only'),
ANNOTATED: _('download-type.annotated'), ANNOTATED: _('download-type.annotated'),
FLATTEN: _('download-type.flatten'), FLATTEN: _('download-type.flatten'),

View File

@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
import { IqserUserPreferenceService, ListingMode } from '@iqser/common-ui'; import { IqserUserPreferenceService, ListingMode } from '@iqser/common-ui';
import { SystemDefaultOption, SystemDefaultType } from '../modules/account/utils/dialog-defaults'; import { SystemDefaultOption, SystemDefaultType } from '../modules/account/utils/dialog-defaults';
import { RedactOrHintOption, RemoveRedactionOption } from '../modules/file-preview/utils/dialog-types'; import { RedactOrHintOption, RemoveRedactionOption } from '../modules/file-preview/utils/dialog-types';
import { OverwriteFileOption } from '@red/domain';
export const PreferencesKeys = { export const PreferencesKeys = {
dossierRecent: 'Dossier-Recent', dossierRecent: 'Dossier-Recent',
@ -22,6 +23,7 @@ export const PreferencesKeys = {
removeRedactionDefaultExtraOption: 'Remove-Redaction-Default-Extra', removeRedactionDefaultExtraOption: 'Remove-Redaction-Default-Extra',
removeRecommendationDefaultExtraOption: 'Remove-Recommendation-Default-Extra', removeRecommendationDefaultExtraOption: 'Remove-Recommendation-Default-Extra',
removeHintDefaultExtraOption: 'Remove-Hint-Default-Extra', removeHintDefaultExtraOption: 'Remove-Hint-Default-Extra',
rememberOverwriteFileOption: 'Remember-Overwrite-File',
} as const; } as const;
@Injectable({ @Injectable({
@ -179,4 +181,12 @@ export class UserPreferenceService extends IqserUserPreferenceService {
async saveRemoveRecommendationDefaultExtraOption(defaultOption: boolean | string): Promise<void> { async saveRemoveRecommendationDefaultExtraOption(defaultOption: boolean | string): Promise<void> {
await this.save(PreferencesKeys.removeRecommendationDefaultExtraOption, defaultOption.toString()); await this.save(PreferencesKeys.removeRecommendationDefaultExtraOption, defaultOption.toString());
} }
getOverwriteFileOption(): OverwriteFileOption | 'undefined' {
return this._getAttribute(PreferencesKeys.rememberOverwriteFileOption, 'undefined') as OverwriteFileOption | 'undefined';
}
async saveOverwriteFileOption(preference: OverwriteFileOption | 'undefined') {
await this.save(PreferencesKeys.rememberOverwriteFileOption, preference);
}
} }

View File

@ -206,11 +206,14 @@
"generic": "Speichern des Benutzers fehlgeschlagen." "generic": "Speichern des Benutzers fehlgeschlagen."
}, },
"form": { "form": {
"account-setup": "User account setup",
"email": "E-Mail", "email": "E-Mail",
"first-name": "Vorname", "first-name": "Vorname",
"last-name": "Nachname", "last-name": "Nachname",
"reset-password": "Passwort zurücksetzen", "reset-password": "Passwort zurücksetzen",
"role": "Rolle" "role": "Rolle",
"send-email": "Do not send email requesting the user to set a password",
"send-email-explanation": "Select this option if you use SSO. Please note that you will need to inform the user directly."
}, },
"title": "{type, select, edit{Benutzer bearbeiten} create{Neuen Benutzer erstellen} other{}}" "title": "{type, select, edit{Benutzer bearbeiten} create{Neuen Benutzer erstellen} other{}}"
}, },
@ -271,9 +274,6 @@
"watermarks": "Wasserzeichen" "watermarks": "Wasserzeichen"
}, },
"analysis-disabled": "", "analysis-disabled": "",
"annotation": {
"pending": "(Analyse steht aus)"
},
"annotation-actions": { "annotation-actions": {
"accept-recommendation": { "accept-recommendation": {
"label": "Empfehlung annehmen" "label": "Empfehlung annehmen"
@ -329,14 +329,14 @@
"error": "Rekategorisierung des Bilds fehlgeschlagen: {error}", "error": "Rekategorisierung des Bilds fehlgeschlagen: {error}",
"success": "Bild wurde einer neuen Kategorie zugeordnet." "success": "Bild wurde einer neuen Kategorie zugeordnet."
}, },
"remove": {
"error": "Entfernen der Schwärzung fehlgeschlagen: {error}",
"success": "Schwärzung wurde entfernt"
},
"remove-hint": { "remove-hint": {
"error": "Entfernen des Hinweises fehlgeschlagen: {error}", "error": "Entfernen des Hinweises fehlgeschlagen: {error}",
"success": "Hinweis wurde entfernt" "success": "Hinweis wurde entfernt"
}, },
"remove": {
"error": "Entfernen der Schwärzung fehlgeschlagen: {error}",
"success": "Schwärzung wurde entfernt"
},
"undo": { "undo": {
"error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}",
"success": "Rücksetzung erfolgreich" "success": "Rücksetzung erfolgreich"
@ -349,15 +349,15 @@
"remove-highlights": { "remove-highlights": {
"label": "Ausgewählte Markierungen entfernen" "label": "Ausgewählte Markierungen entfernen"
}, },
"resize": {
"label": "Größe ändern"
},
"resize-accept": { "resize-accept": {
"label": "Neue Größe speichern" "label": "Neue Größe speichern"
}, },
"resize-cancel": { "resize-cancel": {
"label": "Größenänderung abbrechen" "label": "Größenänderung abbrechen"
}, },
"resize": {
"label": "Größe ändern"
},
"see-references": { "see-references": {
"label": "Referenzen anzeigen" "label": "Referenzen anzeigen"
}, },
@ -391,6 +391,9 @@
"skipped": "Ignorierte Schwärzung", "skipped": "Ignorierte Schwärzung",
"text-highlight": "Markierung" "text-highlight": "Markierung"
}, },
"annotation": {
"pending": "(Analyse steht aus)"
},
"annotations": "Annotationen", "annotations": "Annotationen",
"archived-dossiers-listing": { "archived-dossiers-listing": {
"no-data": { "no-data": {
@ -613,18 +616,14 @@
"warning": "Warnung: Wiederherstellung des Benutzers nicht möglich." "warning": "Warnung: Wiederherstellung des Benutzers nicht möglich."
}, },
"confirmation-dialog": { "confirmation-dialog": {
"approve-file": {
"question": "Dieses Dokument enthält ungesehene Änderungen, die sich durch die Reanalyse ergeben haben. <br><br>Möchten Sie es trotzdem freigeben?",
"title": "Warnung!"
},
"approve-file-without-analysis": { "approve-file-without-analysis": {
"confirmationText": "Ohne Analyse freigeben", "confirmationText": "Ohne Analyse freigeben",
"denyText": "Abbrechen", "denyText": "Abbrechen",
"question": "Analyse zur Erkennung neuer Schwärzungen erforderlich.", "question": "Analyse zur Erkennung neuer Schwärzungen erforderlich.",
"title": "Warnung!" "title": "Warnung!"
}, },
"approve-multiple-files": { "approve-file": {
"question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen, die im Zuge einer Reanalyse hinzugefügt wurden.<br><br>Möchen Sie die Dateien wirklich freigeben?", "question": "Dieses Dokument enthält ungesehene Änderungen, die sich durch die Reanalyse ergeben haben. <br><br>Möchten Sie es trotzdem freigeben?",
"title": "Warnung!" "title": "Warnung!"
}, },
"approve-multiple-files-without-analysis": { "approve-multiple-files-without-analysis": {
@ -633,6 +632,10 @@
"question": "Für mindestens eine Datei ist ein Analyselauf zur Erkennung neuer Schwärzungen erforderlich.", "question": "Für mindestens eine Datei ist ein Analyselauf zur Erkennung neuer Schwärzungen erforderlich.",
"title": "Warnung" "title": "Warnung"
}, },
"approve-multiple-files": {
"question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen, die im Zuge einer Reanalyse hinzugefügt wurden.<br><br>Möchen Sie die Dateien wirklich freigeben?",
"title": "Warnung!"
},
"assign-file-to-me": { "assign-file-to-me": {
"question": { "question": {
"multiple": "Dieses Dokument wird gerade von einer anderen Person geprüft.<br><br>Möchten Sie sich die Datei dennoch zuweisen?", "multiple": "Dieses Dokument wird gerade von einer anderen Person geprüft.<br><br>Möchten Sie sich die Datei dennoch zuweisen?",
@ -1002,13 +1005,13 @@
"recent": "Neu ({hours} h)", "recent": "Neu ({hours} h)",
"unassigned": "Keinem Bearbeiter zugewiesen" "unassigned": "Keinem Bearbeiter zugewiesen"
}, },
"reanalyse": {
"action": "Datei analysieren"
},
"reanalyse-dossier": { "reanalyse-dossier": {
"error": "Einplanung der Dateien für die Reanalyse fehlgeschlagen. Bitte versuchen Sie es noch einmal.", "error": "Einplanung der Dateien für die Reanalyse fehlgeschlagen. Bitte versuchen Sie es noch einmal.",
"success": "Dateien für Reanalyse vorgesehen." "success": "Dateien für Reanalyse vorgesehen."
}, },
"reanalyse": {
"action": "Datei analysieren"
},
"start-auto-analysis": "Auto-Analyse aktivieren", "start-auto-analysis": "Auto-Analyse aktivieren",
"stop-auto-analysis": "Auto-Analyse anhalten", "stop-auto-analysis": "Auto-Analyse anhalten",
"table-col-names": { "table-col-names": {
@ -1078,19 +1081,10 @@
"total-documents": "Dokumente", "total-documents": "Dokumente",
"total-people": "<strong>{count}</strong> {count, plural, one{Benutzer} other {Benutzer}}" "total-people": "<strong>{count}</strong> {count, plural, one{Benutzer} other {Benutzer}}"
}, },
"dossier-templates": {
"label": "Dossier-Vorlagen",
"status": {
"active": "Aktiv",
"inactive": "Inaktiv",
"incomplete": "Unvollständig"
}
},
"dossier-templates-listing": { "dossier-templates-listing": {
"action": { "action": {
"clone": "Vorlage klonen", "clone": "Vorlage klonen",
"delete": "Vorlage löschen", "delete": "Vorlage löschen"
"edit": "Vorlage bearbeiten"
}, },
"add-new": "Neue Dossier-Vorlage", "add-new": "Neue Dossier-Vorlage",
"bulk": { "bulk": {
@ -1121,6 +1115,14 @@
"title": "{length} {length, plural, one{Dossier-Vorlage} other{Dossier-Vorlagen}}" "title": "{length} {length, plural, one{Dossier-Vorlage} other{Dossier-Vorlagen}}"
} }
}, },
"dossier-templates": {
"label": "Dossier-Vorlagen",
"status": {
"active": "Aktiv",
"inactive": "Inaktiv",
"incomplete": "Unvollständig"
}
},
"dossier-watermark-selector": { "dossier-watermark-selector": {
"heading": "Wasserzeichen auf Dokumenten", "heading": "Wasserzeichen auf Dokumenten",
"no-watermark": "Kein Wasserzeichen in der Dossier-Vorlage verfügbar:<br>Bitten Sie Ihren Admin, eines zu konfigurieren.", "no-watermark": "Kein Wasserzeichen in der Dossier-Vorlage verfügbar:<br>Bitten Sie Ihren Admin, eines zu konfigurieren.",
@ -1152,6 +1154,7 @@
"delta-preview": "Delta-PDF", "delta-preview": "Delta-PDF",
"flatten": "Verflachte PDF", "flatten": "Verflachte PDF",
"label": "{length} Dokumenten{length, plural, one{typ} other{typen}}", "label": "{length} Dokumenten{length, plural, one{typ} other{typen}}",
"optimized-preview": "Optimized Preview PDF",
"original": "Optimierte PDF", "original": "Optimierte PDF",
"preview": "Vorschau-PDF", "preview": "Vorschau-PDF",
"redacted": "Geschwärzte PDF", "redacted": "Geschwärzte PDF",
@ -1316,15 +1319,6 @@
"title": "{length} {length, plural, one{Wörterbuch} other{Wörterbücher}}" "title": "{length} {length, plural, one{Wörterbuch} other{Wörterbücher}}"
} }
}, },
"entity": {
"info": {
"actions": {
"revert": "Zurücksetzen",
"save": "Änderungen speichern"
},
"heading": "Entität bearbeiten"
}
},
"entity-rules-screen": { "entity-rules-screen": {
"error": { "error": {
"generic": "Fehler: Aktualisierung der Entitätsregeln fehlgeschlagen." "generic": "Fehler: Aktualisierung der Entitätsregeln fehlgeschlagen."
@ -1339,19 +1333,28 @@
"warning-text": "Warnung: experimentelle Funktion!", "warning-text": "Warnung: experimentelle Funktion!",
"warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} in Regeln gefunden" "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} in Regeln gefunden"
}, },
"entity": {
"info": {
"actions": {
"revert": "Zurücksetzen",
"save": "Änderungen speichern"
},
"heading": "Entität bearbeiten"
}
},
"error": { "error": {
"deleted-entity": { "deleted-entity": {
"dossier": { "dossier": {
"action": "Zurück zur Übersicht", "action": "Zurück zur Übersicht",
"label": "Dieses Dossier wurde gelöscht!" "label": "Dieses Dossier wurde gelöscht!"
}, },
"file": {
"action": "Zurück zum Dossier",
"label": "Diese Datei wurde gelöscht!"
},
"file-dossier": { "file-dossier": {
"action": "Zurück zur Übersicht", "action": "Zurück zur Übersicht",
"label": "Das Dossier dieser Datei wurde gelöscht!" "label": "Das Dossier dieser Datei wurde gelöscht!"
},
"file": {
"action": "Zurück zum Dossier",
"label": "Diese Datei wurde gelöscht!"
} }
}, },
"file-preview": { "file-preview": {
@ -1369,12 +1372,6 @@
}, },
"exact-date": "{day}. {month} {year} um {hour}:{minute} Uhr", "exact-date": "{day}. {month} {year} um {hour}:{minute} Uhr",
"file": "Datei", "file": "Datei",
"file-attribute": {
"update": {
"error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.",
"success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert."
}
},
"file-attribute-encoding-types": { "file-attribute-encoding-types": {
"ascii": "ASCII", "ascii": "ASCII",
"iso": "ISO-8859-1", "iso": "ISO-8859-1",
@ -1385,6 +1382,12 @@
"number": "Nummer", "number": "Nummer",
"text": "Freier Text" "text": "Freier Text"
}, },
"file-attribute": {
"update": {
"error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.",
"success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert."
}
},
"file-attributes-configurations": { "file-attributes-configurations": {
"cancel": "Abbrechen", "cancel": "Abbrechen",
"form": { "form": {
@ -1602,15 +1605,6 @@
"csv": "Die Datei-Attribute wurden erfolgreich aus der hochgeladenen CSV-Datei importiert." "csv": "Die Datei-Attribute wurden erfolgreich aus der hochgeladenen CSV-Datei importiert."
} }
}, },
"filter": {
"analysis": "Analyse erforderlich",
"comment": "Kommentare",
"hint": "Nur Hinweise",
"image": "Bilder",
"none": "Keine Annotationen",
"redaction": "Schwärzungen",
"updated": "Aktualisiert"
},
"filter-menu": { "filter-menu": {
"filter-options": "Filteroptionen", "filter-options": "Filteroptionen",
"filter-types": "Filter", "filter-types": "Filter",
@ -1620,6 +1614,15 @@
"unseen-pages": "Nur Annotationen auf ungesehenen Seiten", "unseen-pages": "Nur Annotationen auf ungesehenen Seiten",
"with-comments": "Nur Annotationen mit Kommentaren" "with-comments": "Nur Annotationen mit Kommentaren"
}, },
"filter": {
"analysis": "Analyse erforderlich",
"comment": "Kommentare",
"hint": "Nur Hinweise",
"image": "Bilder",
"none": "Keine Annotationen",
"redaction": "Schwärzungen",
"updated": "Aktualisiert"
},
"filters": { "filters": {
"assigned-people": "Bearbeiter", "assigned-people": "Bearbeiter",
"documents-status": "Dokumentenstatus", "documents-status": "Dokumentenstatus",
@ -1898,13 +1901,6 @@
"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",
@ -1918,6 +1914,7 @@
"dossier": "Benachrichtigungen zu Dossiers", "dossier": "Benachrichtigungen zu Dossiers",
"other": "Andere Benachrichtigungen" "other": "Andere Benachrichtigungen"
}, },
"options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten",
"options": { "options": {
"ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen werde", "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen werde",
"ASSIGN_REVIEWER": "Wenn ich einem Dokument als Prüfer zugewiesen werde", "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Prüfer zugewiesen werde",
@ -1935,7 +1932,6 @@
"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": "Sofort", "instant": "Sofort",
@ -1943,6 +1939,13 @@
}, },
"title": "Benachrichtigungseinstellungen" "title": "Benachrichtigungseinstellungen"
}, },
"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"
},
"ocr": { "ocr": {
"confirmation-dialog": { "confirmation-dialog": {
"cancel": "Abbrechen", "cancel": "Abbrechen",
@ -2026,6 +2029,7 @@
"help-mode-dialog": "Dialog zur Aktivierung des Hilfemodus", "help-mode-dialog": "Dialog zur Aktivierung des Hilfemodus",
"load-all-annotations-warning": "Warnung bei gleichzeitigem Laden aller Annotationen in der Miniaturansicht", "load-all-annotations-warning": "Warnung bei gleichzeitigem Laden aller Annotationen in der Miniaturansicht",
"open-structured-view-by-default": "Strukturierte Komponentenansicht standardmäßig anzeigen", "open-structured-view-by-default": "Strukturierte Komponentenansicht standardmäßig anzeigen",
"overwrite-file-option": "",
"table-extraction-type": "Art der Tabellenextraktion" "table-extraction-type": "Art der Tabellenextraktion"
}, },
"label": "Präferenzen", "label": "Präferenzen",
@ -2034,16 +2038,16 @@
"warnings-label": "Dialoge und Meldungen", "warnings-label": "Dialoge und Meldungen",
"warnings-subtitle": "„Nicht mehr anzeigen“-Optionen" "warnings-subtitle": "„Nicht mehr anzeigen“-Optionen"
}, },
"processing": {
"basic": "Verarbeitung läuft",
"ocr": "OCR"
},
"processing-status": { "processing-status": {
"ocr": "OCR", "ocr": "OCR",
"pending": "Ausstehend", "pending": "Ausstehend",
"processed": "verarbeitet", "processed": "verarbeitet",
"processing": "Verarbeitung läuft" "processing": "Verarbeitung läuft"
}, },
"processing": {
"basic": "Verarbeitung läuft",
"ocr": "OCR"
},
"readonly": "Lesemodus", "readonly": "Lesemodus",
"readonly-archived": "Lesemodus (archiviert)", "readonly-archived": "Lesemodus (archiviert)",
"redact-text": { "redact-text": {
@ -2279,12 +2283,6 @@
"red-user-admin": "Benutzeradmin", "red-user-admin": "Benutzeradmin",
"regular": "regulärer Benutzer" "regular": "regulärer Benutzer"
}, },
"search": {
"active-dossiers": "Dokumente in aktiven Dossiers",
"all-dossiers": "Alle Dokumente",
"placeholder": "Dokumente durchsuchen...",
"this-dossier": "In diesem Dossier"
},
"search-screen": { "search-screen": {
"cols": { "cols": {
"assignee": "Bearbeiter", "assignee": "Bearbeiter",
@ -2308,6 +2306,12 @@
"no-match": "Suchbegriff wurde in keinem der Dokumente gefunden.", "no-match": "Suchbegriff wurde in keinem der Dokumente gefunden.",
"table-header": "{length} {length, plural, one{Suchergebnis} other{Suchergebnisse}}" "table-header": "{length} {length, plural, one{Suchergebnis} other{Suchergebnisse}}"
}, },
"search": {
"active-dossiers": "Dokumente in aktiven Dossiers",
"all-dossiers": "Alle Dokumente",
"placeholder": "Dokumente durchsuchen...",
"this-dossier": "In diesem Dossier"
},
"seconds": "Sekunden", "seconds": "Sekunden",
"size": "Größe", "size": "Größe",
"smtp-auth-config": { "smtp-auth-config": {

View File

@ -206,11 +206,14 @@
"generic": "Failed to save user." "generic": "Failed to save user."
}, },
"form": { "form": {
"account-setup": "User account setup",
"email": "E-mail", "email": "E-mail",
"first-name": "First name", "first-name": "First name",
"last-name": "Last name", "last-name": "Last name",
"reset-password": "Reset password", "reset-password": "Reset password",
"role": "Role" "role": "Role",
"send-email": "Do not send email requesting the user to set a password",
"send-email-explanation": "Select this option if you use SSO. Please note that you will need to inform the user directly."
}, },
"title": "{type, select, edit{Edit} create{Add new} other{}} user" "title": "{type, select, edit{Edit} create{Add new} other{}} user"
}, },
@ -1081,8 +1084,7 @@
"dossier-templates-listing": { "dossier-templates-listing": {
"action": { "action": {
"clone": "Clone template", "clone": "Clone template",
"delete": "Delete template", "delete": "Delete template"
"edit": "Edit template"
}, },
"add-new": "New dossier template", "add-new": "New dossier template",
"bulk": { "bulk": {
@ -1152,6 +1154,7 @@
"delta-preview": "Delta PDF", "delta-preview": "Delta PDF",
"flatten": "Flatten PDF", "flatten": "Flatten PDF",
"label": "{length} document {length, plural, one{version} other{versions}}", "label": "{length} document {length, plural, one{version} other{versions}}",
"optimized-preview": "Optimized Preview PDF",
"original": "Optimized PDF", "original": "Optimized PDF",
"preview": "Preview PDF", "preview": "Preview PDF",
"redacted": "Redacted PDF", "redacted": "Redacted PDF",
@ -1518,7 +1521,7 @@
}, },
"reanalyse-notification": "Start reanalysis", "reanalyse-notification": "Start reanalysis",
"redacted": "Preview", "redacted": "Preview",
"redacted-tooltip": "Redaction preview shows only redactions. Consider this a preview for the final redacted version. This view is only available if the file has no pending changes & doesn't require a reanalysis", "redacted-tooltip": "The preview shows only the redactions. It is a preview of the final redacted version.",
"standard": "Standard", "standard": "Standard",
"standard-tooltip": "Standard shows all annotation types and allows for editing.", "standard-tooltip": "Standard shows all annotation types and allows for editing.",
"tabs": { "tabs": {
@ -2026,6 +2029,7 @@
"help-mode-dialog": "Help mode activation dialog", "help-mode-dialog": "Help mode activation dialog",
"load-all-annotations-warning": "Warning regarding simultaneous loading of all annotations in thumbnails", "load-all-annotations-warning": "Warning regarding simultaneous loading of all annotations in thumbnails",
"open-structured-view-by-default": "Display structured component management modal by default", "open-structured-view-by-default": "Display structured component management modal by default",
"overwrite-file-option": "Preferred action when re-uploading of an already existing file",
"table-extraction-type": "Table extraction type" "table-extraction-type": "Table extraction type"
}, },
"label": "Preferences", "label": "Preferences",
@ -2125,28 +2129,28 @@
"comment-placeholder": "Add remarks or notes...", "comment-placeholder": "Add remarks or notes...",
"options": { "options": {
"do-not-recommend": { "do-not-recommend": {
"description": "Do not recommend the selected term in any document of this dossier.", "description": "Do not recommend the selected {isImage, select, image{image} other{term}} in any document of this dossier.",
"description-bulk": "Do not recommend the selected terms in any document of this dossier.", "description-bulk": "Do not recommend the selected {isImage, select, image{images} other{terms}} in any document of this dossier.",
"extraOptionLabel": "Apply to all active and future dossiers", "extraOptionLabel": "Apply to all active and future dossiers",
"label": "Remove from dossier" "label": "Remove from dossier"
}, },
"false-positive": { "false-positive": {
"description": "Mark this redaction as a false-positive. The term will not be redacted in this dossier if it occurs in the same context.", "description": "Mark this redaction as a false-positive. The {isImage, select, image{image} other{term}} will not be redacted in this dossier if it occurs in the same context.",
"description-bulk": "Mark these redactions as false-positives. The terms will not be redacted in this dossier if they occur in the same context.", "description-bulk": "Mark these redactions as false-positives. The {isImage, select, image{images} other{terms}} will not be redacted in this dossier if they occur in the same context.",
"extraOptionDescription": "Dossier template access is required to reverse this action. As a regular user you can only reverse it for this dossier.", "extraOptionDescription": "Dossier template access is required to reverse this action. As a regular user you can only reverse it for this dossier.",
"extraOptionLabel": "Apply to all active and future dossiers", "extraOptionLabel": "Apply to all active and future dossiers",
"label": "Remove from dossier in this context" "label": "Remove from dossier in this context"
}, },
"in-dossier": { "in-dossier": {
"description": "Do not {type, select, hint{annotate} other{auto-redact}} the selected term in any document of this dossier.", "description": "Do not {type, select, hint{annotate} other{auto-redact}} the selected {isImage, select, image{image} other{term}} in any document of this dossier.",
"description-bulk": "Do not {type, select, hint{annotate} other{auto-redact}} the selected terms in this dossier.", "description-bulk": "Do not {type, select, hint{annotate} other{auto-redact}} the selected {isImage, select, image{images} other{terms}} in this dossier.",
"extraOptionLabel": "Apply to all active and future dossiers", "extraOptionLabel": "Apply to all active and future dossiers",
"label": "Remove from dossier", "label": "Remove from dossier",
"label-bulk": "Remove from dossier" "label-bulk": "Remove from dossier"
}, },
"only-here": { "only-here": {
"description": "Do not {type, select, hint{annotate} other{redact}} the term at this position in the current document.", "description": "Do not {type, select, hint{annotate} other{redact}} the {isImage, select, image{image} other{term}} at this position in the current document.",
"description-bulk": "Do not {type, select, hint{annotate} other{redact}} the selected terms at this position in the current document.", "description-bulk": "Do not {type, select, hint{annotate} other{redact}} the selected {isImage, select, image{images} other{terms}} at this position in the current document.",
"label": "Remove here" "label": "Remove here"
} }
} }

View File

@ -206,11 +206,14 @@
"generic": "Benutzer konnte nicht gespeichert werden!" "generic": "Benutzer konnte nicht gespeichert werden!"
}, },
"form": { "form": {
"account-setup": "User account setup",
"email": "E-Mail", "email": "E-Mail",
"first-name": "Vorname", "first-name": "Vorname",
"last-name": "Nachname", "last-name": "Nachname",
"reset-password": "Passwort zurücksetzen", "reset-password": "Passwort zurücksetzen",
"role": "Rolle" "role": "Rolle",
"send-email": "Do not send email requesting the user to set a password",
"send-email-explanation": "Select this option if you use SSO. Please note that you will need to inform the user directly."
}, },
"title": "{type, select, edit{Benutzer bearbeiten} create{Neuen Benutzer hinzufügen} other{}}" "title": "{type, select, edit{Benutzer bearbeiten} create{Neuen Benutzer hinzufügen} other{}}"
}, },
@ -271,9 +274,6 @@
"watermarks": "Watermarks" "watermarks": "Watermarks"
}, },
"analysis-disabled": "Analysis disabled", "analysis-disabled": "Analysis disabled",
"annotation": {
"pending": "(Pending analysis)"
},
"annotation-actions": { "annotation-actions": {
"accept-recommendation": { "accept-recommendation": {
"label": "Empfehlung annehmen" "label": "Empfehlung annehmen"
@ -329,14 +329,14 @@
"error": "Rekategorisierung des Bildes gescheitert: {error}", "error": "Rekategorisierung des Bildes gescheitert: {error}",
"success": "Bild wurde einer neuen Kategorie zugeordnet." "success": "Bild wurde einer neuen Kategorie zugeordnet."
}, },
"remove": {
"error": "Fehler beim Entfernen der Schwärzung: {error}",
"success": "Schwärzung entfernt!"
},
"remove-hint": { "remove-hint": {
"error": "Failed to remove hint: {error}", "error": "Failed to remove hint: {error}",
"success": "Hint removed!" "success": "Hint removed!"
}, },
"remove": {
"error": "Fehler beim Entfernen der Schwärzung: {error}",
"success": "Schwärzung entfernt!"
},
"undo": { "undo": {
"error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}",
"success": "erfolgreich Rückgängig gemacht" "success": "erfolgreich Rückgängig gemacht"
@ -349,15 +349,15 @@
"remove-highlights": { "remove-highlights": {
"label": "Remove selected earmarks" "label": "Remove selected earmarks"
}, },
"resize": {
"label": "Größe ändern"
},
"resize-accept": { "resize-accept": {
"label": "Größe speichern" "label": "Größe speichern"
}, },
"resize-cancel": { "resize-cancel": {
"label": "Größenänderung abbrechen" "label": "Größenänderung abbrechen"
}, },
"resize": {
"label": "Größe ändern"
},
"see-references": { "see-references": {
"label": "See references" "label": "See references"
}, },
@ -391,6 +391,9 @@
"skipped": "Übersprungen", "skipped": "Übersprungen",
"text-highlight": "Earmark" "text-highlight": "Earmark"
}, },
"annotation": {
"pending": "(Pending analysis)"
},
"annotations": "Annotations", "annotations": "Annotations",
"archived-dossiers-listing": { "archived-dossiers-listing": {
"no-data": { "no-data": {
@ -613,18 +616,14 @@
"warning": "Achtung: Diese Aktion kann nicht rückgängig gemacht werden!" "warning": "Achtung: Diese Aktion kann nicht rückgängig gemacht werden!"
}, },
"confirmation-dialog": { "confirmation-dialog": {
"approve-file": {
"question": "Dieses Dokument enthält ungesehene Änderungen. Möchten Sie es trotzdem genehmigen?",
"title": "Warnung!"
},
"approve-file-without-analysis": { "approve-file-without-analysis": {
"confirmationText": "Approve without analysis", "confirmationText": "Approve without analysis",
"denyText": "Cancel", "denyText": "Cancel",
"question": "Analysis required to detect new components.", "question": "Analysis required to detect new components.",
"title": "Warning!" "title": "Warning!"
}, },
"approve-multiple-files": { "approve-file": {
"question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen. Möchten Sie sie trotzdem genehmigen?", "question": "Dieses Dokument enthält ungesehene Änderungen. Möchten Sie es trotzdem genehmigen?",
"title": "Warnung!" "title": "Warnung!"
}, },
"approve-multiple-files-without-analysis": { "approve-multiple-files-without-analysis": {
@ -633,6 +632,10 @@
"question": "Analysis required to detect new components for at least one file.", "question": "Analysis required to detect new components for at least one file.",
"title": "Warning" "title": "Warning"
}, },
"approve-multiple-files": {
"question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen. Möchten Sie sie trotzdem genehmigen?",
"title": "Warnung!"
},
"assign-file-to-me": { "assign-file-to-me": {
"question": { "question": {
"multiple": "Dieses Dokument wird gerade von einer anderen Person geprüft. Möchten Sie Reviewer werden und sich selbst dem Dokument zuweisen?", "multiple": "Dieses Dokument wird gerade von einer anderen Person geprüft. Möchten Sie Reviewer werden und sich selbst dem Dokument zuweisen?",
@ -1002,13 +1005,13 @@
"recent": "Neu ({hours} h)", "recent": "Neu ({hours} h)",
"unassigned": "Niemandem zugewiesen" "unassigned": "Niemandem zugewiesen"
}, },
"reanalyse": {
"action": "Datei analysieren"
},
"reanalyse-dossier": { "reanalyse-dossier": {
"error": "Die Dateien konnten nicht für eine Reanalyse eingeplant werden. Bitte versuchen Sie es erneut.", "error": "Die Dateien konnten nicht für eine Reanalyse eingeplant werden. Bitte versuchen Sie es erneut.",
"success": "Dateien für Reanalyse vorgesehen." "success": "Dateien für Reanalyse vorgesehen."
}, },
"reanalyse": {
"action": "Datei analysieren"
},
"start-auto-analysis": "Enable auto-analysis", "start-auto-analysis": "Enable auto-analysis",
"stop-auto-analysis": "Stop auto-analysis", "stop-auto-analysis": "Stop auto-analysis",
"table-col-names": { "table-col-names": {
@ -1078,19 +1081,10 @@
"total-documents": "Anzahl der Dokumente", "total-documents": "Anzahl der Dokumente",
"total-people": "<strong>{count}</strong> {count, plural, one{user} other {users}}" "total-people": "<strong>{count}</strong> {count, plural, one{user} other {users}}"
}, },
"dossier-templates": {
"label": "Dossier-Vorlagen",
"status": {
"active": "Active",
"inactive": "Inactive",
"incomplete": "Incomplete"
}
},
"dossier-templates-listing": { "dossier-templates-listing": {
"action": { "action": {
"clone": "Clone template", "clone": "Clone template",
"delete": "Dossier-Vorlage", "delete": "Dossier-Vorlage"
"edit": "Vorlage bearbeiten"
}, },
"add-new": "Neue Dossier-Vorlage", "add-new": "Neue Dossier-Vorlage",
"bulk": { "bulk": {
@ -1121,6 +1115,14 @@
"title": "{length} dossier {length, plural, one{template} other{templates}}" "title": "{length} dossier {length, plural, one{template} other{templates}}"
} }
}, },
"dossier-templates": {
"label": "Dossier-Vorlagen",
"status": {
"active": "Active",
"inactive": "Inactive",
"incomplete": "Incomplete"
}
},
"dossier-watermark-selector": { "dossier-watermark-selector": {
"heading": "Watermarks on documents", "heading": "Watermarks on documents",
"no-watermark": "There is no watermark defined for the dossier template.<br>Contact your app admin to define one.", "no-watermark": "There is no watermark defined for the dossier template.<br>Contact your app admin to define one.",
@ -1152,6 +1154,7 @@
"delta-preview": "Delta PDF", "delta-preview": "Delta PDF",
"flatten": "PDF verflachen", "flatten": "PDF verflachen",
"label": "{length} document {length, plural, one{version} other{versions}}", "label": "{length} document {length, plural, one{version} other{versions}}",
"optimized-preview": "Optimized Preview PDF",
"original": "Optimiertes PDF", "original": "Optimiertes PDF",
"preview": "PDF-Vorschau", "preview": "PDF-Vorschau",
"redacted": "geschwärztes PDF", "redacted": "geschwärztes PDF",
@ -1316,15 +1319,6 @@
"title": "{length} {length, plural, one{entity} other{entities}}" "title": "{length} {length, plural, one{entity} other{entities}}"
} }
}, },
"entity": {
"info": {
"actions": {
"revert": "Revert",
"save": "Save changes"
},
"heading": "Edit entity"
}
},
"entity-rules-screen": { "entity-rules-screen": {
"error": { "error": {
"generic": "Something went wrong... Entity rules update failed!" "generic": "Something went wrong... Entity rules update failed!"
@ -1339,19 +1333,28 @@
"warning-text": "Warning: experimental feature!", "warning-text": "Warning: experimental feature!",
"warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} found in rules" "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} found in rules"
}, },
"entity": {
"info": {
"actions": {
"revert": "Revert",
"save": "Save changes"
},
"heading": "Edit entity"
}
},
"error": { "error": {
"deleted-entity": { "deleted-entity": {
"dossier": { "dossier": {
"action": "Zurück zur Übersicht", "action": "Zurück zur Übersicht",
"label": "Dieses Dossier wurde gelöscht!" "label": "Dieses Dossier wurde gelöscht!"
}, },
"file": {
"action": "Zurück zum Dossier",
"label": "Diese Datei wurde gelöscht!"
},
"file-dossier": { "file-dossier": {
"action": "Zurück zur Übersicht", "action": "Zurück zur Übersicht",
"label": "Das Dossier dieser Datei wurde gelöscht!" "label": "Das Dossier dieser Datei wurde gelöscht!"
},
"file": {
"action": "Zurück zum Dossier",
"label": "Diese Datei wurde gelöscht!"
} }
}, },
"file-preview": { "file-preview": {
@ -1369,12 +1372,6 @@
}, },
"exact-date": "{day} {month} {year} um {hour}:{minute} Uhr", "exact-date": "{day} {month} {year} um {hour}:{minute} Uhr",
"file": "Datei", "file": "Datei",
"file-attribute": {
"update": {
"error": "Failed to update file attribute value!",
"success": "File attribute value has been updated successfully!"
}
},
"file-attribute-encoding-types": { "file-attribute-encoding-types": {
"ascii": "ASCII", "ascii": "ASCII",
"iso": "ISO-8859-1", "iso": "ISO-8859-1",
@ -1385,6 +1382,12 @@
"number": "Nummer", "number": "Nummer",
"text": "Freier Text" "text": "Freier Text"
}, },
"file-attribute": {
"update": {
"error": "Failed to update file attribute value!",
"success": "File attribute value has been updated successfully!"
}
},
"file-attributes-configurations": { "file-attributes-configurations": {
"cancel": "Cancel", "cancel": "Cancel",
"form": { "form": {
@ -1602,15 +1605,6 @@
"csv": "File attributes were imported successfully from uploaded CSV file." "csv": "File attributes were imported successfully from uploaded CSV file."
} }
}, },
"filter": {
"analysis": "Analyse erforderlich",
"comment": "Kommentare",
"hint": "Nut Hinweise",
"image": "Bilder",
"none": "Keine Anmerkungen",
"redaction": "Geschwärzt",
"updated": "Aktualisiert"
},
"filter-menu": { "filter-menu": {
"filter-options": "Filteroptionen", "filter-options": "Filteroptionen",
"filter-types": "Filter", "filter-types": "Filter",
@ -1620,6 +1614,15 @@
"unseen-pages": "Nur Anmerkungen auf unsichtbaren Seiten", "unseen-pages": "Nur Anmerkungen auf unsichtbaren Seiten",
"with-comments": "Nur Anmerkungen mit Kommentaren" "with-comments": "Nur Anmerkungen mit Kommentaren"
}, },
"filter": {
"analysis": "Analyse erforderlich",
"comment": "Kommentare",
"hint": "Nut Hinweise",
"image": "Bilder",
"none": "Keine Anmerkungen",
"redaction": "Geschwärzt",
"updated": "Aktualisiert"
},
"filters": { "filters": {
"assigned-people": "Beauftragt", "assigned-people": "Beauftragt",
"documents-status": "Documents state", "documents-status": "Documents state",
@ -1898,13 +1901,6 @@
"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": "Notifications",
"deleted-dossier": "Deleted dossier",
"label": "Benachrichtigungen",
"mark-all-as-read": "Alle als gelesen markieren",
"mark-as": "Mark as {type, select, read{read} unread{unread} other{}}"
},
"notifications-screen": { "notifications-screen": {
"category": { "category": {
"email-notifications": "E-Mail Benachrichtigungen", "email-notifications": "E-Mail Benachrichtigungen",
@ -1918,6 +1914,7 @@
"dossier": "Dossierbezogene Benachrichtigungen", "dossier": "Dossierbezogene Benachrichtigungen",
"other": "Andere Benachrichtigungen" "other": "Andere Benachrichtigungen"
}, },
"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 Überprüfer zugewiesen bin",
@ -1935,7 +1932,6 @@
"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, in welcher Kategorie Sie benachrichtigt werden möchten",
"schedule": { "schedule": {
"daily": "Tägliche Zusammenfassung", "daily": "Tägliche Zusammenfassung",
"instant": "Sofortig", "instant": "Sofortig",
@ -1943,6 +1939,13 @@
}, },
"title": "Benachrichtigungseinstellungen" "title": "Benachrichtigungseinstellungen"
}, },
"notifications": {
"button-text": "Notifications",
"deleted-dossier": "Deleted dossier",
"label": "Benachrichtigungen",
"mark-all-as-read": "Alle als gelesen markieren",
"mark-as": "Mark as {type, select, read{read} unread{unread} other{}}"
},
"ocr": { "ocr": {
"confirmation-dialog": { "confirmation-dialog": {
"cancel": "Cancel", "cancel": "Cancel",
@ -2026,6 +2029,7 @@
"help-mode-dialog": "Help Mode Dialog", "help-mode-dialog": "Help Mode Dialog",
"load-all-annotations-warning": "Warning regarding loading all annotations at once in file preview", "load-all-annotations-warning": "Warning regarding loading all annotations at once in file preview",
"open-structured-view-by-default": "Display Component View by default when opening a document", "open-structured-view-by-default": "Display Component View by default when opening a document",
"overwrite-file-option": "",
"table-extraction-type": "Table extraction type" "table-extraction-type": "Table extraction type"
}, },
"label": "Preferences", "label": "Preferences",
@ -2034,16 +2038,16 @@
"warnings-label": "Prompts and dialogs", "warnings-label": "Prompts and dialogs",
"warnings-subtitle": "Do not show again options" "warnings-subtitle": "Do not show again options"
}, },
"processing": {
"basic": "Processing",
"ocr": "OCR"
},
"processing-status": { "processing-status": {
"ocr": "OCR", "ocr": "OCR",
"pending": "Pending", "pending": "Pending",
"processed": "Processed", "processed": "Processed",
"processing": "Processing" "processing": "Processing"
}, },
"processing": {
"basic": "Processing",
"ocr": "OCR"
},
"readonly": "Lesemodus", "readonly": "Lesemodus",
"readonly-archived": "Read only (archived)", "readonly-archived": "Read only (archived)",
"redact-text": { "redact-text": {
@ -2279,12 +2283,6 @@
"red-user-admin": "Benutzer-Admin", "red-user-admin": "Benutzer-Admin",
"regular": "Regulär" "regular": "Regulär"
}, },
"search": {
"active-dossiers": "ganze Plattform",
"all-dossiers": "all documents",
"placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen",
"this-dossier": "in diesem Dossier"
},
"search-screen": { "search-screen": {
"cols": { "cols": {
"assignee": "Bevollmächtigter", "assignee": "Bevollmächtigter",
@ -2308,6 +2306,12 @@
"no-match": "Keine Dokumente entsprechen Ihren aktuellen Filtern.", "no-match": "Keine Dokumente entsprechen Ihren aktuellen Filtern.",
"table-header": "{length} search {length, plural, one{result} other{results}}" "table-header": "{length} search {length, plural, one{result} other{results}}"
}, },
"search": {
"active-dossiers": "ganze Plattform",
"all-dossiers": "all documents",
"placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen",
"this-dossier": "in diesem Dossier"
},
"seconds": "seconds", "seconds": "seconds",
"size": "Size", "size": "Size",
"smtp-auth-config": { "smtp-auth-config": {

View File

@ -206,11 +206,14 @@
"generic": "Failed to save user!" "generic": "Failed to save user!"
}, },
"form": { "form": {
"account-setup": "User account setup",
"email": "E-mail", "email": "E-mail",
"first-name": "First name", "first-name": "First name",
"last-name": "Last name", "last-name": "Last name",
"reset-password": "Reset password", "reset-password": "Reset password",
"role": "Role" "role": "Role",
"send-email": "Do not send email requesting the user to set a password",
"send-email-explanation": "Select this option if you use SSO. Please note that you will need to inform the user directly."
}, },
"title": "{type, select, edit{Edit} create{Add New} other{}} user" "title": "{type, select, edit{Edit} create{Add New} other{}} user"
}, },
@ -1081,8 +1084,7 @@
"dossier-templates-listing": { "dossier-templates-listing": {
"action": { "action": {
"clone": "Clone template", "clone": "Clone template",
"delete": "Delete template", "delete": "Delete template"
"edit": "Edit template"
}, },
"add-new": "New dossier template", "add-new": "New dossier template",
"bulk": { "bulk": {
@ -1152,6 +1154,7 @@
"delta-preview": "Delta PDF", "delta-preview": "Delta PDF",
"flatten": "Flatten PDF", "flatten": "Flatten PDF",
"label": "{length} document {length, plural, one{version} other{versions}}", "label": "{length} document {length, plural, one{version} other{versions}}",
"optimized-preview": "Optimized Preview PDF",
"original": "Optimized PDF", "original": "Optimized PDF",
"preview": "Preview PDF", "preview": "Preview PDF",
"redacted": "Redacted PDF", "redacted": "Redacted PDF",
@ -2026,6 +2029,7 @@
"help-mode-dialog": "Help Mode Dialog", "help-mode-dialog": "Help Mode Dialog",
"load-all-annotations-warning": "Warning regarding loading all annotations at once in file preview", "load-all-annotations-warning": "Warning regarding loading all annotations at once in file preview",
"open-structured-view-by-default": "Display Component View by default when opening a document", "open-structured-view-by-default": "Display Component View by default when opening a document",
"overwrite-file-option": "Preferred action when re-uploading of an already existing file",
"table-extraction-type": "Table extraction type" "table-extraction-type": "Table extraction type"
}, },
"label": "Preferences", "label": "Preferences",

@ -1 +1 @@
Subproject commit 98ac49fbc81bb9989c14a8ca06c11d98ed042c86 Subproject commit b8ba2191f7ed2f3633dabeaac6d1d87ac6f53053

View File

@ -3,6 +3,7 @@ export const DownloadFileTypes = {
FLATTEN: 'FLATTEN', FLATTEN: 'FLATTEN',
ORIGINAL: 'ORIGINAL', ORIGINAL: 'ORIGINAL',
PREVIEW: 'PREVIEW', PREVIEW: 'PREVIEW',
OPTIMIZED_PREVIEW: 'OPTIMIZED_PREVIEW',
REDACTED: 'REDACTED', REDACTED: 'REDACTED',
DELTA_PREVIEW: 'DELTA_PREVIEW', DELTA_PREVIEW: 'DELTA_PREVIEW',
} as const; } as const;