Merge branch 'master' into VM/RED-8748

This commit is contained in:
Valentin Mihai 2024-06-10 14:41:12 +03:00
commit d0c6bef6b5
26 changed files with 926 additions and 278 deletions

View File

@ -19,6 +19,7 @@ import { BaseEntityScreenComponent } from './base-entity-screen/base-entity-scre
import { PermissionsGuard } from '@guards/permissions-guard';
import { Roles } from '@users/roles';
import { IqserAuthGuard } from '@iqser/common-ui/lib/users';
import { ComponentMappingsScreenComponent } from './screens/component-mappings/component-mappings-screen.component';
const dossierTemplateIdRoutes: IqserRoutes = [
{
@ -76,6 +77,14 @@ const dossierTemplateIdRoutes: IqserRoutes = [
},
loadChildren: () => import('./screens/rules/rules.module').then(m => m.RulesModule),
},
{
path: 'component-mappings',
component: ComponentMappingsScreenComponent,
canActivate: [CompositeRouteGuard],
data: {
routeGuards: [IqserAuthGuard, RedRoleGuard],
},
},
{
path: 'file-attributes',
component: BaseDossierTemplateScreenComponent,

View File

@ -57,6 +57,7 @@ import { IqserUsersModule } from '@iqser/common-ui/lib/users';
import { SelectComponent } from '@shared/components/select/select.component';
import { PaginationComponent } from '@common-ui/pagination/pagination.component';
import { AddCloneDossierTemplateDialogComponent } from './dialogs/add-clone-dossier-template-dialog/add-clone-dossier-template-dialog.component';
import { ComponentMappingsScreenComponent } from './screens/component-mappings/component-mappings-screen.component';
const dialogs = [
AddCloneDossierTemplateDialogComponent,
@ -76,6 +77,7 @@ const screens = [
DigitalSignatureScreenComponent,
UserListingScreenComponent,
GeneralConfigScreenComponent,
ComponentMappingsScreenComponent,
];
const components = [

View File

@ -0,0 +1,65 @@
<section class="dialog">
<div
[innerHTML]="'add-edit-component-mapping.dialog.title' | translate: { type: data.mapping ? 'edit' : 'add' }"
class="dialog-header heading-l"
></div>
<form (submit)="save()" [formGroup]="form">
<div class="dialog-content">
<div class="row">
<div class="iqser-input-group required w-300">
<label translate="add-edit-component-mapping.form.name"></label>
<input
[placeholder]="'add-edit-component-mapping.form.name-placeholder' | translate"
formControlName="name"
name="label"
type="text"
/>
</div>
<div class="iqser-input-group w-100 version" *ngIf="data?.mapping?.id">
<label translate="add-edit-component-mapping.form.version"></label>
<span> {{ data.mapping.version }} </span>
</div>
</div>
<div class="iqser-input-group required">
<label translate="add-edit-component-mapping.form.file"></label>
<iqser-upload-file (fileChanged)="fileChanged($event)" [file]="activeFile" [accept]="'.csv'" />
</div>
<div class="row">
<div class="iqser-input-group required w-150">
<label translate="add-edit-component-mapping.form.delimiter"></label>
<input
[placeholder]="'add-edit-component-mapping.form.delimiter-placeholder' | translate"
formControlName="delimiter"
name="delimiter"
type="text"
/>
</div>
<div class="iqser-input-group required w-150">
<label translate="add-edit-component-mapping.form.encoding-type"></label>
<mat-form-field>
<mat-select formControlName="encoding">
<mat-option *ngFor="let type of encodingTypeOptions" [value]="type">
{{ translations[type] | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div class="dialog-actions">
<iqser-icon-button
(action)="save()"
[disabled]="disabled"
[label]="'add-edit-component-mapping.actions.save' | translate"
[type]="iconButtonTypes.primary"
></iqser-icon-button>
</div>
</form>
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
</section>

View File

@ -0,0 +1,21 @@
.row {
display: flex;
margin-top: 14px;
> *:not(:last-child) {
margin-right: 16px;
}
.iqser-input-group {
margin-top: 0;
}
.version {
margin-left: 50px;
span {
margin-top: 10px;
font-size: 15px;
}
}
}

View File

@ -0,0 +1,91 @@
import { Component, OnInit } from '@angular/core';
import { CircleButtonComponent, IconButtonComponent, IconButtonTypes, IqserDialogComponent, IqserUploadFileModule } from '@iqser/common-ui';
import { FileAttributeEncodingTypes, IComponentMapping } from '@red/domain';
import { FormBuilder, ReactiveFormsModule, UntypedFormGroup, Validators } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { NgForOf, NgIf } from '@angular/common';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatDialogClose } from '@angular/material/dialog';
import { MatOption } from '@angular/material/autocomplete';
import { MatSelect } from '@angular/material/select';
import { fileAttributeEncodingTypesTranslations } from '@translations/file-attribute-encoding-types-translations';
import { firstValueFrom } from 'rxjs';
import { ComponentMappingsService } from '@services/entity-services/component-mappings.service';
interface DialogData {
dossierTemplateId: string;
mapping: IComponentMapping;
}
interface DialogResult {
id: string;
name: string;
file: Blob;
encoding: string;
delimiter: string;
}
@Component({
templateUrl: './add-edit-component-mapping-dialog.component.html',
styleUrls: ['./add-edit-component-mapping-dialog.component.scss'],
standalone: true,
imports: [
TranslateModule,
ReactiveFormsModule,
NgIf,
MatFormFieldModule,
NgForOf,
CircleButtonComponent,
MatDialogClose,
IqserUploadFileModule,
MatOption,
MatSelect,
IconButtonComponent,
],
})
export class AddEditComponentMappingDialogComponent
extends IqserDialogComponent<AddEditComponentMappingDialogComponent, DialogData, DialogResult>
implements OnInit
{
protected readonly encodingTypeOptions = Object.keys(FileAttributeEncodingTypes);
protected readonly translations = fileAttributeEncodingTypesTranslations;
protected readonly iconButtonTypes = IconButtonTypes;
activeFile: File;
form!: UntypedFormGroup;
constructor(
private readonly _formBuilder: FormBuilder,
private readonly _componentMappingService: ComponentMappingsService,
) {
super();
this.form = this.#getForm();
}
async ngOnInit() {
if (this.data.mapping?.fileName) {
this.activeFile = { name: this.data.mapping.fileName } as File;
const fileContent = await firstValueFrom(
this._componentMappingService.getComponentMappingFile(this.data.dossierTemplateId, this.data.mapping.id),
);
const file = new Blob([fileContent], { type: 'text/csv' });
this.form.get('file').setValue(file);
this.initialFormValue = this.form.getRawValue();
}
}
fileChanged(file: Blob) {
this.form.get('file').setValue(file);
}
save() {
this.dialogRef.close({ ...this.data.mapping, ...this.form.getRawValue() });
}
#getForm(): UntypedFormGroup {
return this._formBuilder.group({
name: [this.data?.mapping?.name, Validators.required],
file: [null, Validators.required],
encoding: this.encodingTypeOptions.find(e => e === this.data?.mapping?.encoding) ?? this.encodingTypeOptions[0],
delimiter: [this.data?.mapping?.delimiter ?? ',', Validators.required],
});
}
}

View File

@ -0,0 +1,73 @@
<section *ngIf="context$ | async as context">
<div class="page-header">
<redaction-dossier-template-breadcrumbs class="flex-1"></redaction-dossier-template-breadcrumbs>
<div class="flex-1 actions">
<redaction-dossier-template-actions></redaction-dossier-template-actions>
<iqser-circle-button
[routerLink]="['../..']"
[tooltip]="'common.close' | translate"
icon="iqser:close"
tooltipPosition="below"
></iqser-circle-button>
</div>
</div>
<div class="content-inner">
<div class="overlay-shadow"></div>
<redaction-admin-side-nav type="dossierTemplates"></redaction-admin-side-nav>
<div class="content-container">
<iqser-table [headerTemplate]="headerTemplate" [itemSize]="80" [tableColumnConfigs]="tableColumnConfigs" emptyColumnWidth="2fr">
</iqser-table>
</div>
</div>
</section>
<ng-template #headerTemplate>
<div class="table-header-actions">
<iqser-input-with-action
[(value)]="searchService.searchValue"
[placeholder]="'component-mappings-screen.search' | translate"
></iqser-input-with-action>
<div class="actions">
<iqser-icon-button
(action)="openAddEditComponentMappingDialog()"
*allow="roles.componentMappings.write; if: currentUser.isAdmin"
[label]="'component-mappings-screen.add-new' | translate"
[type]="iconButtonTypes.primary"
icon="iqser:plus"
></iqser-icon-button>
</div>
</div>
</ng-template>
<ng-template #tableItemTemplate let-entity="entity">
<div>
<div class="label cell">
<span>{{ entity.name }}</span>
</div>
<div class="cell">
<span>{{ entity.version }}</span>
</div>
<div class="cell">
<div *allow="roles.componentMappings.write; if: currentUser.isAdmin" class="action-buttons">
<iqser-circle-button
(action)="openAddEditComponentMappingDialog(entity)"
[tooltip]="'component-mappings-screen.action.edit' | translate"
icon="iqser:edit"
></iqser-circle-button>
<iqser-circle-button
(action)="openDeleteComponentMappingDialog(entity)"
[tooltip]="'component-mappings-screen.action.delete' | translate"
icon="iqser:trash"
></iqser-circle-button>
</div>
</div>
</div>
</ng-template>

View File

@ -0,0 +1,92 @@
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import {
ListingComponent,
TableColumnConfig,
listingProvidersFactory,
LoadingService,
IconButtonTypes,
IqserDialog,
} from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { defaultColorsTranslations } from '@translations/default-colors-translations';
import { Roles } from '@users/roles';
import { getCurrentUser } from '@common-ui/users';
import { DOSSIER_TEMPLATE_ID, User } from '@red/domain';
import { ComponentMapping } from '@red/domain';
import { combineLatest, firstValueFrom } from 'rxjs';
import { ComponentMappingsService } from '@services/entity-services/component-mappings.service';
import { map, tap } from 'rxjs/operators';
import { AddEditComponentMappingDialogComponent } from './add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component';
import { AdminDialogService } from '../../services/admin-dialog.service';
import { getParam } from '@common-ui/utils';
@Component({
templateUrl: './component-mappings-screen.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
providers: listingProvidersFactory(ComponentMappingsScreenComponent),
})
export class ComponentMappingsScreenComponent extends ListingComponent<ComponentMapping> implements OnInit {
tableColumnConfigs: readonly TableColumnConfig<ComponentMapping>[] = [
{ label: _('component-mappings-screen.table-col-names.name'), sortByKey: 'searchKey' },
{ label: _('component-mappings-screen.table-col-names.version') },
];
readonly tableHeaderLabel = _('component-mappings-screen.table-header.title');
protected readonly context$;
protected readonly currentUser = getCurrentUser<User>();
protected readonly translations = defaultColorsTranslations;
protected readonly roles = Roles;
protected readonly iconButtonTypes = IconButtonTypes;
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
constructor(
private readonly _loadingService: LoadingService,
private readonly _componentMappingService: ComponentMappingsService,
private readonly _iqserDialog: IqserDialog,
private readonly _dialogService: AdminDialogService,
) {
super();
this.context$ = this.loadData$();
}
loadData$() {
return combineLatest([this._componentMappingService.getComponentMappings(this.#dossierTemplateId)]).pipe(
map(([mappingList]) => mappingList.componentMappingList),
tap(mappings => this.entitiesService.setEntities(mappings)),
);
}
ngOnInit() {
this._loadingService.stop();
}
async openAddEditComponentMappingDialog(mapping?: ComponentMapping) {
const dialog = this._iqserDialog.openDefault(AddEditComponentMappingDialogComponent, {
data: {
dossierTemplateId: this.#dossierTemplateId,
mapping,
},
});
const result = await dialog.result();
if (result) {
this._loadingService.start();
const { id, name, encoding, delimiter } = result;
const newMapping = { id, name, encoding, delimiter };
await firstValueFrom(
this._componentMappingService.createUpdateComponentMapping(this.#dossierTemplateId, newMapping, result.file),
);
await firstValueFrom(this.loadData$());
this._loadingService.stop();
}
}
openDeleteComponentMappingDialog(entity: ComponentMapping) {
this._dialogService.openDialog('confirm', null, async confirmation => {
if (confirmation) {
this._loadingService.start();
await firstValueFrom(this._componentMappingService.deleteComponentMapping(this.#dossierTemplateId, entity.id));
await firstValueFrom(this.loadData$());
this._loadingService.stop();
}
});
}
}

View File

@ -62,8 +62,12 @@ export class SmtpFormComponent extends BaseFormComponent implements OnInit {
async testConnection() {
this._loadingService.start();
try {
await firstValueFrom(this._smtpConfigService.testSMTPConfiguration(this.form.getRawValue()));
this._toaster.success(_('general-config-screen.test.success'));
const response = await firstValueFrom(this._smtpConfigService.testSMTPConfiguration(this.form.getRawValue()));
if (!response.adminEmail) {
this._toaster.warning(_('general-config-screen.test.warning'), { params: { recipientEmail: response.recipientEmail } });
} else {
this._toaster.success(_('general-config-screen.test.success'));
}
} catch (e) {
this._toaster.error(_('general-config-screen.test.error'));
} finally {

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { GenericService } from '@iqser/common-ui';
import { ISmtpConfiguration } from '@red/domain';
import { ISmtpConfiguration, ITextConnectionResponse } from '@red/domain';
@Injectable()
export class SmtpConfigService extends GenericService<unknown> {
@ -12,7 +12,7 @@ export class SmtpConfigService extends GenericService<unknown> {
}
testSMTPConfiguration(body: ISmtpConfiguration) {
return this._post(body, `${this._defaultModelPath}/smtp/test`);
return this._post<ITextConnectionResponse>(body, `${this._defaultModelPath}/smtp/test`);
}
getCurrentSMTPConfiguration() {

View File

@ -106,6 +106,11 @@ export class AdminSideNavComponent implements OnInit {
(this.isIqserDevMode || this.canAccessRulesInDocumine) &&
this._permissionsService.has(Roles.rules.read),
},
{
screen: 'component-mappings',
label: _('admin-side-nav.component-mappings'),
show: this.isDocumine,
},
{
screen: 'default-colors',
label: _('admin-side-nav.default-colors'),

View File

@ -57,7 +57,7 @@
<div class="due-date">
<mat-checkbox
(change)="hasDueDate = !hasDueDate"
(change)="toggleDueDateField()"
[checked]="hasDueDate"
[disabled]="form.get('dueDate').disabled"
class="filter-menu-checkbox"

View File

@ -106,18 +106,16 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
description: this.dossier.description,
dueDate: this.dossier.dueDate,
});
this.hasDueDate = !!this.dossier.dueDate;
}
async save(): EditDossierSaveResult {
let dueDate;
if (this.hasDueDate) {
dueDate = dateWithoutTime(dayjs(this.form.get('dueDate').value));
}
const dueDate = dateWithoutTime(dayjs(this.form.get('dueDate').value));
const dossier = {
...this.dossier,
dossierName: this.form.get('dossierName').value,
description: this.form.get('description').value,
dueDate: dueDate,
dueDate: dueDate.isValid() ? dueDate.toISOString() : undefined,
dossierTemplateId: this.form.get(DOSSIER_TEMPLATE_ID).value,
dossierStatusId: this.form.get('dossierStatusId').value,
} as IDossierRequest;
@ -190,6 +188,13 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
return this._dossierStatesMapService.get(this.dossier.dossierTemplateId, stateId).color;
}
toggleDueDateField() {
this.hasDueDate = !this.hasDueDate;
if (!this.hasDueDate) {
this.form.controls['dueDate'].setValue(null);
}
}
async #closeDialogAndRedirectToDossier() {
this._editDossierDialogRef.close();
await this._router.navigate([this.dossier.dossiersListRouterLink]);

View File

@ -10,7 +10,6 @@ import { inject, Injectable, OnDestroy } from '@angular/core';
import { DashboardStatsService } from '../dossier-templates/dashboard-stats.service';
import { CHANGED_CHECK_INTERVAL } from '@utils/constants';
import { List } from '@iqser/common-ui/lib/utils';
import { DossiersCacheService } from '@services/dossiers/dossiers-cache.service';
import { Router } from '@angular/router';
import { filterEventsOnPages } from '@utils/operators';
@ -21,7 +20,6 @@ export class DossiersChangesService extends GenericService<Dossier> implements O
readonly #archivedDossiersService = inject(ArchivedDossiersService);
readonly #dashboardStatsService = inject(DashboardStatsService);
readonly #logger = inject(NGXLogger);
readonly #dossierCache = inject(DossiersCacheService);
readonly #router = inject(Router);
protected readonly _defaultModelPath = 'dossier';
@ -78,7 +76,6 @@ export class DossiersChangesService extends GenericService<Dossier> implements O
}
#load(id: string): Observable<DossierStats[]> {
if (!this.#dossierCache.get(id)) return of([]);
const queryParams: List<QueryParam> = [{ key: 'includeArchived', value: true }];
return super._getOne([id], this._defaultModelPath, queryParams).pipe(
map(entity => new Dossier(entity)),

View File

@ -0,0 +1,60 @@
import { Injectable } from '@angular/core';
import { EntitiesService, QueryParam } from '@iqser/common-ui';
import { ComponentMapping, IComponentMapping, IComponentMappingList } from '@red/domain';
import { Observable } from 'rxjs';
import { HeadersConfiguration, List } from '@common-ui/utils';
interface CreateMappingParams {
dossierTemplateId: string;
name: string;
encoding: string;
delimiter: string;
}
@Injectable({
providedIn: 'root',
})
export class ComponentMappingsService extends EntitiesService<IComponentMapping, ComponentMapping> {
getComponentMappings(dossierTemplateId: string): Observable<IComponentMappingList> {
return this._http.get<IComponentMappingList>(`/api/dossier-templates/${dossierTemplateId}/component-mappings`);
}
createUpdateComponentMapping(
dossierTemplateId: string,
componentMapping: Partial<ComponentMapping>,
file: Blob,
): Observable<IComponentMapping> {
const formParams = new FormData();
formParams.append('file', file);
const queryParams: List<QueryParam> = [
{ key: 'name', value: componentMapping.name },
{ key: 'encoding', value: componentMapping.encoding },
{ key: 'delimiter', value: componentMapping.delimiter },
];
if (componentMapping.id) {
return this._http.put<IComponentMapping>(
`/api/dossier-templates/${dossierTemplateId}/component-mappings/${componentMapping.id}`,
formParams,
{
params: this._queryParams(queryParams),
},
);
}
return this._http.post<IComponentMapping>(`/api/dossier-templates/${dossierTemplateId}/component-mappings`, formParams, {
params: this._queryParams(queryParams),
});
}
deleteComponentMapping(dossierTemplateId: string, componentMappingId: string) {
return this._http.delete(`/api/dossier-templates/${dossierTemplateId}/component-mappings/${componentMappingId}`);
}
getComponentMappingFile(dossierTemplateId: string, componentMappingId: string) {
return this._http.get(`/api/dossier-templates/${dossierTemplateId}/component-mappings/${componentMappingId}`, {
responseType: 'text',
});
}
}

View File

@ -21,6 +21,10 @@ export const Roles = {
read: 'red-read-rules',
write: 'red-write-rules',
},
componentMappings: {
read: 'red-read-rules',
write: 'red-write-rules',
},
redactions: {
write: 'red-add-redaction',
readManual: 'red-read-manual-redactions',

File diff suppressed because it is too large Load Diff

View File

@ -94,6 +94,23 @@
},
"save": "Save dossier template"
},
"add-edit-component-mapping": {
"actions": {
"save": "Save mapping"
},
"dialog": {
"title": "{type, select, add{Add New} edit{Edit} other{}} Component Mapping"
},
"form": {
"delimiter": "",
"delimiter-placeholder": "",
"encoding-type": "",
"file": "Mapping file",
"name": "Mapping name",
"name-placeholder": "Mapping name",
"version": "Version"
}
},
"add-edit-dossier-attribute": {
"error": {
"generic": "Failed to save attribute"
@ -138,12 +155,12 @@
"rank-placeholder": "1000",
"redaction": "Redaction",
"technical-name": "Technical name",
"technical-name-hint": "{type, select, edit{Auto-generated based on the initial display name.} create{Is auto-generates based on the display name and cannot be edited after saving.} other{}}",
"technical-name-hint": "{type, select, edit{Auto-generated based on the initial display name.} create{Is auto-generated based on the display name and cannot be edited after saving.} other{}}",
"template-and-dossier-dictionaries": "Template & dossier dictionaries"
},
"success": {
"create": "Success: Entity created.",
"edit": "<strong>Entity updated.</strong><br><br>Please note that other users need to refresh their browsers to see your changes."
"edit": "<strong>Success: Entity updated.</strong><br><br>Please ask the users to refresh the browser to see the changes."
}
},
"add-edit-file-attribute": {
@ -231,6 +248,7 @@
},
"admin-side-nav": {
"audit": "Audit",
"component-mappings": "Component mappings",
"component-rule-editor": "",
"configurations": "Configurations",
"default-colors": "Default colors",
@ -513,6 +531,24 @@
"value": "Value"
}
},
"component-mappings-screen": {
"action": {
"delete": "Delete mapping",
"edit": "Edit mapping"
},
"add-new": "New Mapping",
"bulk-actions": {
"delete": "Delete selected mappings"
},
"search": "Search by name...",
"table-col-names": {
"name": "name",
"version": "version"
},
"table-header": {
"title": "Component mapping"
}
},
"component-rules-screen": {
"error": {
"generic": ""
@ -542,10 +578,10 @@
"cancel": "Keep {count, plural, one{attribute} other{attributes}}",
"delete": "Delete {count, plural, one{attribute} other{attributes}}",
"dossier-impacted-documents": "This action will affect all dossiers that use this template.",
"dossier-lost-details": "All attribute values entered by users on document level will be lost.",
"dossier-lost-details": "The attribute values entered by users on document level will be lost.",
"file-impacted-documents": "All documents that use {count, plural, one{his attribute} other{these attributes}} will be impacted.",
"file-lost-details": "All information entered by users on document level will be lost.",
"impacted-report": "<strong>{reportsCount} reports currently use the placeholder for this attribute.</strong> <br><br>Please update them accordingly.",
"impacted-report": "{reportsCount} reports currently use the placeholder for this attribute. Please update them.",
"title": "Delete {count, plural, one{{name}} other{file attributes}}",
"toast-error": "Please confirm that you understand the consequences of this action.",
"warning": "Warning: This action cannot be undone!"
@ -711,13 +747,13 @@
},
"download": "Download current entries",
"error": {
"400": "Cannot update dictionary because at least one of the newly added words where recognized as a general term that appear too often in texts.",
"generic": "An error occurred... Dictionary update failed!"
"400": "<strong>Dictionary update failed.</strong><br><br>One or more of the newly added terms have been identified as frequently used general term. Please remove these terms to proceed with the upate. ",
"generic": "Error: Dictionary update failed."
},
"revert-changes": "Revert",
"save-changes": "Save changes",
"search": "Search entries...",
"select-dictionary": "Select a dictionary above to compare with the current one.",
"select-dictionary": "Select a dictionary for comparison above.",
"success": {
"generic": "Dictionary updated"
}
@ -753,11 +789,11 @@
},
"options": {
"kms": {
"description": "Provide a corresponding PEM file containing the certificate, along with Amazon KMS credentials needed for securing the private key.",
"description": "Please upload a PEM file with the certificate and provide Amazon KMS credentials to secure the private key.",
"label": "I use an Amazon KMS private key"
},
"pkcs": {
"description": "A PKCS#12 file is a file that bundles the private key and the X.509 certificate. The password protection is required to secure the private key. Unprotected PKCS#12 files are not supported.",
"description": "A PKCS#12 file combines your private key with an X.509 certificate. Password protection is essential to secure the private key, as unprotected PKCS#12 files are not supported.",
"label": "I want to upload a PKCS#12 file"
}
},
@ -779,7 +815,7 @@
},
"no-data": {
"action": "Configure certificate",
"title": "No digital signature certificate.<br/>For signing redacted documents please configure a certificate."
"title": "No digital signature certificate available.<br/>Please configure a certificate to sign redacted documents."
}
},
"document-info": {
@ -888,7 +924,7 @@
},
"dossier-overview": {
"approve": "Approve",
"approve-disabled": "File can only be approved once it has been analysed with the latest dictionaries.",
"approve-disabled": "File can only be approved once it has been analyzed with the latest set of business rules and terms stored in the system dictionaries.",
"assign-approver": "Assign approver",
"assign-me": "Assign to me",
"assign-reviewer": "Assign user",
@ -923,7 +959,7 @@
}
},
"download-file": "Download",
"download-file-disabled": "You need to be approver in the dossier and the {count, plural, one{file needs} other{files need}} to be initially processed in order to download.",
"download-file-disabled": "To download, ensure you are an approver in the dossier, and the {count, plural, one{file has undergone} other{files have undergone}} initial processing.",
"file-listing": {
"file-entry": {
"file-error": "Re-processing required",
@ -1002,13 +1038,13 @@
},
"error": {
"conflict": "Dossier state with this name already exists",
"generic": "Failed to save dossier state!"
"generic": "Failed to save dossier state."
},
"no-data": {
"title": "There are no dossier states."
},
"no-match": {
"title": "No dossier states match your current filters."
"title": "No dossier state matches the currently selected filters."
},
"search": "Search...",
"table-col-names": {
@ -1050,8 +1086,8 @@
},
"entities": "{length} {length, plural, one{entity} other{entities}}",
"error": {
"conflict": "Cannot delete this dossier template. At least one dossier uses this template.",
"generic": "Cannot delete this dossier template!"
"conflict": "<strong>Deletion denied:</strong> This dossier template is used by at least one dossier and cannot be deleted.",
"generic": "Cannot delete this dossier template."
},
"no-data": {
"title": "There are no dossier templates yet."
@ -1083,8 +1119,8 @@
},
"dossier-watermark-selector": {
"heading": "Watermarks on documents",
"no-watermark": "There is no watermark defined for the dossier template.<br>Contact your app admin to define one.",
"preview": "Watermark application on preview documents",
"no-watermark": "No watermark available in dossier template:<br>Please ask your admin to configure a watermark.",
"preview": "Watermark on redacted documents",
"watermark": "Watermark application on redacted documents"
},
"dossiers-type-switch": {
@ -1102,10 +1138,10 @@
"header": "Download options",
"unapproved-files-warning": "This download contains unapproved file(s)."
},
"download-includes": "Choose what is included at download:",
"download-includes": "Select the documents for your download:",
"download-status": {
"error": "The download preparation failed, please recheck the selected files and download option settings.",
"queued": "Your download has been queued, you can see all your requested downloads here: <a href=\"{downloadHref}\">My downloads<a/>."
"error": "<strong>Download generation failed</strong><br><br>Please check the selected files and download option settings.",
"queued": "Your download has been added to the queue.<br><br>To see your requested downloads, visit: <a href=\"{downloadHref}\">My downloads<a/>."
},
"download-type": {
"annotated": "Annotated PDF",
@ -1145,7 +1181,7 @@
"color-placeholder": "Color"
},
"save": "Save",
"success": "<strong>Success: Color saved.</strong><br><br>Please note that other users need to refresh their browsers to see your changes."
"success": "<strong>Success: Color saved.</strong><br><br>Please ask the users to refresh the browser to see the changes."
},
"edit-dossier-dialog": {
"actions": {
@ -1157,7 +1193,7 @@
"custom-attributes": "Custom dossier attributes",
"delete-image": "Delete image",
"error": {
"generic": "Only PNG, JPG and JPEG files are allowed as image dossier attributes."
"generic": "Supported image formats: PNG, JPG, and JPEG."
},
"image-attributes": "Image attributes",
"no-custom-attributes": "There are no text attributes",
@ -1203,9 +1239,9 @@
}
},
"header": "Edit {dossierName}",
"missing-owner": "You cannot edit the dossier because the owner is missing!",
"missing-owner": "Editing the dossier not possible: No owner assigned.",
"nav-items": {
"choose-download": "Choose what is included at download:",
"choose-download": "Select the documents for your download:",
"dictionary": "Dictionaries",
"dossier-attributes": "Dossier attributes",
"dossier-dictionary": "Dictionaries",
@ -1263,7 +1299,7 @@
"title": "There are no entities yet."
},
"no-match": {
"title": "No entities match your current filters."
"title": "No entity matches your currently selected filters."
},
"search": "Search...",
"table-col-names": {
@ -1278,13 +1314,13 @@
},
"entity-rules-screen": {
"error": {
"generic": "An error ocurred... Entity rules update failed!"
"generic": "Error: Entity rules update failed."
},
"errors-found": "{errors, plural, one{An error} other{{errors} errors}} found in rules",
"revert-changes": "Revert",
"save-changes": "Save changes",
"success": {
"generic": "Entity rules updated!"
"generic": "Entity rules updated."
},
"title": "Entity rule editor",
"warning-text": "Warning: experimental feature!",
@ -1316,16 +1352,16 @@
},
"file-preview": {
"action": "Refresh",
"label": "An unknown error occurred. Please refresh the page"
"label": "<strong>Unknown error:</strong> Please refresh the page."
},
"http": {
"generic": "Action failed with code {status}"
"generic": "Action failed. Error code: {status}"
},
"missing-types": "The dossier template has missing types ({missingTypes}). Data might not be displayed correctly.",
"missing-types": "<strong>Dossier template incomplete:</strong> missing types ({missingTypes}) may cause data display issues.",
"offline": "Disconnected",
"online": "Reconnected",
"reload": "Reload",
"title": "Oops! Something went wrong..."
"title": "An error ocurred."
},
"exact-date": "{day} {month} {year} at {hour}:{minute}",
"file": "File",
@ -1341,7 +1377,7 @@
},
"file-attribute": {
"update": {
"error": "Failed to update file attribute value!",
"error": "Update of file attribute value failed. Please try again.",
"success": "File attribute value has been updated successfully!"
}
},
@ -1377,9 +1413,9 @@
"key-column": "Key column",
"key-column-placeholder": "Select column...",
"no-data": {
"title": "No file attributes defined. Select a column from the left panel to start defining file attributes."
"title": "No file attributes defined. Select a CSV column from the left to start defining file attributes."
},
"no-hovered-column": "Preview CSV column by hovering the entry.",
"no-hovered-column": "Preview CSV column by hovering over the entry.",
"no-sample-data-for": "No sample data for {column}.",
"parse-csv": "Parse CSV with new options",
"quick-activation": {
@ -1398,7 +1434,7 @@
"table-col-names": {
"name": "Name",
"primary": "Primary",
"primary-info-tooltip": "The value of the attribute set as primary shows up under the file name in the documents list.",
"primary-info-tooltip": "The value of the attribute set as primary is diplayed below the file name in the document list.",
"read-only": "Read-only",
"type": "Type"
},
@ -1426,7 +1462,7 @@
},
"configurations": "Configurations",
"error": {
"conflict": "File attribute with this name already exists!",
"conflict": "File attribute name already exists. Please try another name.",
"generic": "Failed to add file attribute"
},
"no-data": {
@ -1443,7 +1479,7 @@
"filterable": "Filterable",
"name": "Name",
"primary": "Primary",
"primary-info-tooltip": "The value of the attribute set as primary shows up under the file name in the documents list.",
"primary-info-tooltip": "The value of the attribute set as primary is diplayed below the file name in the document list.",
"read-only": "Read-only",
"type": "Input type"
},
@ -1457,7 +1493,7 @@
"assign-reviewer": "Assign user",
"change-reviewer": "Change user",
"delta": "Delta",
"delta-tooltip": "The delta view shows the unseen changes since your last visit to the page. This view is only available if there is at least 1 change.",
"delta-tooltip": "Delta shows the unseen changes since your last visit to the page. It is only available if there has been at least 1 change.",
"document-info": "Document info",
"download-original-file": "Download original file",
"exclude-pages": "Exclude pages from redaction",
@ -1480,7 +1516,7 @@
"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",
"standard": "Standard",
"standard-tooltip": "Standard workload view shows all hints, redactions & recommendations. This view allows editing.",
"standard-tooltip": "Standard shows all annotation types and allows for editing.",
"tabs": {
"annotations": {
"hide-skipped": "Hide skipped in document",
@ -1527,7 +1563,7 @@
}
},
"text-highlights": "Earmarks",
"text-highlights-tooltip": "Shows all text earmarks and allows removing or importing them as redactions",
"text-highlights-tooltip": "Earmark allows removing text highlights or converting them into redactions.",
"toggle-analysis": {
"disable": "Disable redaction",
"enable": "Enable for redaction",
@ -1642,19 +1678,20 @@
"title": "System preferences"
},
"test": {
"error": "Test e-mail could not be sent! Please revise the e-mail address.",
"success": "Test e-mail was sent successfully!"
"error": "Test e-mail could not be sent. Please double-check the email address.",
"success": "Test e-mail was sent successfully!",
"warning": "Admin mail address not set. Test email sent to {recipientEmail} instead."
},
"title": "Configure SMTP account"
},
"help-mode": {
"bottom-text": "Help mode",
"clicking-anywhere-on": "<b> Clicking anywhere on the screen </b> will show you which areas are interactive. Hovering an interactive area will <b> change the mouse cursor </b> to let you know if the element is interactive.",
"clicking-anywhere-on": "<b>Click anywhere on the screen </b> to display the interactive elements. When you hover over an interactive element, <b> the mouse cursor changes</b> to show the element is clickable.",
"instructions": "Open help mode instructions",
"options": {
"do-not-show-again": "Do not show again"
},
"welcome-to-help-mode": "<b> Welcome to help mode! <br> Clicking on interactive elements will open info about them in new tab. </b>"
"welcome-to-help-mode": "<b>Welcome to Help Mode!<br> Click on interactive elements to learn more about their functionality in a new tab."
},
"highlight-action-dialog": {
"actions": {
@ -1662,14 +1699,14 @@
},
"convert": {
"confirmation": "The {count} selected {count, plural, one{earmark} other{earmarks}} will be converted",
"details": "All earmarks from the document will be converted to imported redactions, using the color defined by the application admin.",
"details": "All earmarks in the document will be converted into imported redactions. Imported redactions are highlighted in the color configured in the 'Default colors' section of the app.",
"options": {
"all-pages": {
"description": "The earmarks in the selected HEX color will be converted on all pages of the document.",
"label": "Convert on all pages"
},
"this-page": {
"description": "The earmarks in the selected HEX color will be converted only on the current page in view.",
"description": "The earmarks in the selected HEX color will be converted only on the currently viewed page.",
"label": "Convert only on this page"
}
},
@ -1683,14 +1720,14 @@
},
"remove": {
"confirmation": "The {count} selected {count, plural, one{earmark} other{earmarks}} will be removed from the document",
"details": "Removing earmarks from the document will delete all the rectangles and leave a white background behind the highlighted text.",
"details": "Removing earmarks from the document will delete all colored rectangles and leave a white background behind the previously highlighted text.",
"options": {
"all-pages": {
"description": "The earmarks in the selected HEX color will be removed on all pages of the document.",
"label": "Remove on all pages"
},
"this-page": {
"description": "The earmarks in the selected HEX color will be removed only on the current page in view.",
"description": "The earmarks in the selected HEX color will be converted only on the currently viewed page.",
"label": "Remove only on this page"
}
},
@ -1714,7 +1751,7 @@
"details": "To apply redactions from another document, you first need to upload it.",
"http": {
"error": "Failed to import redactions! {error}",
"success": "Redactions have been imported!"
"success": "Redactions have been imported."
},
"import-only-for-pages": "Import only for pages",
"range": {
@ -1798,8 +1835,8 @@
}
},
"license-information": "License Information",
"load-all-annotations-success": "All annotations were loaded and are now visible in the document thumbnails",
"load-all-annotations-threshold-exceeded": "Caution, document contains more than {threshold} annotations. Drawing all annotations will affect the performance of the app and could even block it. Do you want to proceed?",
"load-all-annotations-success": "All annotations were loaded and are now visible in the document thumbnails.",
"load-all-annotations-threshold-exceeded": "<strong>Alert:</strong> Document contains more than {threshold} annotations. Drawing all annotations may cause the app to slow down or freeze. Do you still want to continue?",
"load-all-annotations-threshold-exceeded-checkbox": "Do not show this warning again",
"loading": "Loading",
"manual-annotation": {
@ -1837,18 +1874,18 @@
"minutes": "minutes",
"no-active-license": "Invalid or corrupt license Please contact your administrator",
"notification": {
"assign-approver": "You have been assigned as approver for <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
"assign-reviewer": "You have been assigned as reviewer for <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
"assign-approver": "You have been assigned as approver for a document. <br>Document: <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> <br>Dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>",
"assign-reviewer": "You have been assigned as reviewer for a document. <br>Document: <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> <br>Dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>",
"document-approved": " <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> has been approved!",
"dossier-deleted": "Dossier: <b>{dossierName}</b> has been deleted!",
"dossier-owner-deleted": "The owner of dossier: <b>{dossierName}</b> has been deleted!",
"dossier-owner-removed": "You have been removed as dossier owner from <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
"dossier-owner-set": "You are now the dossier owner of <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
"download-ready": "Your <b><a href=\"{downloadHref}\", target=\"_blank\">download</a></b> is ready!",
"no-data": "You currently have no notifications",
"unassigned-from-file": "You have been unassigned from <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> in dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>!",
"user-becomes-dossier-member": "You have been added to dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
"user-demoted-to-reviewer": "You have been demoted to reviewer in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
"no-data": "You currently have no notifications.",
"unassigned-from-file": "You have been unassigned from a document. <br>Document: <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> <br>Dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>",
"user-becomes-dossier-member": "You have been added to a dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>",
"user-demoted-to-reviewer": "You have been demoted to reviewer in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>",
"user-promoted-to-approver": "You have been promoted to approver in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
"user-removed-as-dossier-member": "You have been removed as a member from dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!"
},
@ -1858,7 +1895,7 @@
"in-app-notifications": "In-app notifications"
},
"error": {
"generic": "Something went wrong... Preferences update failed!"
"generic": "Error: Preferences update failed."
},
"groups": {
"document": "Document related notifications",
@ -1900,30 +1937,30 @@
"ocr": {
"confirmation-dialog": {
"cancel": "Cancel",
"question": "Manual changes could get lost if OCR makes changes at those positions. Are you sure you want to proceed?",
"question": "Manual changes may be overwritten if the OCR makes changes at the respective positions. Do you still want to proceed?",
"title": "Warning: The file contains manual changes!"
}
},
"overwrite-files-dialog": {
"archive-question": "Dossier is not empty, so files might overlap with the contents of the archive you are uploading. Choose how to proceed in case of duplicates:",
"archive-question": "Dossier already contains files. Files might overlap with the contents of the folder you are uploading. Select how to handle duplicates:",
"archive-title": "Uploading a ZIP archive",
"file-question": "<b>{filename}</b> already exists. Choose how to proceed:",
"file-title": "File already exists!",
"file-title": "File already exists.",
"options": {
"all-files": "Apply to all files of current upload",
"cancel": "Cancel upload",
"current-files": "Apply to current file",
"full-overwrite": {
"description": "Manual changes done to the existing file will be removed and you are able to start over with redactions.",
"description": "Remove all manual changes made to the file, and start reviewing a freshly processed file.",
"label": "Overwrite and start over"
},
"partial-overwrite": {
"description": "Manual changes are kept only if the affected redactions are still at the same position in the file. Some redactions could be misplaced if the content of the file changed.",
"description": "Keep manual changes if the affected redactions remain in their original positions. Some redactions could be misplaced if the content has changed.",
"label": "Overwrite and keep manual changes"
},
"proceed": "Proceed",
"skip": {
"description": "The upload will be skipped and the existing file will not be replaced.",
"description": "Skip the file upload and do not replace the existing file.",
"label": "Keep the existing file and do not overwrite"
}
},
@ -1978,7 +2015,7 @@
"form": {
"auto-expand-filters-on-action": "Auto-expand filters on my actions",
"help-mode-dialog": "Help mode activation dialog",
"load-all-annotations-warning": "Warning regarding loading all annotations at once in file preview",
"load-all-annotations-warning": "Warning regarding simultaneous loading of all annotations in thumbnails",
"open-structured-view-by-default": "Display structured component management modal by default",
"table-extraction-type": "Table extraction type"
},
@ -2115,7 +2152,7 @@
"reports-screen": {
"description": "Below, you will find a list of placeholders for dossier- and document-specific information. You can include these placeholders in your report templates.",
"descriptions": {
"dossier-attributes": "This placeholder gets replaced with the value of the dossier attribute <code>{attribute}</code>.",
"dossier-attributes": "This placeholder is replaced by the value of the dossier attribute <code>{attribute}</code>.",
"file-attributes": "This placeholder is replaced with the value of the file attribute <code>{attribute}</code>.",
"general": {
"date": {
@ -2131,7 +2168,7 @@
},
"redaction": {
"entity": {
"display-name": "This placeholder is replaced by the name of the entity the redaction is based on."
"display-name": "This placeholder is replaced by the name of the entity on which the redaction is based."
},
"excerpt": "This placeholder is replaced by a text snippet that contains the redaction.",
"is-skipped": "The skipped redaction placeholder indicates whether a redaction is skipped or not. It can be included in a separate column of a template that also contains the '{{redaction.value'}} placeholder. The placeholder is replaced by “true” if the respective redaction is skipped, and by “false” if it is redacted (i. e., not skipped).",
@ -2150,7 +2187,7 @@
}
}
},
"invalid-upload": "Invalid format selected for upload! Supported formats are XLSX and DOCX",
"invalid-upload": "Invalid upload format. Supported formats: .xlsx and .docx",
"multi-file-report": "(Multi-file)",
"report-documents": "Report documents",
"setup": "Click the upload button on the right to upload your redaction report templates.",
@ -2365,7 +2402,7 @@
"overwrite": "Overwrite"
},
"question": "Choose how to proceed:",
"title": "The dictionary already has entries!"
"title": "The dictionary already has entries."
},
"upload-file": {
"upload-area-text": "Click or drag & drop anywhere on this area..."
@ -2435,7 +2472,7 @@
},
"title": "Edit profile",
"update": {
"success": "Successfully updated profile!"
"success": "Successfully updated profile."
}
},
"user-stats": {
@ -2456,8 +2493,8 @@
},
"watermark-screen": {
"action": {
"change-success": "Watermark has been updated!",
"created-success": "Watermark has been created!",
"change-success": "Watermark has been updated.",
"created-success": "Watermark has been created.",
"error": "Failed to update watermark",
"revert": "Revert",
"save": "Save changes"
@ -2487,7 +2524,7 @@
"watermarks-listing": {
"action": {
"delete": "Delete",
"delete-success": "Watermark has been deleted!",
"delete-success": "Watermark has been deleted.",
"edit": "Edit"
},
"add-new": "New watermark",
@ -2504,7 +2541,7 @@
"table-header": {
"title": "Watermarks"
},
"watermark-is-used": "This watermark is already in use, are you sure you want to delete it?"
"watermark-is-used": "This watermark is already in use. Do you still want to delete it?"
},
"workflow": {
"selection": {

View File

@ -94,6 +94,23 @@
},
"save": "Dossier-Vorlage speichern"
},
"add-edit-component-mapping": {
"actions": {
"save": "Save mapping"
},
"dialog": {
"title": "{type, select, add{Add New} edit{Edit} other{}} Component Mapping"
},
"form": {
"delimiter": "Delimiter",
"delimiter-placeholder": "Delimiter",
"encoding-type": "Encoding type",
"file": "Mapping file",
"name": "Mapping name",
"name-placeholder": "Mapping name",
"version": "Version"
}
},
"add-edit-dossier-attribute": {
"error": {
"generic": "Attribut konnte nicht gespeichert werden!"
@ -231,6 +248,7 @@
},
"admin-side-nav": {
"audit": "Audit",
"component-mappings": "Component mappings",
"component-rule-editor": "Component rule editor",
"configurations": "Configurations",
"default-colors": "Default colors",
@ -357,6 +375,7 @@
},
"annotation-engines": {
"dictionary": "{isHint, select, true{Hint} other{Redaction}} basierend auf Wörterbuch",
"dossier-dictionary": "Annotation based on dossier dictionary",
"imported": "Annotation is imported",
"ner": "Redaktion basierend auf KI",
"rule": "Schwärzung basierend auf Regel {rule}"
@ -511,6 +530,24 @@
"value": ""
}
},
"component-mappings-screen": {
"action": {
"delete": "Delete mapping",
"edit": "Edit mapping"
},
"add-new": "New Mapping",
"bulk-actions": {
"delete": "Delete selected mappings"
},
"search": "Search by name...",
"table-col-names": {
"name": "name",
"version": "version"
},
"table-header": {
"title": "Component mapping"
}
},
"component-rules-screen": {
"error": {
"generic": "Something went wrong... Component rules update failed!"
@ -1641,7 +1678,8 @@
},
"test": {
"error": "Die Test-E-Mail konnte nicht gesendet werden! Bitte überprüfen Sie die E-Mail-Adresse.",
"success": "Die Test-E-Mail wurde erfolgreich versendet!"
"success": "Die Test-E-Mail wurde erfolgreich versendet!",
"warning": "Admin mail address not set. Test email sent to {recipientEmail} instead."
},
"title": "SMTP-Konto konfigurieren"
},
@ -2132,6 +2170,7 @@
"display-name": "This placeholder is replaced by the name of the entity the component is based on."
},
"excerpt": "Dieser Platzhalter wird durch einen Textausschnitt ersetzt, der die Schwärzung enthält.",
"is-skipped": "The skipped redaction placeholder indicates whether a redaction is skipped or not. It can be included in a separate column of a template that also contains the '{{redaction.value'}} placeholder. The placeholder is replaced by “true” if the respective redaction is skipped, and by “false” if it is redacted (i. e., not skipped).",
"justification": "Dieser Platzhalter wird durch die Begründung der Schwärzung ersetzt. Es ist eine Kombination aus dem Rechtsverweis (justificationParagraph) und dem Begründungstext (justificationReason).",
"justification-legal-basis": "This placeholder is replaced by the legal basis for the component.",
"justification-paragraph": "Dieser Platzhalter wird durch den Rechtshinweis der Begründung der Redaktion ersetzt.",
@ -2139,6 +2178,7 @@
"justification-text": "This placeholder is replaced by the justification text.",
"page": "Dieser Platzhalter wird durch die Seitenzahl der Redaktion ersetzt.",
"paragraph": "Dieser Platzhalter wird durch den Absatz ersetzt, der die Schwärzung enthält.",
"paragraph-idx": "The placeholder is replaced by the number of the paragraph containing the redaction. Paragraphs are numbered on a per-page basis.",
"value": "This placeholder is replaced by the value that was extracted."
},
"time": {

View File

@ -94,6 +94,23 @@
},
"save": "Save dossier template"
},
"add-edit-component-mapping": {
"actions": {
"save": "Save mapping"
},
"dialog": {
"title": "{type, select, add{Add New} edit{Edit} other{}} Component Mapping"
},
"form": {
"delimiter": "Delimiter",
"delimiter-placeholder": "Delimiter",
"encoding-type": "Encoding type",
"file": "Mapping file",
"name": "Mapping name",
"name-placeholder": "Mapping name",
"version": "Version"
}
},
"add-edit-dossier-attribute": {
"error": {
"generic": "Failed to save attribute!"
@ -231,6 +248,7 @@
},
"admin-side-nav": {
"audit": "Audit",
"component-mappings": "Component mappings",
"component-rule-editor": "Component rule editor",
"configurations": "Configurations",
"default-colors": "Default colors",
@ -513,6 +531,24 @@
"value": "Value"
}
},
"component-mappings-screen": {
"action": {
"delete": "Delete mapping",
"edit": "Edit mapping"
},
"add-new": "New Mapping",
"bulk-actions": {
"delete": "Delete selected mappings"
},
"search": "Search by name...",
"table-col-names": {
"name": "name",
"version": "version"
},
"table-header": {
"title": "Component mapping"
}
},
"component-rules-screen": {
"error": {
"generic": "Something went wrong... Component rules update failed!"
@ -1643,7 +1679,8 @@
},
"test": {
"error": "Test e-mail could not be sent! Please revise the e-mail address.",
"success": "Test e-mail was sent successfully!"
"success": "Test e-mail was sent successfully!",
"warning": "Admin mail address not set. Test email sent to {recipientEmail} instead."
},
"title": "Configure SMTP Account"
},

View File

@ -29,3 +29,4 @@ export * from './lib/digital-signature';
export * from './lib/watermarks';
export * from './lib/colors';
export * from './lib/component-log';
export * from './lib/component-mappings';

View File

@ -0,0 +1,16 @@
import { ComponentMapping, IComponentMapping } from './component-mapping';
export interface IComponentMappingList {
dossierTemplateId: string;
componentMappingList: IComponentMapping[];
}
export class ComponentMappingList implements IComponentMappingList {
readonly dossierTemplateId: string;
readonly componentMappingList: ComponentMapping[];
constructor(componentMappingList: IComponentMappingList) {
this.dossierTemplateId = componentMappingList.dossierTemplateId;
this.componentMappingList = componentMappingList.componentMappingList;
}
}

View File

@ -0,0 +1,38 @@
import { IListable } from '@iqser/common-ui';
export interface IComponentMapping extends IListable {
id: string;
name: string;
fileName: string;
version: number;
columnLabels: string[];
numberOfLines: number;
encoding: string;
delimiter: string;
}
export class ComponentMapping implements IComponentMapping, IListable {
readonly id: string;
readonly name: string;
readonly fileName: string;
readonly version: number;
readonly columnLabels: string[];
readonly numberOfLines: number;
readonly encoding: string;
readonly delimiter: string;
constructor(componentMapping: IComponentMapping) {
this.id = componentMapping.id;
this.name = componentMapping.name;
this.fileName = componentMapping.fileName;
this.version = componentMapping.version;
this.columnLabels = componentMapping.columnLabels;
this.numberOfLines = componentMapping.numberOfLines;
this.encoding = componentMapping.encoding;
this.delimiter = componentMapping.delimiter;
}
get searchKey(): string {
return this.name;
}
}

View File

@ -0,0 +1,2 @@
export * from './component-mapping-list.model';
export * from './component-mapping';

View File

@ -13,3 +13,10 @@ export interface ISmtpConfiguration {
starttls?: boolean;
user?: string;
}
export interface ITextConnectionResponse {
adminEmail: boolean;
reasonPhrase: string;
recipientEmail: string;
statusCode: number;
}

View File

@ -34,7 +34,7 @@
"@messageformat/core": "^3.3.0",
"@ngx-translate/core": "15.0.0",
"@ngx-translate/http-loader": "8.0.0",
"@pdftron/webviewer": "10.8.0",
"@pdftron/webviewer": "10.9.0",
"chart.js": "4.4.2",
"dayjs": "1.11.10",
"file-saver": "^2.0.5",

View File

@ -3131,10 +3131,10 @@
resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-18.2.4.tgz#8e7eb0f9c7bee12977f37ebddc935463d9251793"
integrity sha512-Y52Afz02Ub1kRZXd6NUTwPMjKQqBKZ35e5dUEpl14na2fWvdgdMz4bYOBPUcmQrovlxBGhmFXtFzxkdW3zyRbQ==
"@pdftron/webviewer@10.8.0":
version "10.8.0"
resolved "https://registry.yarnpkg.com/@pdftron/webviewer/-/webviewer-10.8.0.tgz#d19d698cb80d011acb4a9a844141bf37d186ac1f"
integrity sha512-/VPHEDTrqVEbjLTu5YIDExARXqrG6JUKtguOjvF+hlH21V465FIVw/BfZw+A0rpxSZFoTYf0Wtly5u8ZFXofng==
"@pdftron/webviewer@10.9.0":
version "10.9.0"
resolved "https://registry.yarnpkg.com/@pdftron/webviewer/-/webviewer-10.9.0.tgz#c39105189c70cfaa0601dae02e688bb510f74e3b"
integrity sha512-na6dQE1aFVc42zeRYjk0UDWKqdsI1PcQeQdAcwpNCKyND9W3s8iG8GLkZzfvP2CZjGhj47l28LkZ0NUBrq3weQ==
"@phenomnomnominal/tsquery@^4.1.1":
version "4.2.0"