Merge branch 'RED-9578' into 'master'

RED-9578: implemented the new approval modal layout.

See merge request redactmanager/red-ui!572
This commit is contained in:
Dan Percic 2024-09-19 16:58:56 +02:00
commit a51e68c3d8
24 changed files with 386 additions and 319 deletions

View File

@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { Injectable, signal } from '@angular/core';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { IConfirmationDialogData, IqserDialog, LoadingService } from '@iqser/common-ui';
import { Dossier, File, User, WorkflowFileStatus, WorkflowFileStatuses } from '@red/domain';
import { ApproveResponse, Dossier, File, User, WorkflowFileStatus, WorkflowFileStatuses } from '@red/domain';
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
import { FileManagementService } from '@services/files/file-management.service';
import { FilesService } from '@services/files/files.service';
@ -11,6 +11,7 @@ import { AssignReviewerApproverDialogComponent } from '../../shared-dossiers/dia
import { DossiersDialogService } from '../../shared-dossiers/services/dossiers-dialog.service';
import { FileAssignService } from '../../shared-dossiers/services/file-assign.service';
import { getCurrentUser } from '@common-ui/users';
import { ApproveWarningDetailsComponent } from '@shared/components/approve-warning-details/approve-warning-details.component';
@Injectable()
export class BulkActionsService {
@ -110,34 +111,33 @@ export class BulkActionsService {
}
async approve(files: File[]): Promise<void> {
const foundAnalysisRequiredFile = files.find(file => file.analysisRequired);
const foundUpdatedFile = files.find(file => file.hasUpdates);
if (foundAnalysisRequiredFile || foundUpdatedFile) {
this._dialogService.openDialog(
'confirm',
{
title: foundAnalysisRequiredFile
? _('confirmation-dialog.approve-multiple-files-without-analysis.title')
: _('confirmation-dialog.approve-multiple-files.title'),
question: foundAnalysisRequiredFile
? _('confirmation-dialog.approve-multiple-files-without-analysis.question')
: _('confirmation-dialog.approve-multiple-files.question'),
confirmationText: foundAnalysisRequiredFile
? _('confirmation-dialog.approve-multiple-files-without-analysis.confirmationText')
: null,
denyText: foundAnalysisRequiredFile ? _('confirmation-dialog.approve-multiple-files-without-analysis.denyText') : null,
} as IConfirmationDialogData,
async () => {
this._loadingService.start();
await this._filesService.setApproved(files);
this._loadingService.stop();
},
);
} else {
this._loadingService.start();
await this._filesService.setApproved(files);
this._loadingService.stop();
this._loadingService.start();
const approvalResponse: ApproveResponse[] = await this._filesService.getApproveWarnings(files);
this._loadingService.stop();
const hasWarnings = approvalResponse.some(response => response.hasWarnings);
if (!hasWarnings) {
return;
}
const fileWarnings = approvalResponse.map(response => ({ fileId: response.fileId, fileWarnings: response.fileWarnings }));
this._dialogService.openDialog(
'confirm',
{
title: _('confirmation-dialog.approve-file.title'),
question: _('confirmation-dialog.approve-file.question'),
translateParams: { questionLength: files.length },
confirmationText: _('confirmation-dialog.approve-file.confirmationText'),
denyText: _('confirmation-dialog.approve-file.denyText'),
component: ApproveWarningDetailsComponent,
componentInputs: { data: signal(fileWarnings), files: signal(files) },
cancelButtonPrimary: true,
} as IConfirmationDialogData,
async () => {
this._loadingService.start();
await this._filesService.setApproved(files);
this._loadingService.stop();
},
);
}
assign(files: File[]): void {

View File

@ -1,14 +1,17 @@
<table>
<thead>
<tr>
<th *ngFor="let column of columns" [ngClass]="{ hide: !column.show, 'w-50': staticColumns }">
<th *ngFor="let column of columns()" [ngClass]="{ hide: !!column.hide, 'w-50': staticColumns() && shouldApplyHalfWidth() }">
<label>{{ column.label }}</label>
</th>
</tr>
</thead>
<tbody [ngStyle]="{ height: redactedTextsAreaHeight + 'px' }">
<tr *ngFor="let row of data">
<td *ngFor="let cell of row" [ngClass]="{ hide: !cell.show, bold: cell.bold, 'w-50': staticColumns }">
<tbody [ngStyle]="{ height: redactedTextsAreaHeight() + 'px' }">
<tr *ngFor="let row of data()">
<td
*ngFor="let cell of row"
[ngClass]="{ hide: !!cell.hide, bold: cell.bold, 'w-50': staticColumns() && shouldApplyHalfWidth() }"
>
{{ cell.label }}
</td>
</tr>

View File

@ -27,7 +27,7 @@ table {
th,
td {
&:not(.w-50) {
&:first-child:not(.w-50) {
width: 25%;
}
max-width: 0;

View File

@ -1,9 +1,9 @@
import { Component, Input } from '@angular/core';
import { Component, computed, input } from '@angular/core';
import { NgClass, NgForOf, NgStyle } from '@angular/common';
export interface ValueColumn {
label: string;
show: boolean;
hide?: boolean;
bold?: boolean;
}
@ -18,11 +18,12 @@ const MAX_ITEMS_DISPLAY = 10;
styleUrl: './selected-annotations-table.component.scss',
})
export class SelectedAnnotationsTableComponent {
@Input({ required: true }) columns: ValueColumn[];
@Input({ required: true }) data: ValueColumn[][];
@Input() staticColumns = false;
readonly columns = input.required<ValueColumn[]>();
readonly data = input.required<ValueColumn[][]>();
readonly staticColumns = input(false);
get redactedTextsAreaHeight() {
return this.data.length <= MAX_ITEMS_DISPLAY ? TABLE_ROW_SIZE * this.data.length : TABLE_ROW_SIZE * MAX_ITEMS_DISPLAY;
}
readonly redactedTextsAreaHeight = computed(() =>
this.data().length <= MAX_ITEMS_DISPLAY ? TABLE_ROW_SIZE * this.data().length : TABLE_ROW_SIZE * MAX_ITEMS_DISPLAY,
);
readonly shouldApplyHalfWidth = computed(() => this.columns().filter(column => !column.hide).length === 2);
}

View File

@ -77,19 +77,10 @@ export class EditRedactionDialogComponent
readonly isRedacted = this.annotations.every(annotation => annotation.isRedacted);
readonly isImported: boolean = this.annotations.every(annotation => annotation.imported);
readonly allRectangles = this.annotations.reduce((acc, a) => acc && a.AREA, true);
readonly tableColumns = [
{
label: 'Value',
show: true,
},
{
label: 'Type',
show: true,
},
];
readonly tableColumns: ValueColumn[] = [{ label: 'Value' }, { label: 'Type' }];
readonly tableData: ValueColumn[][] = this.data.annotations.map(redaction => [
{ label: redaction.value, show: true, bold: true },
{ label: redaction.typeLabel, show: true },
{ label: redaction.value, bold: true },
{ label: redaction.typeLabel },
]);
options: DetailsRadioOption<RedactOrHintOption>[] | undefined;
legalOptions: LegalBasisOption[] = [];

View File

@ -60,19 +60,10 @@ const DOCUMINE_LEGAL_BASIS = 'n-a.';
export class ForceAnnotationDialogComponent extends BaseDialogComponent implements OnInit {
readonly isDocumine = getConfig().IS_DOCUMINE;
readonly tableColumns = [
{
label: 'Value',
show: true,
},
{
label: 'Type',
show: true,
},
];
readonly tableColumns: ValueColumn[] = [{ label: 'Value' }, { label: 'Type' }];
readonly tableData: ValueColumn[][] = this._data.annotations.map(redaction => [
{ label: redaction.value, show: true, bold: true },
{ label: redaction.typeLabel, show: true },
{ label: redaction.value, bold: true },
{ label: redaction.typeLabel },
]);
legalOptions: LegalBasisOption[] = [];

View File

@ -69,19 +69,10 @@ export class RedactRecommendationDialogComponent
reason: [null],
});
readonly tableColumns = [
{
label: 'Value',
show: true,
},
{
label: 'Type',
show: true,
},
];
readonly tableColumns: ValueColumn[] = [{ label: 'Value' }, { label: 'Type' }];
readonly tableData: ValueColumn[][] = this.data.annotations.map(redaction => [
{ label: redaction.value, show: true, bold: true },
{ label: redaction.typeLabel, show: true },
{ label: redaction.value, bold: true },
{ label: redaction.typeLabel },
]);
constructor(

View File

@ -105,25 +105,19 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent<
readonly selectedOption = toSignal(this.form.get('option').valueChanges.pipe(map(value => value.value)));
readonly isFalsePositive = computed(() => this.selectedOption() === RemoveRedactionOptions.FALSE_POSITIVE);
readonly tableColumns = computed<ValueColumn[]>(() => [
{
label: 'Value',
show: true,
},
{
label: 'Type',
show: true,
},
{ label: 'Value' },
{ label: 'Type' },
{
label: 'Context',
show: this.isFalsePositive(),
hide: !this.isFalsePositive(),
},
]);
readonly tableData = computed<ValueColumn[][]>(() =>
this.data.redactions.map((redaction, index) => [
{ label: redaction.value, show: true, bold: true },
{ label: redaction.typeLabel, show: true },
{ label: this.data.falsePositiveContext[index], show: this.isFalsePositive() },
{ label: redaction.value, bold: true },
{ label: redaction.typeLabel },
{ label: this.data.falsePositiveContext[index], hide: !this.isFalsePositive() },
]),
);

View File

@ -1,4 +1,4 @@
import { ChangeDetectorRef, Component, HostBinding, Injector, Input, OnChanges, Optional, ViewChild } from '@angular/core';
import { ChangeDetectorRef, Component, HostBinding, Injector, Input, OnChanges, Optional, signal, ViewChild } from '@angular/core';
import { toObservable } from '@angular/core/rxjs-interop';
import { Router } from '@angular/router';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
@ -13,7 +13,7 @@ import {
} from '@iqser/common-ui';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { IqserTooltipPositions } from '@iqser/common-ui/lib/utils';
import { Action, ActionTypes, Dossier, File, ProcessingFileStatuses, User } from '@red/domain';
import { Action, ActionTypes, ApproveResponse, Dossier, File, ProcessingFileStatuses, User } from '@red/domain';
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
import { FileManagementService } from '@services/files/file-management.service';
@ -36,6 +36,7 @@ import { FileAssignService } from '../../services/file-assign.service';
import { ProcessingIndicatorComponent } from '@shared/components/processing-indicator/processing-indicator.component';
import { StatusBarComponent } from '@common-ui/shared';
import { NgIf, NgTemplateOutlet } from '@angular/common';
import { ApproveWarningDetailsComponent } from '@shared/components/approve-warning-details/approve-warning-details.component';
@Component({
selector: 'redaction-file-actions',
@ -302,20 +303,22 @@ export class FileActionsComponent implements OnChanges {
}
async setFileApproved() {
if (!this.file.analysisRequired && !this.file.hasUpdates) {
await this.#setFileApproved();
this._loadingService.start();
const approvalResponse: ApproveResponse = (await this._filesService.getApproveWarnings([this.file]))[0];
this._loadingService.stop();
if (!approvalResponse.hasWarnings) {
return;
}
const data: IConfirmationDialogData = {
title: this.file.analysisRequired
? _('confirmation-dialog.approve-file-without-analysis.title')
: _('confirmation-dialog.approve-file.title'),
question: this.file.analysisRequired
? _('confirmation-dialog.approve-file-without-analysis.question')
: _('confirmation-dialog.approve-file.question'),
confirmationText: this.file.analysisRequired ? _('confirmation-dialog.approve-file-without-analysis.confirmationText') : null,
denyText: this.file.analysisRequired ? _('confirmation-dialog.approve-file-without-analysis.denyText') : null,
title: _('confirmation-dialog.approve-file.title'),
question: _('confirmation-dialog.approve-file.question'),
translateParams: { questionLength: 1 },
confirmationText: _('confirmation-dialog.approve-file.confirmationText'),
denyText: _('confirmation-dialog.approve-file.denyText'),
component: ApproveWarningDetailsComponent,
componentInputs: { data: signal([approvalResponse]), files: signal([this.file]) },
cancelButtonPrimary: true,
};
this._dialogService.openDialog('confirm', data, () => this.#setFileApproved());

View File

@ -0,0 +1,9 @@
<div class="scrollable">
@for (file of data(); track file) {
<redaction-warning-details-panel
[warnings]="file.fileWarnings"
[filename]="fileNamesByIds()[file.fileId]"
[openByDefault]="shouldPanelOpenDefault()"
></redaction-warning-details-panel>
}
</div>

View File

@ -0,0 +1,10 @@
@use 'common-mixins';
.scrollable {
overflow-y: auto;
max-height: calc(5 * 50px);
@include common-mixins.scroll-bar;
padding-left: 2px;
padding-right: 11px;
}

View File

@ -0,0 +1,31 @@
import { Component, computed, input } from '@angular/core';
import { ApproveResponse, File } from '@red/domain';
import { SelectedAnnotationsTableComponent } from '../../../file-preview/components/selected-annotations-table/selected-annotations-table.component';
import { MatExpansionPanel, MatExpansionPanelHeader } from '@angular/material/expansion';
import { KeyValuePipe, NgStyle } from '@angular/common';
import { WarningDetailsPanelComponent } from '@shared/components/warning-details-panel/warning-details-panel.component';
import { CdkFixedSizeVirtualScroll, CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
@Component({
selector: 'redaction-approve-warning-details',
standalone: true,
imports: [
SelectedAnnotationsTableComponent,
MatExpansionPanel,
MatExpansionPanelHeader,
KeyValuePipe,
WarningDetailsPanelComponent,
CdkVirtualScrollViewport,
CdkFixedSizeVirtualScroll,
NgStyle,
],
templateUrl: './approve-warning-details.component.html',
styleUrl: './approve-warning-details.component.scss',
})
export class ApproveWarningDetailsComponent {
readonly data = input.required<ApproveResponse[]>();
readonly files = input.required<File[]>();
readonly fileNamesByIds = computed(() => this.files().reduce((acc, file) => ({ ...acc, [file.id]: file.filename }), {}));
readonly shouldPanelOpenDefault = computed(() => this.files().length === 1);
}

View File

@ -0,0 +1,8 @@
<mat-expansion-panel [expanded]="openByDefault()" togglePosition="before">
<mat-expansion-panel-header>{{ filename() }}</mat-expansion-panel-header>
<redaction-selected-annotations-table
[columns]="tableColumns()"
[data]="tableData()"
[staticColumns]="true"
></redaction-selected-annotations-table>
</mat-expansion-panel>

View File

@ -0,0 +1,4 @@
mat-expansion-panel {
margin-bottom: 8px;
max-width: 100%;
}

View File

@ -0,0 +1,37 @@
import { Component, computed, inject, input } from '@angular/core';
import {
SelectedAnnotationsTableComponent,
ValueColumn,
} from '../../../file-preview/components/selected-annotations-table/selected-annotations-table.component';
import { WarningModel } from '@red/domain';
import { MatExpansionPanel, MatExpansionPanelHeader } from '@angular/material/expansion';
import { approvalWarningReasonTranslations } from '@translations/approval-warning-reason-translations';
import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'redaction-warning-details-panel',
standalone: true,
imports: [MatExpansionPanel, MatExpansionPanelHeader, SelectedAnnotationsTableComponent],
templateUrl: './warning-details-panel.component.html',
styleUrl: './warning-details-panel.component.scss',
})
export class WarningDetailsPanelComponent {
readonly #translateService = inject(TranslateService);
readonly warnings = input<WarningModel[]>();
readonly filename = input<string>();
readonly openByDefault = input<boolean>();
readonly tableColumns = computed<ValueColumn[]>(() => [
{ label: 'Value' },
{ label: 'Type' },
{ label: 'Page' },
{ label: 'Warning Reason' },
]);
readonly tableData = computed<ValueColumn[][]>(() =>
this.warnings().map(warning => [
{ label: warning.value, bold: true },
{ label: warning.type },
{ label: warning.pages.join(',') },
{ label: this.#translateService.instant(approvalWarningReasonTranslations[warning.warningType]) },
]),
);
}

View File

@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { EntitiesService, isArray, QueryParam } from '@iqser/common-ui';
import { List, mapEach } from '@iqser/common-ui/lib/utils';
import { File, IFile } from '@red/domain';
import { ApproveResponse, File, IFile } from '@red/domain';
import { UserService } from '@users/user.service';
import { NGXLogger } from 'ngx-logger';
import { firstValueFrom } from 'rxjs';
@ -70,7 +70,13 @@ export class FilesService extends EntitiesService<IFile, File> {
async setApproved(files: File | List<File>) {
const _files = asList(files);
return this.#makePost(_files, `${this._defaultModelPath}/approved/${_files[0].dossierId}/bulk`);
return this.#makePost(_files, `${this._defaultModelPath}/approved/${_files[0].dossierId}/bulk`, [{ key: 'force', value: true }]);
}
async getApproveWarnings(files: File[]) {
const filesIds = files.map(file => file.id);
const url = `${this._defaultModelPath}/approved/${files[0].dossierId}/bulk`;
return await firstValueFrom<ApproveResponse[]>(this._post(filesIds, url));
}
async setUnderReview(files: File | List<File>) {

View File

@ -0,0 +1,8 @@
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { WarningType } from '@red/domain';
export const approvalWarningReasonTranslations: Record<string, string> = {
[WarningType.PENDING_CHANGE]: _('confirmation-dialog.approve-file.warning-reason.pending-changes'),
[WarningType.LEGAL_BASIS_MISSING]: _('confirmation-dialog.approve-file.warning-reason.legal-basis-missing'),
[WarningType.UNMAPPED_JUSTIFICATION]: _('confirmation-dialog.approve-file.warning-reason.unmapped-justification'),
};

View File

@ -242,7 +242,6 @@
"label": "Nur hier hinzufügen"
}
},
"selected-text": "Ausgewählter Text:",
"type": "Typ",
"type-placeholder": "Typ auswählen..."
},
@ -276,9 +275,6 @@
"watermarks": "Wasserzeichen"
},
"analysis-disabled": "",
"annotation": {
"pending": "(Analyse steht aus)"
},
"annotation-actions": {
"accept-recommendation": {
"label": "Empfehlung annehmen"
@ -334,14 +330,14 @@
"error": "Rekategorisierung des Bilds fehlgeschlagen: {error}",
"success": "Bild wurde einer neuen Kategorie zugeordnet."
},
"remove": {
"error": "Entfernen der Schwärzung fehlgeschlagen: {error}",
"success": "Schwärzung wurde entfernt"
},
"remove-hint": {
"error": "Entfernen des Hinweises fehlgeschlagen: {error}",
"success": "Hinweis wurde entfernt"
},
"remove": {
"error": "Entfernen der Schwärzung fehlgeschlagen: {error}",
"success": "Schwärzung wurde entfernt"
},
"undo": {
"error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}",
"success": "Rücksetzung erfolgreich"
@ -354,15 +350,15 @@
"remove-highlights": {
"label": "Ausgewählte Markierungen entfernen"
},
"resize": {
"label": "Größe ändern"
},
"resize-accept": {
"label": "Neue Größe speichern"
},
"resize-cancel": {
"label": "Größenänderung abbrechen"
},
"resize": {
"label": "Größe ändern"
},
"see-references": {
"label": "Referenzen anzeigen"
},
@ -396,6 +392,9 @@
"skipped": "Ignorierte Schwärzung",
"text-highlight": "Markierung"
},
"annotation": {
"pending": "(Analyse steht aus)"
},
"annotations": "Annotationen",
"archived-dossiers-listing": {
"no-data": {
@ -640,24 +639,15 @@
},
"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": {
"confirmationText": "Ohne Analyse freigeben",
"denyText": "Abbrechen",
"question": "Analyse zur Erkennung neuer Schwärzungen erforderlich.",
"title": "Warnung!"
},
"approve-multiple-files": {
"question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen, die im Zuge einer Reanalyse hinzugefügt wurden.<br><br>Möchen Sie die Dateien wirklich freigeben?",
"title": "Warnung!"
},
"approve-multiple-files-without-analysis": {
"confirmationText": "Ohne Analyse freigeben",
"denyText": "Abbrechen",
"question": "Für mindestens eine Datei ist ein Analyselauf zur Erkennung neuer Schwärzungen erforderlich.",
"title": "Warnung"
"confirmationText": "Approve anyway",
"denyText": "No, cancel",
"question": "Do you still want to approve the {questionLength, plural, one{document} other{documents}}?",
"title": "Approval warning",
"warning-reason": {
"legal-basis-missing": "Legal basis missing",
"pending-changes": "Pending Changes",
"unmapped-justification": "Unmapped justification"
}
},
"assign-file-to-me": {
"question": {
@ -1028,13 +1018,13 @@
"recent": "Neu ({hours} h)",
"unassigned": "Keinem Bearbeiter zugewiesen"
},
"reanalyse": {
"action": "Datei analysieren"
},
"reanalyse-dossier": {
"error": "Einplanung der Dateien für die Reanalyse fehlgeschlagen. Bitte versuchen Sie es noch einmal.",
"success": "Dateien für Reanalyse vorgesehen."
},
"reanalyse": {
"action": "Datei analysieren"
},
"report-download": "",
"start-auto-analysis": "Auto-Analyse aktivieren",
"stop-auto-analysis": "Auto-Analyse anhalten",
@ -1104,14 +1094,6 @@
"total-documents": "Dokumente",
"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": {
"action": {
"clone": "Vorlage klonen",
@ -1146,6 +1128,14 @@
"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": {
"heading": "Wasserzeichen auf Dokumenten",
"no-watermark": "Kein Wasserzeichen in der Dossier-Vorlage verfügbar:<br>Bitten Sie Ihren Admin, eines zu konfigurieren.",
@ -1341,15 +1331,6 @@
"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": {
"error": {
"generic": "Fehler: Aktualisierung der Entitätsregeln fehlgeschlagen."
@ -1363,19 +1344,28 @@
"title": "Entitätsregeln-Editor",
"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": {
"deleted-entity": {
"dossier": {
"action": "Zurück zur Übersicht",
"label": "Dieses Dossier wurde gelöscht!"
},
"file": {
"action": "Zurück zum Dossier",
"label": "Diese Datei wurde gelöscht!"
},
"file-dossier": {
"action": "Zurück zur Übersicht",
"label": "Das Dossier dieser Datei wurde gelöscht!"
},
"file": {
"action": "Zurück zum Dossier",
"label": "Diese Datei wurde gelöscht!"
}
},
"file-preview": {
@ -1393,12 +1383,6 @@
},
"exact-date": "{day}. {month} {year} um {hour}:{minute} Uhr",
"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": {
"ascii": "ASCII",
"iso": "ISO-8859-1",
@ -1409,6 +1393,12 @@
"number": "Nummer",
"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": {
"cancel": "Abbrechen",
"form": {
@ -1626,15 +1616,6 @@
"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-options": "Filteroptionen",
"filter-types": "Filter",
@ -1644,6 +1625,15 @@
"unseen-pages": "Nur Annotationen auf ungesehenen Seiten",
"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": {
"assigned-people": "Bearbeiter",
"documents-status": "Dokumentenstatus",
@ -1922,13 +1912,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-removed-as-dossier-member": "<b>{user}</b> wurde als Mitglied von: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> entfernt!"
},
"notifications": {
"button-text": "Benachrichtigungen",
"deleted-dossier": "Gelöschtes Dossier",
"label": "Benachrichtigungen",
"mark-all-as-read": "Alle als gelesen markieren",
"mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren"
},
"notifications-screen": {
"category": {
"email-notifications": "E-Mail-Benachrichtigungen",
@ -1942,6 +1925,7 @@
"dossier": "Benachrichtigungen zu Dossiers",
"other": "Andere Benachrichtigungen"
},
"options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten",
"options": {
"ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen werde",
"ASSIGN_REVIEWER": "Wenn ich einem Dokument als Prüfer zugewiesen werde",
@ -1959,7 +1943,6 @@
"USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde",
"USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere"
},
"options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten",
"schedule": {
"daily": "Tägliche Zusammenfassung",
"instant": "Sofort",
@ -1967,6 +1950,13 @@
},
"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": {
"confirmation-dialog": {
"cancel": "Abbrechen",
@ -2058,16 +2048,16 @@
"warnings-label": "Dialoge und Meldungen",
"warnings-subtitle": "„Nicht mehr anzeigen“-Optionen"
},
"processing": {
"basic": "Verarbeitung läuft",
"ocr": "OCR"
},
"processing-status": {
"ocr": "OCR",
"pending": "Ausstehend",
"processed": "Verarbeitet",
"processing": "Verarbeitung läuft"
},
"processing": {
"basic": "Verarbeitung läuft",
"ocr": "OCR"
},
"readonly": "Lesemodus",
"readonly-archived": "Lesemodus (archiviert)",
"redact-text": {
@ -2303,12 +2293,6 @@
"red-user-admin": "Benutzeradmin",
"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": {
"cols": {
"assignee": "Bearbeiter",
@ -2332,6 +2316,12 @@
"no-match": "Der Suchbegriff wurde in keinem der Dokumente gefunden.",
"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",
"size": "Größe",
"smtp-auth-config": {
@ -2587,4 +2577,4 @@
}
},
"yesterday": "Gestern"
}
}

View File

@ -242,7 +242,6 @@
"label": "Add hint only here"
}
},
"selected-text": "Selected text:",
"type": "Type",
"type-placeholder": "Select type..."
},
@ -639,25 +638,16 @@
"warning": "Warning: This action cannot be undone!"
},
"confirmation-dialog": {
"approve-file-without-analysis": {
"confirmationText": "Approve without analysis",
"denyText": "Cancel",
"question": "Analysis required to detect new redactions.",
"title": "Warning!"
},
"approve-file": {
"question": "This document contains unseen changes that have been added during the reanalysis.<br><br>Do you still want to approve it?",
"title": "Warning!"
},
"approve-multiple-files-without-analysis": {
"confirmationText": "Approve without analysis",
"denyText": "Cancel",
"question": "Analysis required to detect new redactions for at least one file.",
"title": "Warning"
},
"approve-multiple-files": {
"question": "At least one of the selected files contains unseen changes that have been added during the reanalysis.<br><br>Do you still want to approve them?",
"title": "Warning!"
"confirmationText": "Approve anyway",
"denyText": "No, cancel",
"question": "Do you still want to approve the {questionLength, plural, one{document} other{documents}}?",
"title": "Approval warning",
"warning-reason": {
"legal-basis-missing": "Legal basis missing",
"pending-changes": "Pending Changes",
"unmapped-justification": "Unmapped justification"
}
},
"assign-file-to-me": {
"question": {
@ -2587,4 +2577,4 @@
}
},
"yesterday": "Yesterday"
}
}

View File

@ -242,7 +242,6 @@
"label": "Add hint only here"
}
},
"selected-text": "Selected text:",
"type": "Type",
"type-placeholder": "Select type..."
},
@ -276,9 +275,6 @@
"watermarks": "Watermarks"
},
"analysis-disabled": "Analysis disabled",
"annotation": {
"pending": "(Pending analysis)"
},
"annotation-actions": {
"accept-recommendation": {
"label": "Empfehlung annehmen"
@ -334,14 +330,14 @@
"error": "Rekategorisierung des Bildes gescheitert: {error}",
"success": "Bild wurde einer neuen Kategorie zugeordnet."
},
"remove": {
"error": "Fehler beim Entfernen der Schwärzung: {error}",
"success": "Schwärzung entfernt!"
},
"remove-hint": {
"error": "Failed to remove hint: {error}",
"success": "Hint removed!"
},
"remove": {
"error": "Fehler beim Entfernen der Schwärzung: {error}",
"success": "Schwärzung entfernt!"
},
"undo": {
"error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}",
"success": "erfolgreich Rückgängig gemacht"
@ -354,15 +350,15 @@
"remove-highlights": {
"label": "Remove selected earmarks"
},
"resize": {
"label": "Größe ändern"
},
"resize-accept": {
"label": "Größe speichern"
},
"resize-cancel": {
"label": "Größenänderung abbrechen"
},
"resize": {
"label": "Größe ändern"
},
"see-references": {
"label": "See references"
},
@ -396,6 +392,9 @@
"skipped": "Übersprungen",
"text-highlight": "Earmark"
},
"annotation": {
"pending": "(Pending analysis)"
},
"annotations": "Annotations",
"archived-dossiers-listing": {
"no-data": {
@ -640,24 +639,15 @@
},
"confirmation-dialog": {
"approve-file": {
"question": "Dieses Dokument enthält ungesehene Änderungen. Möchten Sie es trotzdem genehmigen?",
"title": "Warnung!"
},
"approve-file-without-analysis": {
"confirmationText": "Approve without analysis",
"denyText": "Cancel",
"question": "Analysis required to detect new components.",
"title": "Warning!"
},
"approve-multiple-files": {
"question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen. Möchten Sie sie trotzdem genehmigen?",
"title": "Warnung!"
},
"approve-multiple-files-without-analysis": {
"confirmationText": "Approve without analysis",
"denyText": "Cancel",
"question": "Analysis required to detect new components for at least one file.",
"title": "Warning"
"confirmationText": "Approve anyway",
"denyText": "No, cancel",
"question": "Do you still want to approve the {questionLength, plural, one{document} other{documents}}?",
"title": "Approval warning",
"warning-reason": {
"legal-basis-missing": "Legal basis missing",
"pending-changes": "Pending Changes",
"unmapped-justification": "Unmapped justification"
}
},
"assign-file-to-me": {
"question": {
@ -1028,13 +1018,13 @@
"recent": "Neu ({hours} h)",
"unassigned": "Niemandem zugewiesen"
},
"reanalyse": {
"action": "Datei analysieren"
},
"reanalyse-dossier": {
"error": "Die Dateien konnten nicht für eine Reanalyse eingeplant werden. Bitte versuchen Sie es erneut.",
"success": "Dateien für Reanalyse vorgesehen."
},
"reanalyse": {
"action": "Datei analysieren"
},
"report-download": "Report download",
"start-auto-analysis": "Enable auto-analysis",
"stop-auto-analysis": "Stop auto-analysis",
@ -1104,14 +1094,6 @@
"total-documents": "Anzahl der Dokumente",
"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": {
"action": {
"clone": "Clone template",
@ -1146,6 +1128,14 @@
"title": "{length} dossier {length, plural, one{template} other{templates}}"
}
},
"dossier-templates": {
"label": "Dossier-Vorlagen",
"status": {
"active": "Active",
"inactive": "Inactive",
"incomplete": "Incomplete"
}
},
"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.",
@ -1341,15 +1331,6 @@
"title": "{length} {length, plural, one{entity} other{entities}}"
}
},
"entity": {
"info": {
"actions": {
"revert": "Revert",
"save": "Save changes"
},
"heading": "Edit entity"
}
},
"entity-rules-screen": {
"error": {
"generic": "Something went wrong... Entity rules update failed!"
@ -1363,19 +1344,28 @@
"title": "Entity rule editor",
"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": {
"deleted-entity": {
"dossier": {
"action": "Zurück zur Übersicht",
"label": "Dieses Dossier wurde gelöscht!"
},
"file": {
"action": "Zurück zum Dossier",
"label": "Diese Datei wurde gelöscht!"
},
"file-dossier": {
"action": "Zurück zur Übersicht",
"label": "Das Dossier dieser Datei wurde gelöscht!"
},
"file": {
"action": "Zurück zum Dossier",
"label": "Diese Datei wurde gelöscht!"
}
},
"file-preview": {
@ -1393,12 +1383,6 @@
},
"exact-date": "{day} {month} {year} um {hour}:{minute} Uhr",
"file": "Datei",
"file-attribute": {
"update": {
"error": "Failed to update file attribute value!",
"success": "File attribute value has been updated successfully!"
}
},
"file-attribute-encoding-types": {
"ascii": "ASCII",
"iso": "ISO-8859-1",
@ -1409,6 +1393,12 @@
"number": "Nummer",
"text": "Freier Text"
},
"file-attribute": {
"update": {
"error": "Failed to update file attribute value!",
"success": "File attribute value has been updated successfully!"
}
},
"file-attributes-configurations": {
"cancel": "Cancel",
"form": {
@ -1626,15 +1616,6 @@
"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-options": "Filteroptionen",
"filter-types": "Filter",
@ -1644,6 +1625,15 @@
"unseen-pages": "Nur Anmerkungen auf unsichtbaren Seiten",
"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": {
"assigned-people": "Beauftragt",
"documents-status": "Documents state",
@ -1922,13 +1912,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-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": {
"category": {
"email-notifications": "E-Mail Benachrichtigungen",
@ -1942,6 +1925,7 @@
"dossier": "Dossierbezogene Benachrichtigungen",
"other": "Andere Benachrichtigungen"
},
"options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten",
"options": {
"ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen bin",
"ASSIGN_REVIEWER": "Wenn ich einem Dokument als Überprüfer zugewiesen bin",
@ -1959,7 +1943,6 @@
"USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde",
"USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere"
},
"options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten",
"schedule": {
"daily": "Tägliche Zusammenfassung",
"instant": "Sofortig",
@ -1967,6 +1950,13 @@
},
"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": {
"confirmation-dialog": {
"cancel": "Cancel",
@ -2058,16 +2048,16 @@
"warnings-label": "Prompts and dialogs",
"warnings-subtitle": "Do not show again options"
},
"processing": {
"basic": "Processing",
"ocr": "OCR"
},
"processing-status": {
"ocr": "OCR",
"pending": "Pending",
"processed": "Processed",
"processing": "Processing"
},
"processing": {
"basic": "Processing",
"ocr": "OCR"
},
"readonly": "Lesemodus",
"readonly-archived": "Read only (archived)",
"redact-text": {
@ -2303,12 +2293,6 @@
"red-user-admin": "Benutzer-Admin",
"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": {
"cols": {
"assignee": "Bevollmächtigter",
@ -2332,6 +2316,12 @@
"no-match": "Keine Dokumente entsprechen Ihren aktuellen Filtern.",
"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",
"size": "Size",
"smtp-auth-config": {
@ -2587,4 +2577,4 @@
}
},
"yesterday": "Gestern"
}
}

View File

@ -242,7 +242,6 @@
"label": "Add hint only here"
}
},
"selected-text": "Selected text:",
"type": "Type",
"type-placeholder": "Select type..."
},
@ -639,25 +638,16 @@
"warning": "Warning: this cannot be undone!"
},
"confirmation-dialog": {
"approve-file-without-analysis": {
"confirmationText": "Approve without analysis",
"denyText": "Cancel",
"question": "Analysis required to detect new components.",
"title": "Warning!"
},
"approve-file": {
"question": "This document has unseen changes, do you wish to approve it anyway?",
"title": "Warning!"
},
"approve-multiple-files-without-analysis": {
"confirmationText": "Approve without analysis",
"denyText": "Cancel",
"question": "Analysis required to detect new components for at least one file.",
"title": "Warning"
},
"approve-multiple-files": {
"question": "At least one of the files you selected has unseen changes, do you wish to approve them anyway?",
"title": "Warning!"
"confirmationText": "Approve anyway",
"denyText": "No, cancel",
"question": "Do you still want to approve the {questionLength, plural, one{document} other{documents}}?",
"title": "Approval warning",
"warning-reason": {
"legal-basis-missing": "Legal basis missing",
"pending-changes": "Pending Changes",
"unmapped-justification": "Unmapped justification"
}
},
"assign-file-to-me": {
"question": {
@ -2587,4 +2577,4 @@
}
},
"yesterday": "Yesterday"
}
}

@ -1 +1 @@
Subproject commit 2faecb44a926f02a6d4186e58751ac615f2bfd47
Subproject commit c71a4995a63e4886bc23a8a8cea7d02d7560c2aa

View File

@ -0,0 +1,19 @@
export interface ApproveResponse {
readonly fileId: string;
readonly hasWarnings?: boolean;
readonly fileWarnings: WarningModel[];
}
export interface WarningModel {
id: string;
value: string;
pages: number[];
type: string;
warningType: WarningType;
}
export enum WarningType {
PENDING_CHANGE = 'PENDING_CHANGE',
LEGAL_BASIS_MISSING = 'LEGAL_BASIS_MISSING',
UNMAPPED_JUSTIFICATION = 'UNMAPPED_JUSTIFICATION',
}

View File

@ -4,3 +4,4 @@ export * from './types';
export * from './file-upload-result';
export * from './overwrite-file-options';
export * from './super-types';
export * from './approve-file-types';