Merge branch 'master' into VM/RED-7340
This commit is contained in:
commit
af17c026ff
@ -9,7 +9,7 @@
|
||||
|
||||
.container {
|
||||
padding: 32px;
|
||||
width: 900px;
|
||||
width: 1000px;
|
||||
max-width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@ -26,6 +26,12 @@ import {
|
||||
} from '@red/domain';
|
||||
import { annotationTypesTranslations } from '@translations/annotation-types-translations';
|
||||
|
||||
interface AnnotationContent {
|
||||
translation: string;
|
||||
params: { [key: string]: string };
|
||||
untranslatedContent: string;
|
||||
}
|
||||
|
||||
export class AnnotationWrapper implements IListable {
|
||||
id: string;
|
||||
superType: SuperType;
|
||||
@ -36,7 +42,7 @@ export class AnnotationWrapper implements IListable {
|
||||
numberOfComments = 0;
|
||||
firstTopLeftPoint: IPoint;
|
||||
shortContent: string;
|
||||
content: string;
|
||||
content: AnnotationContent;
|
||||
value: string;
|
||||
pageNumber: number;
|
||||
dictionaryOperation = false;
|
||||
@ -279,7 +285,7 @@ export class AnnotationWrapper implements IListable {
|
||||
);
|
||||
|
||||
const content = this.#createContent(annotationWrapper, logEntry, isDocumine);
|
||||
annotationWrapper.shortContent = this.#getShortContent(annotationWrapper, legalBasisList) || content;
|
||||
annotationWrapper.shortContent = this.#getShortContent(annotationWrapper, legalBasisList) || content.untranslatedContent;
|
||||
annotationWrapper.content = content;
|
||||
|
||||
const lastRelevantManualChange = logEntry.manualChanges?.at(-1);
|
||||
@ -311,39 +317,57 @@ export class AnnotationWrapper implements IListable {
|
||||
}
|
||||
|
||||
static #createContent(annotationWrapper: AnnotationWrapper, logEntry: IEntityLogEntry, isDocumine: boolean) {
|
||||
let content = '';
|
||||
let untranslatedContent = '';
|
||||
const params: { [key: string]: string } = {};
|
||||
if (logEntry.matchedRule) {
|
||||
content += `Rule ${logEntry.matchedRule} matched${isDocumine ? ':' : ''} \n\n`;
|
||||
params['hasRule'] = 'true';
|
||||
params['matchedRule'] = logEntry.matchedRule.replace(/(^[, ]*)|([, ]*$)/g, '');
|
||||
params['ruleSymbol'] = isDocumine ? ':' : '';
|
||||
|
||||
untranslatedContent += `Rule ${logEntry.matchedRule} matched${isDocumine ? ':' : ''} \n\n`;
|
||||
}
|
||||
|
||||
if (logEntry.reason) {
|
||||
params['hasReason'] = 'true';
|
||||
if (isDocumine && logEntry.reason.slice(-1) === '.') {
|
||||
logEntry.reason = logEntry.reason.slice(0, -1);
|
||||
}
|
||||
|
||||
content += logEntry.reason + '\n\n';
|
||||
if (!params['hasRule']) {
|
||||
params['reason'] = logEntry.reason.substring(0, 1).toUpperCase() + logEntry.reason.substring(1);
|
||||
} else {
|
||||
params['reason'] = logEntry.reason;
|
||||
}
|
||||
params['reason'] = params['reason'].replace(/(^[, ]*)|([, ]*$)/g, '');
|
||||
untranslatedContent += logEntry.reason + '\n\n';
|
||||
//remove leading and trailing commas and whitespaces
|
||||
content = content.replace(/(^[, ]*)|([, ]*$)/g, '');
|
||||
content = content.substring(0, 1).toUpperCase() + content.substring(1);
|
||||
untranslatedContent = untranslatedContent.replace(/(^[, ]*)|([, ]*$)/g, '');
|
||||
untranslatedContent = untranslatedContent.substring(0, 1).toUpperCase() + untranslatedContent.substring(1);
|
||||
}
|
||||
|
||||
if (annotationWrapper.legalBasis && !isDocumine) {
|
||||
content += 'Legal basis: ' + annotationWrapper.legalBasis + '\n\n';
|
||||
params['hasLb'] = 'true';
|
||||
params['legalBasis'] = annotationWrapper.legalBasis;
|
||||
untranslatedContent += 'Legal basis: ' + annotationWrapper.legalBasis + '\n\n';
|
||||
}
|
||||
|
||||
if (annotationWrapper.hasBeenRemovedByManualOverride) {
|
||||
content += 'Removed by manual override';
|
||||
params['hasOverride'] = 'true';
|
||||
untranslatedContent += 'Removed by manual override';
|
||||
}
|
||||
|
||||
if (logEntry.section) {
|
||||
params['hasSection'] = 'true';
|
||||
params['sectionSymbol'] = isDocumine ? '' : ':';
|
||||
params['shouldLower'] = untranslatedContent.length.toString();
|
||||
params['section'] = logEntry.section;
|
||||
let prefix = `In section${isDocumine ? '' : ':'} `;
|
||||
if (content.length) {
|
||||
if (untranslatedContent.length) {
|
||||
prefix = ` ${prefix.toLowerCase()}`;
|
||||
}
|
||||
content += `${prefix} "${logEntry.section}"`;
|
||||
untranslatedContent += `${prefix} "${logEntry.section}"`;
|
||||
}
|
||||
|
||||
return content;
|
||||
return { translation: _('annotation-content'), params: params, untranslatedContent: untranslatedContent };
|
||||
}
|
||||
|
||||
static #getShortContent(annotationWrapper: AnnotationWrapper, legalBasisList: ILegalBasis[]) {
|
||||
|
||||
@ -21,6 +21,7 @@ import { NgForOf, NgIf } from '@angular/common';
|
||||
import { MatFormField } from '@angular/material/form-field';
|
||||
import { MatOption, MatSelect } from '@angular/material/select';
|
||||
import { MatSlideToggle } from '@angular/material/slide-toggle';
|
||||
import { PdfViewer } from '../../../../pdf-viewer/services/pdf-viewer.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: './user-profile-screen.component.html',
|
||||
@ -45,6 +46,7 @@ export class UserProfileScreenComponent extends BaseFormComponent implements OnI
|
||||
protected readonly _userPreferenceService: UserPreferenceService,
|
||||
private readonly _changeRef: ChangeDetectorRef,
|
||||
private readonly _toaster: Toaster,
|
||||
private readonly _pdfViewer: PdfViewer,
|
||||
) {
|
||||
super();
|
||||
this._loadingService.start();
|
||||
@ -107,6 +109,7 @@ export class UserProfileScreenComponent extends BaseFormComponent implements OnI
|
||||
|
||||
if (this.languageChanged) {
|
||||
await this._languageService.change(this.form.get('language').value);
|
||||
await this._pdfViewer.instance?.UI.setLanguage(this._languageService.currentLanguage);
|
||||
}
|
||||
|
||||
if (this.themeChanged) {
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
<div class="pagination noselect">
|
||||
<div (click)="changePage.emit(1)" class="page-button" id="portraitPage">
|
||||
<mat-icon class="chevron-icon" svgIcon="iqser:nav-prev"></mat-icon>
|
||||
Portrait
|
||||
{{ 'watermark-screen.pagination.portrait' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="separator">/</div>
|
||||
|
||||
<div (click)="changePage.emit(2)" class="page-button" id="landscapePage">
|
||||
Landscape
|
||||
{{ 'watermark-screen.pagination.landscape' | translate }}
|
||||
<mat-icon class="chevron-icon" svgIcon="iqser:nav-next"></mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
import { Component, EventEmitter, Output } from '@angular/core';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-paginator',
|
||||
templateUrl: './paginator.component.html',
|
||||
styleUrls: ['./paginator.component.scss'],
|
||||
standalone: true,
|
||||
imports: [MatIcon],
|
||||
imports: [MatIcon, TranslateModule],
|
||||
})
|
||||
export class PaginatorComponent {
|
||||
@Output() readonly changePage = new EventEmitter<number>();
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
.container {
|
||||
padding: 32px;
|
||||
width: 1000px;
|
||||
max-width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@ -119,7 +119,9 @@ export class BulkActionsService {
|
||||
return;
|
||||
}
|
||||
|
||||
const fileWarnings = approvalResponse.map(response => ({ fileId: response.fileId, fileWarnings: response.fileWarnings }));
|
||||
const fileWarnings = approvalResponse
|
||||
.filter(response => response.hasWarnings)
|
||||
.map(response => ({ fileId: response.fileId, fileWarnings: response.fileWarnings }));
|
||||
this._dialogService.openDialog(
|
||||
'confirm',
|
||||
{
|
||||
|
||||
@ -1,161 +1,165 @@
|
||||
<div
|
||||
*ngIf="canPerformAnnotationActions && annotationPermissions"
|
||||
[class.always-visible]="alwaysVisible || (helpModeService.isHelpModeActive$ | async)"
|
||||
class="annotation-actions"
|
||||
>
|
||||
<!-- Resize Mode for annotation -> only resize accept and deny actions are available-->
|
||||
<ng-container *ngIf="resizing && annotationPermissions.canResizeAnnotation">
|
||||
<iqser-circle-button
|
||||
(action)="acceptResize()"
|
||||
[buttonId]="annotations.length === 1 ? 'annotation-' + annotations[0].id + '-accept_resize' : 'annotations-accept_resize'"
|
||||
[class.disabled]="!resized"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="resized ? ('annotation-actions.resize-accept.label' | translate) : ''"
|
||||
[type]="buttonType"
|
||||
icon="iqser:check"
|
||||
></iqser-circle-button>
|
||||
@if (canPerformAnnotationActions && annotationPermissions()) {
|
||||
<div [class.always-visible]="alwaysVisible || (helpModeService.isHelpModeActive$ | async)" class="annotation-actions">
|
||||
<!-- Resize Mode for annotation -> only resize accept and deny actions are available-->
|
||||
<ng-container *ngIf="resizing() && annotationPermissions().canResizeAnnotation">
|
||||
<iqser-circle-button
|
||||
(action)="acceptResize()"
|
||||
[buttonId]="
|
||||
annotations().length === 1 ? 'annotation-' + annotations()[0].id + '-accept_resize' : 'annotations-accept_resize'
|
||||
"
|
||||
[class.disabled]="!resized"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="resized ? ('annotation-actions.resize-accept.label' | translate) : ''"
|
||||
[type]="buttonType"
|
||||
icon="iqser:check"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="cancelResize()"
|
||||
[buttonId]="annotations.length === 1 ? 'annotation-' + annotations[0].id + '-cancel_resize' : 'annotations-cancel_resize'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.resize-cancel.label' | translate"
|
||||
[type]="buttonType"
|
||||
icon="iqser:close"
|
||||
></iqser-circle-button>
|
||||
</ng-container>
|
||||
<iqser-circle-button
|
||||
(action)="cancelResize()"
|
||||
[buttonId]="
|
||||
annotations().length === 1 ? 'annotation-' + annotations()[0].id + '-cancel_resize' : 'annotations-cancel_resize'
|
||||
"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.resize-cancel.label' | translate"
|
||||
[type]="buttonType"
|
||||
icon="iqser:close"
|
||||
></iqser-circle-button>
|
||||
</ng-container>
|
||||
|
||||
<!-- Not resizing - standard actions -->
|
||||
<ng-container *ngIf="!resizing">
|
||||
<iqser-circle-button
|
||||
(action)="resize()"
|
||||
*ngIf="canResize"
|
||||
[attr.help-mode-key]="helpModeKey('resize')"
|
||||
[buttonId]="annotations.length === 1 ? 'annotation-' + annotations[0].id + '-resize' : 'annotations-resize'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.resize.label' | translate"
|
||||
[type]="buttonType"
|
||||
icon="iqser:resize"
|
||||
></iqser-circle-button>
|
||||
<!-- Not resizing - standard actions -->
|
||||
<ng-container *ngIf="!resizing()">
|
||||
<iqser-circle-button
|
||||
(action)="resize()"
|
||||
*ngIf="canResize()"
|
||||
[attr.help-mode-key]="helpModeKey('resize')"
|
||||
[buttonId]="annotations().length === 1 ? 'annotation-' + annotations()[0].id + '-resize' : 'annotations-resize'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.resize.label' | translate"
|
||||
[type]="buttonType"
|
||||
icon="iqser:resize"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="annotationActionsService.editRedaction(annotations)"
|
||||
*ngIf="canEdit"
|
||||
[attr.help-mode-key]="helpModeKey('edit')"
|
||||
[buttonId]="annotations.length === 1 ? 'annotation-' + annotations[0].id + '-edit' : 'annotations-edit'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.edit-redaction.label' | translate"
|
||||
[type]="buttonType"
|
||||
icon="iqser:edit"
|
||||
></iqser-circle-button>
|
||||
<iqser-circle-button
|
||||
(action)="annotationActionsService.editRedaction(annotations())"
|
||||
*ngIf="canEdit()"
|
||||
[attr.help-mode-key]="helpModeKey('edit')"
|
||||
[buttonId]="annotations().length === 1 ? 'annotation-' + annotations()[0].id + '-edit' : 'annotations-edit'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.edit-redaction.label' | translate"
|
||||
[type]="buttonType"
|
||||
icon="iqser:edit"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="acceptRecommendation()"
|
||||
*ngIf="canAcceptRecommendation"
|
||||
[attr.help-mode-key]="helpModeKey('accept')"
|
||||
[buttonId]="
|
||||
annotations.length === 1
|
||||
? 'annotation-' + annotations[0].id + '-accept_recommendation'
|
||||
: 'annotations-accept_recommendation'
|
||||
"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.accept-recommendation.label' | translate"
|
||||
[type]="buttonType"
|
||||
icon="iqser:check"
|
||||
></iqser-circle-button>
|
||||
<iqser-circle-button
|
||||
(action)="acceptRecommendation()"
|
||||
*ngIf="canAcceptRecommendation()"
|
||||
[attr.help-mode-key]="helpModeKey('accept')"
|
||||
[buttonId]="
|
||||
annotations().length === 1
|
||||
? 'annotation-' + annotations()[0].id + '-accept_recommendation'
|
||||
: 'annotations-accept_recommendation'
|
||||
"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.accept-recommendation.label' | translate"
|
||||
[type]="buttonType"
|
||||
icon="iqser:check"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="annotationActionsService.convertHighlights(annotations)"
|
||||
*ngIf="viewModeService.isEarmarks()"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.convert-highlights.label' | translate"
|
||||
[type]="buttonType"
|
||||
icon="red:convert"
|
||||
></iqser-circle-button>
|
||||
<iqser-circle-button
|
||||
(action)="annotationActionsService.convertHighlights(annotations())"
|
||||
*ngIf="viewModeService.isEarmarks()"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.convert-highlights.label' | translate"
|
||||
[type]="buttonType"
|
||||
icon="red:convert"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="annotationActionsService.removeHighlights(annotations)"
|
||||
*ngIf="viewModeService.isEarmarks()"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.remove-highlights.label' | translate"
|
||||
[type]="buttonType"
|
||||
icon="iqser:trash"
|
||||
></iqser-circle-button>
|
||||
<iqser-circle-button
|
||||
(action)="annotationActionsService.removeHighlights(annotations())"
|
||||
*ngIf="viewModeService.isEarmarks()"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.remove-highlights.label' | translate"
|
||||
[type]="buttonType"
|
||||
icon="iqser:trash"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="annotationActionsService.undoDirectAction(annotations)"
|
||||
*allow="roles.redactions.deleteManual; if: annotationPermissions.canUndo"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.undo' | translate"
|
||||
[type]="buttonType"
|
||||
icon="red:undo"
|
||||
></iqser-circle-button>
|
||||
<iqser-circle-button
|
||||
(action)="annotationActionsService.undoDirectAction(annotations())"
|
||||
*allow="roles.redactions.deleteManual; if: annotationPermissions().canUndo"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.undo' | translate"
|
||||
[type]="buttonType"
|
||||
icon="red:undo"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="annotationReferencesService.show(annotations[0])"
|
||||
*ngIf="multiSelectService.inactive() && annotations[0].reference.length"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.see-references.label' | translate"
|
||||
[type]="buttonType"
|
||||
icon="red:reference"
|
||||
></iqser-circle-button>
|
||||
<iqser-circle-button
|
||||
(action)="annotationReferencesService.show(annotations()[0])"
|
||||
*ngIf="multiSelectService.inactive() && annotations()[0].reference.length"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.see-references.label' | translate"
|
||||
[type]="buttonType"
|
||||
icon="red:reference"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="annotationActionsService.forceAnnotation(annotations)"
|
||||
*ngIf="canForceRedaction"
|
||||
[attr.help-mode-key]="isImageHint ? helpModeKey('redact') : helpModeKey('force')"
|
||||
[buttonId]="annotations.length === 1 ? 'annotation-' + annotations[0].id + '-force_redaction' : 'annotations-force_redaction'"
|
||||
[icon]="isImageHint ? 'red:pdftron-action-add-redaction' : 'iqser:thumb-up'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="
|
||||
isImageHint
|
||||
? ('annotation-actions.force-redaction.label-image-hint' | translate)
|
||||
: ('annotation-actions.force-redaction.label' | translate)
|
||||
"
|
||||
[type]="buttonType"
|
||||
></iqser-circle-button>
|
||||
<iqser-circle-button
|
||||
(action)="annotationActionsService.forceAnnotation(annotations())"
|
||||
*ngIf="canForceRedaction()"
|
||||
[attr.help-mode-key]="isImageHint() ? helpModeKey('redact') : helpModeKey('force')"
|
||||
[buttonId]="
|
||||
annotations().length === 1 ? 'annotation-' + annotations()[0].id + '-force_redaction' : 'annotations-force_redaction'
|
||||
"
|
||||
[icon]="isImageHint() ? 'red:pdftron-action-add-redaction' : 'iqser:thumb-up'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="
|
||||
isImageHint()
|
||||
? ('annotation-actions.force-redaction.label-image-hint' | translate)
|
||||
: ('annotation-actions.force-redaction.label' | translate)
|
||||
"
|
||||
[type]="buttonType"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="annotationActionsService.forceAnnotation(annotations, true)"
|
||||
*ngIf="canForceHint"
|
||||
[attr.help-mode-key]="actionsHelpModeKey"
|
||||
[buttonId]="annotations.length === 1 ? 'annotation-' + annotations[0].id + '-force_hint' : 'annotations-force_hint'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.force-hint.label' | translate"
|
||||
[type]="buttonType"
|
||||
icon="iqser:thumb-up"
|
||||
></iqser-circle-button>
|
||||
<iqser-circle-button
|
||||
(action)="annotationActionsService.forceAnnotation(annotations(), true)"
|
||||
*ngIf="canForceHint()"
|
||||
[attr.help-mode-key]="actionsHelpModeKey"
|
||||
[buttonId]="annotations().length === 1 ? 'annotation-' + annotations()[0].id + '-force_hint' : 'annotations-force_hint'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.force-hint.label' | translate"
|
||||
[type]="buttonType"
|
||||
icon="iqser:thumb-up"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="hideAnnotation()"
|
||||
*ngIf="isImage && isVisible() && !hideSkipped"
|
||||
[attr.help-mode-key]="helpModeKey('hide')"
|
||||
[buttonId]="annotations.length === 1 ? 'annotation-' + annotations[0].id + '-hide' : 'annotations-hide'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.hide' | translate"
|
||||
[type]="buttonType"
|
||||
icon="iqser:visibility-off"
|
||||
></iqser-circle-button>
|
||||
<iqser-circle-button
|
||||
(action)="hideAnnotation()"
|
||||
*ngIf="isImage() && isVisible() && !hideSkipped()"
|
||||
[attr.help-mode-key]="helpModeKey('hide')"
|
||||
[buttonId]="annotations().length === 1 ? 'annotation-' + annotations()[0].id + '-hide' : 'annotations-hide'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.hide' | translate"
|
||||
[type]="buttonType"
|
||||
icon="iqser:visibility-off"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="showAnnotation()"
|
||||
*ngIf="isImage && !isVisible() && !hideSkipped"
|
||||
[buttonId]="annotations.length === 1 ? 'annotation-' + annotations[0].id + '-show' : 'annotations-show'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.show' | translate"
|
||||
[type]="buttonType"
|
||||
icon="iqser:visibility"
|
||||
></iqser-circle-button>
|
||||
<iqser-circle-button
|
||||
(action)="showAnnotation()"
|
||||
*ngIf="isImage() && !isVisible() && !hideSkipped()"
|
||||
[buttonId]="annotations().length === 1 ? 'annotation-' + annotations()[0].id + '-show' : 'annotations-show'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.show' | translate"
|
||||
[type]="buttonType"
|
||||
icon="iqser:visibility"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="removeRedaction()"
|
||||
*ngIf="canRemoveRedaction"
|
||||
[attr.help-mode-key]="helpModeKey('remove')"
|
||||
[buttonId]="annotations.length === 1 ? 'annotation-' + annotations[0].id + '-remove' : 'annotations-remove'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.remove-annotation.remove-redaction' | translate"
|
||||
[type]="buttonType"
|
||||
icon="iqser:trash"
|
||||
></iqser-circle-button>
|
||||
</ng-container>
|
||||
</div>
|
||||
<iqser-circle-button
|
||||
(action)="removeRedaction()"
|
||||
*ngIf="canRemoveRedaction()"
|
||||
[attr.help-mode-key]="helpModeKey('remove')"
|
||||
[buttonId]="annotations().length === 1 ? 'annotation-' + annotations()[0].id + '-remove' : 'annotations-remove'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.remove-annotation.remove-redaction' | translate"
|
||||
[type]="buttonType"
|
||||
icon="iqser:trash"
|
||||
></iqser-circle-button>
|
||||
</ng-container>
|
||||
</div>
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Component, computed, Input, OnChanges } from '@angular/core';
|
||||
import { Component, computed, input, Input, untracked } from '@angular/core';
|
||||
import { CircleButtonComponent, getConfig, HelpModeService, IqserAllowDirective, IqserPermissionsService } from '@iqser/common-ui';
|
||||
import { AnnotationPermissions } from '@models/file/annotation.permissions';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
@ -28,21 +28,77 @@ export type AnnotationButtonType = keyof typeof AnnotationButtonTypes;
|
||||
standalone: true,
|
||||
imports: [CircleButtonComponent, NgIf, TranslateModule, AsyncPipe, IqserAllowDirective],
|
||||
})
|
||||
export class AnnotationActionsComponent implements OnChanges {
|
||||
#annotations: AnnotationWrapper[] = [];
|
||||
readonly #isDocumine = getConfig().IS_DOCUMINE;
|
||||
protected _annotationId = '';
|
||||
export class AnnotationActionsComponent {
|
||||
@Input() buttonType: AnnotationButtonType = AnnotationButtonTypes.default;
|
||||
@Input() tooltipPosition: 'before' | 'above' = 'before';
|
||||
@Input() canPerformAnnotationActions: boolean;
|
||||
@Input() alwaysVisible: boolean;
|
||||
@Input() actionsHelpModeKey: string;
|
||||
readonly roles = Roles;
|
||||
annotationPermissions: AnnotationPermissions;
|
||||
isImage = true;
|
||||
readonly annotations = input.required<AnnotationWrapper[], (AnnotationWrapper | undefined)[]>({
|
||||
transform: value => value.filter(a => a !== undefined),
|
||||
});
|
||||
readonly isVisible = computed(() => {
|
||||
const hidden = this._annotationManager.hidden();
|
||||
return this.#annotations.reduce((acc, annotation) => !hidden.has(annotation.id) && acc, true);
|
||||
return this.annotations().reduce((acc, annotation) => !hidden.has(annotation.id) && acc, true);
|
||||
});
|
||||
readonly somePending = computed(() => {
|
||||
return this.annotations().some(a => a.pending);
|
||||
});
|
||||
readonly sameType = computed(() => {
|
||||
const annotations = this.annotations();
|
||||
const type = annotations[0].superType;
|
||||
return annotations.every(a => a.superType === type);
|
||||
});
|
||||
readonly resizing = computed(() => {
|
||||
return this.annotations().length === 1 && this.annotations()[0].id === this._annotationManager.resizingAnnotationId;
|
||||
});
|
||||
readonly viewerAnnotations = computed(() => {
|
||||
return this._annotationManager.get(this.annotations());
|
||||
});
|
||||
readonly annotationPermissions = computed(() =>
|
||||
AnnotationPermissions.forUser(
|
||||
this._permissionsService.isApprover(this._state.dossier()),
|
||||
this.annotations(),
|
||||
this._state.dictionaries,
|
||||
this._iqserPermissionsService,
|
||||
this._state.file().excludedFromAutomaticAnalysis,
|
||||
),
|
||||
);
|
||||
readonly hideSkipped = computed(() => this.skippedService.hideSkipped() && this.annotations().some(a => a.isSkipped));
|
||||
readonly isImageHint = computed(() => this.annotations().every(a => a.IMAGE_HINT));
|
||||
readonly isImage = computed(() => this.annotations().reduce((acc, a) => acc && a.isImage, true));
|
||||
readonly canRemoveRedaction = computed(
|
||||
() => this.annotationChangesAllowed() && this.annotationPermissions().canRemoveRedaction && this.sameType(),
|
||||
);
|
||||
readonly canForceRedaction = computed(() => this.annotationChangesAllowed() && this.annotationPermissions().canForceRedaction);
|
||||
readonly canForceHint = computed(() => this.annotationChangesAllowed() && this.annotationPermissions().canForceHint);
|
||||
readonly canAcceptRecommendation = computed(
|
||||
() => this.annotationChangesAllowed() && this.annotationPermissions().canAcceptRecommendation,
|
||||
);
|
||||
readonly #isDocumine = getConfig().IS_DOCUMINE;
|
||||
readonly annotationChangesAllowed = computed(
|
||||
() => (!this.#isDocumine || !this._state.file().excludedFromAutomaticAnalysis) && !this.somePending(),
|
||||
);
|
||||
readonly canResize = computed(
|
||||
() => this.annotationChangesAllowed() && this.annotationPermissions().canResizeAnnotation && this.annotations().length === 1,
|
||||
);
|
||||
readonly canEdit = computed(() => {
|
||||
const canEditRedactions =
|
||||
this.annotationPermissions().canChangeLegalBasis ||
|
||||
this.annotationPermissions().canRecategorizeAnnotation ||
|
||||
this.annotationPermissions().canForceHint ||
|
||||
this.annotationPermissions().canForceRedaction;
|
||||
return (
|
||||
this.annotationChangesAllowed() &&
|
||||
(this.annotations().length > 1
|
||||
? this.#isDocumine
|
||||
? this.annotationPermissions().canEditAnnotations
|
||||
: this.annotationPermissions().canEditHints ||
|
||||
this.annotationPermissions().canEditImages ||
|
||||
this.annotationPermissions().canEditAnnotations
|
||||
: canEditRedactions)
|
||||
);
|
||||
});
|
||||
|
||||
constructor(
|
||||
@ -58,137 +114,54 @@ export class AnnotationActionsComponent implements OnChanges {
|
||||
readonly annotationReferencesService: AnnotationReferencesService,
|
||||
) {}
|
||||
|
||||
get annotations(): AnnotationWrapper[] {
|
||||
return this.#annotations;
|
||||
}
|
||||
|
||||
get isImageHint(): boolean {
|
||||
return this.annotations.every(annotation => annotation.IMAGE_HINT);
|
||||
}
|
||||
|
||||
@Input()
|
||||
set annotations(annotations: AnnotationWrapper[]) {
|
||||
this.#annotations = annotations.filter(a => a !== undefined);
|
||||
this.isImage = this.#annotations?.reduce((accumulator, annotation) => annotation.isImage && accumulator, true);
|
||||
this._annotationId = this.#annotations[0]?.id;
|
||||
}
|
||||
|
||||
get canEdit(): boolean {
|
||||
const canEditRedactions =
|
||||
this.annotationPermissions.canChangeLegalBasis ||
|
||||
this.annotationPermissions.canRecategorizeAnnotation ||
|
||||
this.annotationPermissions.canForceHint ||
|
||||
this.annotationPermissions.canForceRedaction;
|
||||
return (
|
||||
this.#annotationChangesAllowed &&
|
||||
(this.annotations.length > 1
|
||||
? this.#isDocumine
|
||||
? this.annotationPermissions.canEditAnnotations
|
||||
: this.annotationPermissions.canEditHints ||
|
||||
this.annotationPermissions.canEditImages ||
|
||||
this.annotationPermissions.canEditAnnotations
|
||||
: canEditRedactions)
|
||||
);
|
||||
}
|
||||
|
||||
get canResize(): boolean {
|
||||
return this.#annotationChangesAllowed && this.annotationPermissions.canResizeAnnotation && this.annotations.length === 1;
|
||||
}
|
||||
|
||||
get canRemoveRedaction(): boolean {
|
||||
return this.#annotationChangesAllowed && this.annotationPermissions.canRemoveRedaction && this.#sameType;
|
||||
}
|
||||
|
||||
get canForceRedaction() {
|
||||
return this.#annotationChangesAllowed && this.annotationPermissions.canForceRedaction;
|
||||
}
|
||||
|
||||
get canForceHint() {
|
||||
return this.#annotationChangesAllowed && this.annotationPermissions.canForceHint;
|
||||
}
|
||||
|
||||
get canAcceptRecommendation() {
|
||||
return this.#annotationChangesAllowed && this.annotationPermissions.canAcceptRecommendation;
|
||||
}
|
||||
|
||||
get viewerAnnotations() {
|
||||
return this._annotationManager.get(this.#annotations);
|
||||
}
|
||||
|
||||
get resizing() {
|
||||
return this.#annotations?.length === 1 && this.#annotations?.[0].id === this._annotationManager.resizingAnnotationId;
|
||||
}
|
||||
|
||||
get resized() {
|
||||
get resized(): boolean {
|
||||
return this._annotationManager.annotationHasBeenResized;
|
||||
}
|
||||
|
||||
get hideSkipped() {
|
||||
return this.skippedService.hideSkipped() && this.annotations.some(a => a.isSkipped);
|
||||
async removeRedaction(): Promise<void> {
|
||||
const annotations = untracked(this.annotations);
|
||||
const permissions = untracked(this.annotationPermissions);
|
||||
await this.annotationActionsService.removeRedaction(annotations, permissions);
|
||||
}
|
||||
|
||||
get #sameType() {
|
||||
const type = this.annotations[0].superType;
|
||||
return this.annotations.every(a => a.superType === type);
|
||||
}
|
||||
|
||||
ngOnChanges(): void {
|
||||
this.#setPermissions();
|
||||
}
|
||||
|
||||
removeRedaction() {
|
||||
this.annotationActionsService.removeRedaction(this.annotations, this.annotationPermissions);
|
||||
}
|
||||
|
||||
acceptRecommendation() {
|
||||
return this.annotationActionsService.convertRecommendationToAnnotation(this.annotations);
|
||||
async acceptRecommendation(): Promise<void> {
|
||||
const annotations = untracked(this.annotations);
|
||||
await this.annotationActionsService.convertRecommendationToAnnotation(annotations);
|
||||
}
|
||||
|
||||
hideAnnotation() {
|
||||
this._annotationManager.hide(this.viewerAnnotations);
|
||||
const viewerAnnotations = untracked(this.viewerAnnotations);
|
||||
this._annotationManager.hide(viewerAnnotations);
|
||||
this._annotationManager.deselect();
|
||||
this._annotationManager.addToHidden(this.viewerAnnotations[0].Id);
|
||||
this._annotationManager.addToHidden(viewerAnnotations[0].Id);
|
||||
}
|
||||
|
||||
showAnnotation() {
|
||||
this._annotationManager.show(this.viewerAnnotations);
|
||||
const viewerAnnotations = untracked(this.viewerAnnotations);
|
||||
this._annotationManager.show(viewerAnnotations);
|
||||
this._annotationManager.deselect();
|
||||
this._annotationManager.removeFromHidden(this.viewerAnnotations[0].Id);
|
||||
this._annotationManager.removeFromHidden(viewerAnnotations[0].Id);
|
||||
}
|
||||
|
||||
resize() {
|
||||
return this.annotationActionsService.resize(this.#annotations[0]);
|
||||
const annotations = untracked(this.annotations);
|
||||
return this.annotationActionsService.resize(annotations[0]);
|
||||
}
|
||||
|
||||
acceptResize() {
|
||||
if (this.resized) {
|
||||
return this.annotationActionsService.acceptResize(this.#annotations[0], this.annotationPermissions);
|
||||
const annotations = untracked(this.annotations);
|
||||
const permissions = untracked(this.annotationPermissions);
|
||||
return this.annotationActionsService.acceptResize(annotations[0], permissions);
|
||||
}
|
||||
}
|
||||
|
||||
cancelResize() {
|
||||
return this.annotationActionsService.cancelResize(this.#annotations[0]);
|
||||
const annotations = untracked(this.annotations);
|
||||
return this.annotationActionsService.cancelResize(annotations[0]);
|
||||
}
|
||||
|
||||
helpModeKey(action: string) {
|
||||
return this.#isDocumine ? `${action}_annotation` : `${this.actionsHelpModeKey}_${action}`;
|
||||
}
|
||||
|
||||
#setPermissions() {
|
||||
this.annotationPermissions = AnnotationPermissions.forUser(
|
||||
this._permissionsService.isApprover(this._state.dossier()),
|
||||
this.#annotations,
|
||||
this._state.dictionaries,
|
||||
this._iqserPermissionsService,
|
||||
this._state.file().excludedFromAutomaticAnalysis,
|
||||
);
|
||||
}
|
||||
|
||||
get #annotationChangesAllowed() {
|
||||
return (!this.#isDocumine || !this._state.file().excludedFromAutomaticAnalysis) && !this.#somePending;
|
||||
}
|
||||
|
||||
get #somePending() {
|
||||
return this.#annotations.some(a => a.pending);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,37 +1,42 @@
|
||||
<div class="active-bar-marker"></div>
|
||||
|
||||
<div [class.removed]="annotation.item.isRemoved" class="annotation">
|
||||
<div [class.removed]="annotation().item.isRemoved" class="annotation">
|
||||
<redaction-annotation-card
|
||||
[annotation]="annotation.item"
|
||||
[isSelected]="annotation.isSelected"
|
||||
[matTooltip]="annotation.item.content"
|
||||
[annotation]="annotation().item"
|
||||
[isSelected]="annotation().isSelected"
|
||||
[matTooltip]="annotation().item.content.translation | translate: annotation().item.content.params | replaceNbsp"
|
||||
matTooltipPosition="above"
|
||||
></redaction-annotation-card>
|
||||
|
||||
<div *ngIf="!annotation.item.isEarmark" class="actions-wrapper">
|
||||
<div
|
||||
*ngIf="!annotation.item.pending"
|
||||
(click)="showComments = !showComments"
|
||||
[matTooltip]="'comments.comments' | translate: { count: annotation.item.numberOfComments }"
|
||||
class="comments-counter"
|
||||
iqserStopPropagation
|
||||
matTooltipPosition="above"
|
||||
>
|
||||
<mat-icon svgIcon="red:comment"></mat-icon>
|
||||
{{ annotation.item.numberOfComments }}
|
||||
</div>
|
||||
@if (!annotation().item.isEarmark) {
|
||||
<div class="actions-wrapper">
|
||||
@if (!annotation().item.pending) {
|
||||
<div
|
||||
(click)="showComments = !showComments"
|
||||
[matTooltip]="'comments.comments' | translate: { count: annotation().item.numberOfComments }"
|
||||
class="comments-counter"
|
||||
iqserStopPropagation
|
||||
matTooltipPosition="above"
|
||||
>
|
||||
<mat-icon svgIcon="red:comment"></mat-icon>
|
||||
{{ annotation().item.numberOfComments }}
|
||||
</div>
|
||||
}
|
||||
|
||||
<div *ngIf="multiSelectService.inactive()" class="actions">
|
||||
<redaction-annotation-actions
|
||||
[annotations]="[annotation.item]"
|
||||
[actionsHelpModeKey]="actionsHelpModeKey"
|
||||
[canPerformAnnotationActions]="pdfProxyService.canPerformActions()"
|
||||
></redaction-annotation-actions>
|
||||
@if (multiSelectService.inactive()) {
|
||||
<div class="actions">
|
||||
<redaction-annotation-actions
|
||||
[actionsHelpModeKey]="actionsHelpModeKey()"
|
||||
[annotations]="[annotation().item]"
|
||||
[canPerformAnnotationActions]="pdfProxyService.canPerformActions()"
|
||||
></redaction-annotation-actions>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<ng-container *ngIf="showComments">
|
||||
<redaction-comments [annotation]="annotation.item"></redaction-comments>
|
||||
@if (showComments) {
|
||||
<redaction-comments [annotation]="annotation().item"></redaction-comments>
|
||||
|
||||
<div
|
||||
(click)="showComments = false"
|
||||
@ -39,7 +44,7 @@
|
||||
iqserStopPropagation
|
||||
translate="comments.hide-comments"
|
||||
></div>
|
||||
</ng-container>
|
||||
}
|
||||
</div>
|
||||
|
||||
<redaction-annotation-details [annotation]="annotation"></redaction-annotation-details>
|
||||
<redaction-annotation-details [annotation]="annotation()"></redaction-annotation-details>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Component, HostBinding, inject, Input, OnChanges } from '@angular/core';
|
||||
import { Component, computed, effect, HostBinding, inject, input } from '@angular/core';
|
||||
import { getConfig, StopPropagationDirective } from '@iqser/common-ui';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { ListItem } from '@models/file/list-item';
|
||||
@ -6,13 +6,13 @@ import { MultiSelectService } from '../../services/multi-select.service';
|
||||
import { PdfProxyService } from '../../services/pdf-proxy.service';
|
||||
import { ActionsHelpModeKeys } from '../../utils/constants';
|
||||
import { AnnotationCardComponent } from '../annotation-card/annotation-card.component';
|
||||
import { NgIf } from '@angular/common';
|
||||
import { MatTooltip } from '@angular/material/tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
import { AnnotationActionsComponent } from '../annotation-actions/annotation-actions.component';
|
||||
import { CommentsComponent } from '../comments/comments.component';
|
||||
import { AnnotationDetailsComponent } from '../annotation-details/annotation-details.component';
|
||||
import { ReplaceNbspPipe } from '@common-ui/pipes/replace-nbsp.pipe';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-annotation-wrapper',
|
||||
@ -21,7 +21,6 @@ import { AnnotationDetailsComponent } from '../annotation-details/annotation-det
|
||||
standalone: true,
|
||||
imports: [
|
||||
AnnotationCardComponent,
|
||||
NgIf,
|
||||
MatTooltip,
|
||||
TranslateModule,
|
||||
StopPropagationDirective,
|
||||
@ -29,28 +28,31 @@ import { AnnotationDetailsComponent } from '../annotation-details/annotation-det
|
||||
AnnotationActionsComponent,
|
||||
CommentsComponent,
|
||||
AnnotationDetailsComponent,
|
||||
ReplaceNbspPipe,
|
||||
],
|
||||
})
|
||||
export class AnnotationWrapperComponent implements OnChanges {
|
||||
readonly #isDocumine = getConfig().IS_DOCUMINE;
|
||||
export class AnnotationWrapperComponent {
|
||||
readonly annotation = input.required<ListItem<AnnotationWrapper>>();
|
||||
@HostBinding('attr.annotation-id') annotationId: string;
|
||||
@HostBinding('class.active') active: boolean;
|
||||
|
||||
readonly actionsHelpModeKey = computed(() => this.#getActionsHelpModeKey(this.annotation().item));
|
||||
showComments = false;
|
||||
protected readonly pdfProxyService = inject(PdfProxyService);
|
||||
protected readonly multiSelectService = inject(MultiSelectService);
|
||||
@Input({ required: true }) annotation!: ListItem<AnnotationWrapper>;
|
||||
@HostBinding('attr.annotation-id') annotationId: string;
|
||||
@HostBinding('class.active') active = false;
|
||||
actionsHelpModeKey: string;
|
||||
showComments = false;
|
||||
readonly #isDocumine = getConfig().IS_DOCUMINE;
|
||||
|
||||
ngOnChanges() {
|
||||
this.annotationId = this.annotation.item.id;
|
||||
this.active = this.annotation.isSelected;
|
||||
this.actionsHelpModeKey = this.#getActionsHelpModeKey();
|
||||
constructor() {
|
||||
effect(() => {
|
||||
this.active = this.annotation().isSelected;
|
||||
this.annotationId = this.annotation().item.id;
|
||||
});
|
||||
}
|
||||
|
||||
#getActionsHelpModeKey(): string {
|
||||
#getActionsHelpModeKey(item: AnnotationWrapper): string {
|
||||
if (!this.#isDocumine) {
|
||||
const superType = this.annotation.item.superTypeLabel?.split('.')[1];
|
||||
const type = this.annotation.item.type;
|
||||
const superType = item.superTypeLabel?.split('.')[1];
|
||||
const type = item.type;
|
||||
if (superType === 'hint' && (type === 'ocr' || type === 'formula' || type === 'image')) {
|
||||
return ActionsHelpModeKeys[`${superType}-${type}`];
|
||||
}
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
<ng-container *ngFor="let annotation of annotations; let idx = index; trackBy: _trackBy">
|
||||
<div *ngIf="showHighlightGroup(idx) as highlightGroup" class="workload-separator">
|
||||
@for (annotation of annotations(); track annotation.item.id) {
|
||||
@if (displayedHighlightGroups()[$index]; as highlightGroup) {
|
||||
<redaction-highlights-separator [annotation]="annotation.item" [highlightGroup]="highlightGroup"></redaction-highlights-separator>
|
||||
</div>
|
||||
}
|
||||
|
||||
<redaction-annotation-wrapper
|
||||
*ngIf="!annotation.item.hiddenInWorkload"
|
||||
(click)="annotationClicked(annotation.item, $event)"
|
||||
*ngIf="!annotation.item.hiddenInWorkload"
|
||||
[annotation]="annotation"
|
||||
[id]="'annotation-' + annotation.item.id"
|
||||
[class.documine-wrapper]="isDocumine"
|
||||
[id]="'annotation-' + annotation.item.id"
|
||||
></redaction-annotation-wrapper>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<redaction-annotation-references-list
|
||||
(referenceClicked)="referenceClicked($event)"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Component, computed, ElementRef, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { Component, computed, ElementRef, input, output } from '@angular/core';
|
||||
import { getConfig, HasScrollbarDirective } from '@iqser/common-ui';
|
||||
import { FilterService } from '@iqser/common-ui/lib/filtering';
|
||||
import { IqserEventTarget } from '@iqser/common-ui/lib/utils';
|
||||
@ -24,13 +24,24 @@ import { AnnotationReferencesListComponent } from '../annotation-references-list
|
||||
imports: [NgForOf, NgIf, HighlightsSeparatorComponent, AnnotationWrapperComponent, AnnotationReferencesListComponent],
|
||||
})
|
||||
export class AnnotationsListComponent extends HasScrollbarDirective {
|
||||
@Input({ required: true }) annotations: ListItem<AnnotationWrapper>[];
|
||||
@Output() readonly pagesPanelActive = new EventEmitter<boolean>();
|
||||
readonly #earmarkGroups = computed(() => {
|
||||
if (this._viewModeService.isEarmarks()) {
|
||||
return this.#getEarmarksGroups();
|
||||
readonly annotations = input.required<ListItem<AnnotationWrapper>[]>();
|
||||
readonly pagesPanelActive = output<boolean>();
|
||||
readonly displayedHighlightGroups = computed(() => {
|
||||
const isEarMarks = this._viewModeService.isEarmarks();
|
||||
let result: Record<number, EarmarkGroup> = {};
|
||||
|
||||
if (isEarMarks) {
|
||||
const annotations = this.annotations();
|
||||
const earmarkGroups = this.#getEarmarksGroups(annotations);
|
||||
for (let idx = 0; idx < annotations.length; ++idx) {
|
||||
const group = earmarkGroups.find(h => h.startIdx === idx);
|
||||
if (group) {
|
||||
result[idx] = group;
|
||||
}
|
||||
}
|
||||
}
|
||||
return [] as EarmarkGroup[];
|
||||
|
||||
return result;
|
||||
});
|
||||
protected readonly isDocumine = getConfig().IS_DOCUMINE;
|
||||
|
||||
@ -77,26 +88,20 @@ export class AnnotationsListComponent extends HasScrollbarDirective {
|
||||
}
|
||||
}
|
||||
|
||||
showHighlightGroup(idx: number): EarmarkGroup {
|
||||
return this._viewModeService.isEarmarks() && this.#earmarkGroups().find(h => h.startIdx === idx);
|
||||
}
|
||||
|
||||
protected readonly _trackBy = (index: number, listItem: ListItem<AnnotationWrapper>) => listItem.item.id;
|
||||
|
||||
#getEarmarksGroups() {
|
||||
#getEarmarksGroups(annotations: ListItem<AnnotationWrapper>[]) {
|
||||
const earmarksGroups: EarmarkGroup[] = [];
|
||||
|
||||
if (!this.annotations?.length) {
|
||||
if (!annotations.length) {
|
||||
return earmarksGroups;
|
||||
}
|
||||
|
||||
let lastGroup: EarmarkGroup;
|
||||
for (let idx = 0; idx < this.annotations.length; ++idx) {
|
||||
if (idx === 0 || this.annotations[idx].item.color !== this.annotations[idx - 1].item.color) {
|
||||
for (let idx = 0; idx < annotations.length; ++idx) {
|
||||
if (idx === 0 || annotations[idx].item.color !== annotations[idx - 1].item.color) {
|
||||
if (lastGroup) {
|
||||
earmarksGroups.push(lastGroup);
|
||||
}
|
||||
lastGroup = { startIdx: idx, length: 1, color: this.annotations[idx].item.color };
|
||||
lastGroup = { startIdx: idx, length: 1, color: annotations[idx].item.color };
|
||||
} else {
|
||||
lastGroup.length += 1;
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
<div [ngStyle]="gridConfig()" class="table">
|
||||
@for (column of _columns(); track column.label) {
|
||||
<div [ngClass]="{ hide: !!column.hide }" class="col cell">{{ column.label }}</div>
|
||||
<div [ngClass]="{ hide: !!column.hide }" class="col cell">
|
||||
<label>{{ column.label }}</label>
|
||||
</div>
|
||||
}
|
||||
@for (row of _data(); track $index) {
|
||||
@for (cell of row; track cell.label) {
|
||||
|
||||
@ -12,6 +12,11 @@
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
background: white;
|
||||
|
||||
label {
|
||||
opacity: 0.7;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.cell {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { ActivatedRouteSnapshot, NavigationExtras, Router, RouterLink } from '@angular/router';
|
||||
import { ChangeDetectorRef, Component, effect, NgZone, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, effect, NgZone, OnDestroy, OnInit, TemplateRef, untracked, ViewChild } from '@angular/core';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { ComponentCanDeactivate } from '@guards/can-deactivate.guard';
|
||||
import {
|
||||
@ -101,13 +101,13 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
readonly roles = Roles;
|
||||
readonly fileId = this.state.fileId;
|
||||
readonly dossierId = this.state.dossierId;
|
||||
protected readonly isDocumine = getConfig().IS_DOCUMINE;
|
||||
@ViewChild('annotationFilterTemplate', {
|
||||
read: TemplateRef,
|
||||
static: false,
|
||||
})
|
||||
private readonly _filterTemplate: TemplateRef<unknown>;
|
||||
#loadAllAnnotationsEnabled = false;
|
||||
protected readonly isDocumine = getConfig().IS_DOCUMINE;
|
||||
|
||||
constructor(
|
||||
readonly pdf: PdfViewer,
|
||||
@ -180,7 +180,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
|
||||
effect(() => {
|
||||
this._viewModeService.viewMode();
|
||||
this.updateViewMode().then();
|
||||
this.#updateViewMode().then();
|
||||
});
|
||||
|
||||
effect(() => {
|
||||
@ -208,7 +208,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
const earmarks$ = isEarmarksViewMode$.pipe(
|
||||
tap(() => this._loadingService.start()),
|
||||
switchMap(() => this._fileDataService.loadEarmarks()),
|
||||
tap(() => this.updateViewMode().then(() => this._loadingService.stop())),
|
||||
tap(() => this.#updateViewMode().then(() => this._loadingService.stop())),
|
||||
);
|
||||
|
||||
const currentPageIfEarmarksView$ = combineLatest([this.pdf.currentPage$, this._viewModeService.viewMode$]).pipe(
|
||||
@ -234,7 +234,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
|
||||
return isChangingFromEarmarksViewMode$.pipe(
|
||||
map(() => this._fileDataService.earmarks().get(this.pdf.currentPage()) ?? []),
|
||||
map(earmarks => this.deleteAnnotations(earmarks, [])),
|
||||
map(earmarks => this.#deleteAnnotations(earmarks, [])),
|
||||
);
|
||||
}
|
||||
|
||||
@ -243,61 +243,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
this._viewerHeaderService.disable(ROTATION_ACTION_BUTTONS);
|
||||
}
|
||||
|
||||
async updateViewMode(): Promise<void> {
|
||||
this._logger.info(`[PDF] Update ${this._viewModeService.viewMode()} view mode`);
|
||||
|
||||
const annotations = this._annotationManager.get(a => bool(a.getCustomData('redact-manager')));
|
||||
const redactions = annotations.filter(a => bool(a.getCustomData('redaction')));
|
||||
|
||||
switch (this._viewModeService.viewMode()) {
|
||||
case ViewModes.STANDARD: {
|
||||
const wrappers = this._fileDataService.annotations();
|
||||
const ocrAnnotationIds = wrappers.filter(a => a.isOCR).map(a => a.id);
|
||||
const standardEntries = annotations
|
||||
.filter(a => !bool(a.getCustomData('changeLogRemoved')) && !this._annotationManager.isHidden(a.Id))
|
||||
.filter(a => !ocrAnnotationIds.includes(a.Id));
|
||||
const nonStandardEntries = annotations.filter(
|
||||
a =>
|
||||
bool(a.getCustomData('changeLogRemoved')) ||
|
||||
this._annotationManager.isHidden(a.Id) ||
|
||||
(this._skippedService.hideSkipped() && bool(a.getCustomData('skipped'))),
|
||||
);
|
||||
this._readableRedactionsService.setAnnotationsColor(standardEntries, 'annotationColor');
|
||||
this._readableRedactionsService.setAnnotationsOpacity(standardEntries, true);
|
||||
this._annotationManager.show(standardEntries);
|
||||
this._annotationManager.hide(nonStandardEntries);
|
||||
break;
|
||||
}
|
||||
case ViewModes.DELTA: {
|
||||
const changeLogEntries = annotations.filter(a => bool(a.getCustomData('changeLog')));
|
||||
const nonChangeLogEntries = annotations.filter(a => !bool(a.getCustomData('changeLog')));
|
||||
this._readableRedactionsService.setAnnotationsColor(redactions, 'annotationColor');
|
||||
this._readableRedactionsService.setAnnotationsOpacity(changeLogEntries, true);
|
||||
this._annotationManager.show(changeLogEntries);
|
||||
this._annotationManager.hide(nonChangeLogEntries);
|
||||
break;
|
||||
}
|
||||
case ViewModes.REDACTED: {
|
||||
const nonRedactionEntries = annotations.filter(
|
||||
a => !bool(a.getCustomData('redaction')) || bool(a.getCustomData('changeLogRemoved')),
|
||||
);
|
||||
this._readableRedactionsService.setAnnotationsColor(redactions, 'redactionColor');
|
||||
this._readableRedactionsService.setAnnotationsOpacity(redactions);
|
||||
this._annotationManager.show(redactions);
|
||||
this._annotationManager.hide(nonRedactionEntries);
|
||||
|
||||
break;
|
||||
}
|
||||
case ViewModes.TEXT_HIGHLIGHTS: {
|
||||
this._annotationManager.hide(annotations);
|
||||
}
|
||||
}
|
||||
|
||||
this._logger.info('[PDF] Rebuild filters');
|
||||
this.#rebuildFilters();
|
||||
this._logger.info('[PDF] Update done');
|
||||
}
|
||||
|
||||
ngOnDetach() {
|
||||
this._viewerHeaderService.resetCompareButtons();
|
||||
this._viewerHeaderService.enableLoadAllAnnotations(); // Reset the button state (since the viewer is reused between files)
|
||||
@ -412,7 +357,9 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
const annotations$ = this._fileDataService.annotations$.pipe(
|
||||
startWith([] as AnnotationWrapper[]),
|
||||
pairwise(),
|
||||
tap(annotations => this.deleteAnnotations(...annotations)),
|
||||
tap(annotations => this.#deleteAnnotations(...annotations)),
|
||||
tap(() => this.#updateFiltersAfterAnnotationsChanged()),
|
||||
tap(() => this.#updateViewMode()),
|
||||
);
|
||||
|
||||
const currentPageIfNotHighlightsView$ = combineLatest([this.pdf.currentPage$, this._viewModeService.viewMode$]).pipe(
|
||||
@ -431,12 +378,72 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
return combineLatest([currentPageAnnotations$, this._documentViewer.loaded$]).pipe(
|
||||
filter(([, loaded]) => loaded),
|
||||
map(([annotations]) => annotations),
|
||||
tap(([oldA, newA]) => this.drawChangedAnnotations(oldA, newA)?.then(() => this.updateViewMode())),
|
||||
tap(([, newAnnotations]) => this.#highlightSelectedAnnotations(newAnnotations)),
|
||||
switchMap(async ([oldAnnotations, newAnnotations]) => {
|
||||
await this.#drawChangedAnnotations(oldAnnotations, newAnnotations);
|
||||
return newAnnotations;
|
||||
}),
|
||||
tap(newAnnotations => this.#highlightSelectedAnnotations(newAnnotations)),
|
||||
);
|
||||
}
|
||||
|
||||
deleteAnnotations(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]) {
|
||||
async #updateViewMode(): Promise<void> {
|
||||
const viewMode = untracked(this._viewModeService.viewMode);
|
||||
this._logger.info(`[PDF] Update ${viewMode} view mode`);
|
||||
|
||||
const annotations = this._annotationManager.get(a => bool(a.getCustomData('redact-manager')));
|
||||
const redactions = annotations.filter(a => bool(a.getCustomData('redaction')));
|
||||
|
||||
switch (viewMode) {
|
||||
case ViewModes.STANDARD: {
|
||||
const wrappers = this._fileDataService.annotations();
|
||||
// TODO: const wrappers = untracked(this._fileDataService.annotations);
|
||||
const ocrAnnotationIds = wrappers.filter(a => a.isOCR).map(a => a.id);
|
||||
const standardEntries = annotations
|
||||
.filter(a => !bool(a.getCustomData('changeLogRemoved')) && !this._annotationManager.isHidden(a.Id))
|
||||
.filter(a => !ocrAnnotationIds.includes(a.Id));
|
||||
const nonStandardEntries = annotations.filter(
|
||||
a =>
|
||||
bool(a.getCustomData('changeLogRemoved')) ||
|
||||
this._annotationManager.isHidden(a.Id) ||
|
||||
(untracked(this._skippedService.hideSkipped) && bool(a.getCustomData('skipped'))),
|
||||
);
|
||||
this._readableRedactionsService.setAnnotationsColor(standardEntries, 'annotationColor');
|
||||
this._readableRedactionsService.setAnnotationsOpacity(standardEntries, true);
|
||||
this._annotationManager.show(standardEntries);
|
||||
this._annotationManager.hide(nonStandardEntries);
|
||||
break;
|
||||
}
|
||||
case ViewModes.DELTA: {
|
||||
const changeLogEntries = annotations.filter(a => bool(a.getCustomData('changeLog')));
|
||||
const nonChangeLogEntries = annotations.filter(a => !bool(a.getCustomData('changeLog')));
|
||||
this._readableRedactionsService.setAnnotationsColor(redactions, 'annotationColor');
|
||||
this._readableRedactionsService.setAnnotationsOpacity(changeLogEntries, true);
|
||||
this._annotationManager.show(changeLogEntries);
|
||||
this._annotationManager.hide(nonChangeLogEntries);
|
||||
break;
|
||||
}
|
||||
case ViewModes.REDACTED: {
|
||||
const nonRedactionEntries = annotations.filter(
|
||||
a => !bool(a.getCustomData('redaction')) || bool(a.getCustomData('changeLogRemoved')),
|
||||
);
|
||||
this._readableRedactionsService.setAnnotationsColor(redactions, 'redactionColor');
|
||||
this._readableRedactionsService.setAnnotationsOpacity(redactions);
|
||||
this._annotationManager.show(redactions);
|
||||
this._annotationManager.hide(nonRedactionEntries);
|
||||
|
||||
break;
|
||||
}
|
||||
case ViewModes.TEXT_HIGHLIGHTS: {
|
||||
this._annotationManager.hide(annotations);
|
||||
}
|
||||
}
|
||||
|
||||
this._logger.info('[PDF] Rebuild filters');
|
||||
this.#rebuildFilters();
|
||||
this._logger.info('[PDF] Update done');
|
||||
}
|
||||
|
||||
#deleteAnnotations(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]) {
|
||||
const annotationsToDelete = oldAnnotations.filter(oldAnnotation => {
|
||||
const newAnnotation = newAnnotations.find(byId(oldAnnotation.id));
|
||||
return newAnnotation ? hasChanges(oldAnnotation, newAnnotation) : true;
|
||||
@ -446,11 +453,11 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
this._annotationManager.delete(annotationsToDelete);
|
||||
}
|
||||
|
||||
drawChangedAnnotations(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]) {
|
||||
async #drawChangedAnnotations(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]): Promise<void> {
|
||||
const annotationsToDraw = this.#getAnnotationsToDraw(oldAnnotations, newAnnotations);
|
||||
this._logger.info('[ANNOTATIONS] To draw: ', annotationsToDraw);
|
||||
this._annotationManager.delete(annotationsToDraw);
|
||||
return this.#cleanupAndRedrawAnnotations(annotationsToDraw);
|
||||
await this.#cleanupAndRedrawAnnotations(annotationsToDraw);
|
||||
}
|
||||
|
||||
async #openRedactTextDialog(manualRedactionEntryWrapper: ManualRedactionEntryWrapper) {
|
||||
@ -641,7 +648,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
filter(event => event.type === ViewerEvents.LOAD_ALL_ANNOTATIONS),
|
||||
switchMap(() => {
|
||||
// TODO: this switchMap is ugly, to be refactored
|
||||
const annotations = this._fileDataService.annotations();
|
||||
const annotations = untracked(this._fileDataService.annotations);
|
||||
const showWarning = !this.userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning);
|
||||
const annotationsExceedThreshold = annotations.length >= this.configService.values.ANNOTATIONS_THRESHOLD;
|
||||
|
||||
@ -654,7 +661,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
filter(([confirmed]) => confirmed),
|
||||
map(([, annotations]) => {
|
||||
this.#loadAllAnnotationsEnabled = true;
|
||||
this.drawChangedAnnotations([], annotations).then(() => {
|
||||
this.#drawChangedAnnotations([], annotations).then(() => {
|
||||
this._toaster.success(_('load-all-annotations-success'));
|
||||
this._viewerHeaderService.disableLoadAllAnnotations();
|
||||
});
|
||||
@ -662,7 +669,9 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
)
|
||||
.subscribe();
|
||||
|
||||
this.addActiveScreenSubscription = this._readableRedactionsService.active$.pipe(map(() => this.updateViewMode())).subscribe();
|
||||
this.addActiveScreenSubscription = this._readableRedactionsService.active$
|
||||
.pipe(switchMap(() => this.#updateViewMode()))
|
||||
.subscribe();
|
||||
|
||||
this.addActiveScreenSubscription = combineLatest([this._viewModeService.viewMode$, this.state.file$, this._documentViewer.loaded$])
|
||||
.pipe(
|
||||
@ -701,11 +710,15 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
this._errorService.set(error);
|
||||
}
|
||||
|
||||
#cleanupAndRedrawAnnotations(newAnnotations: List<AnnotationWrapper>) {
|
||||
async #cleanupAndRedrawAnnotations(newAnnotations: List<AnnotationWrapper>): Promise<void> {
|
||||
if (!newAnnotations.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
await this._annotationDrawService.draw(newAnnotations, this._skippedService.hideSkipped(), this.state.dossierTemplateId);
|
||||
}
|
||||
|
||||
#updateFiltersAfterAnnotationsChanged(): void {
|
||||
const currentFilters = this._filterService.getGroup('primaryFilters')?.filters || [];
|
||||
this.#rebuildFilters();
|
||||
|
||||
@ -714,8 +727,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
this.#handleDeltaAnnotationFilters(currentFilters);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
return this._annotationDrawService.draw(newAnnotations, this._skippedService.hideSkipped(), this.state.dossierTemplateId);
|
||||
}
|
||||
|
||||
#handleDeltaAnnotationFilters(currentFilters: NestedFilter[]) {
|
||||
|
||||
@ -277,7 +277,6 @@ export class AnnotationActionsService {
|
||||
const text = annotation.AREA ? annotation.value : isImageText;
|
||||
const isApprover = this._permissionsService.isApprover(dossier);
|
||||
const dossierTemplate = this._dossierTemplatesService.find(this._state.dossierTemplateId);
|
||||
const isUnprocessed = annotation.pending;
|
||||
|
||||
const data: ResizeRedactionData = {
|
||||
redaction: annotation,
|
||||
@ -308,7 +307,7 @@ export class AnnotationActionsService {
|
||||
|
||||
await this.cancelResize(annotation);
|
||||
|
||||
const { fileId, dossierId, file } = this._state;
|
||||
const { fileId, dossierId } = this._state;
|
||||
const request = this._manualRedactionService.resize([resizeRequest], dossierId, fileId, includeUnprocessed);
|
||||
return this.#processObsAndEmit(request);
|
||||
}
|
||||
@ -471,6 +470,36 @@ export class AnnotationActionsService {
|
||||
// todo: might not be correct, probably shouldn't get to this point if they are not all the same
|
||||
const isHint = redactions.every(r => r.isHint);
|
||||
const { dossierId, fileId } = this._state;
|
||||
const maximumNumberEntries = 100;
|
||||
if (removeFromDictionary && (body as List<IRemoveRedactionRequest>).length > maximumNumberEntries) {
|
||||
const requests = body as List<IRemoveRedactionRequest>;
|
||||
const splitNumber = Math.floor(requests.length / maximumNumberEntries);
|
||||
const remainder = requests.length % maximumNumberEntries;
|
||||
const splitRequests = [];
|
||||
for (let i = 0; i < splitNumber; i++) {
|
||||
splitRequests.push(requests.slice(i * maximumNumberEntries, (i + 1) * maximumNumberEntries));
|
||||
}
|
||||
splitRequests.push(requests.slice(splitNumber * maximumNumberEntries, splitNumber * maximumNumberEntries + remainder));
|
||||
|
||||
const promises = [];
|
||||
for (const split of splitRequests) {
|
||||
promises.push(
|
||||
firstValueFrom(
|
||||
this._manualRedactionService.removeRedaction(
|
||||
split,
|
||||
dossierId,
|
||||
fileId,
|
||||
removeFromDictionary,
|
||||
isHint,
|
||||
includeUnprocessed,
|
||||
dialogResult.bulkLocal,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
Promise.all(promises).finally(() => this._fileDataService.annotationsChanged());
|
||||
return;
|
||||
}
|
||||
this.#processObsAndEmit(
|
||||
this._manualRedactionService.removeRedaction(
|
||||
body,
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { computed, Injectable, Signal, signal } from '@angular/core';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { FileDataService } from './file-data.service';
|
||||
|
||||
@ -7,7 +6,6 @@ import { FileDataService } from './file-data.service';
|
||||
export class AnnotationReferencesService {
|
||||
readonly references: Signal<AnnotationWrapper[]>;
|
||||
readonly annotation: Signal<AnnotationWrapper | undefined>;
|
||||
private readonly _annotation$ = new BehaviorSubject<AnnotationWrapper | undefined>(undefined);
|
||||
readonly #annotation = signal<AnnotationWrapper | undefined>(undefined);
|
||||
|
||||
constructor(private readonly _fileDataService: FileDataService) {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { computed, effect, inject, Injectable, NgZone } from '@angular/core';
|
||||
import { computed, effect, inject, Injectable, NgZone, untracked } from '@angular/core';
|
||||
import { getConfig, IqserPermissionsService } from '@iqser/common-ui';
|
||||
import { getCurrentUser } from '@iqser/common-ui/lib/users';
|
||||
import { isJustOne, shareDistinctLast, UI_ROOT_PATH_FN } from '@iqser/common-ui/lib/utils';
|
||||
@ -49,7 +49,7 @@ export class PdfProxyService {
|
||||
readonly redactTextRequested$ = new Subject<ManualRedactionEntryWrapper>();
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly pageChanged$ = this._pdf.pageChanged$.pipe(
|
||||
tap(() => this.#handleExcludedPageActions()),
|
||||
tap(pageNumber => this.#handleExcludedPageActions(pageNumber)),
|
||||
tap(() => {
|
||||
if (this._multiSelectService.inactive()) {
|
||||
this._annotationManager.deselect();
|
||||
@ -98,7 +98,7 @@ export class PdfProxyService {
|
||||
effect(
|
||||
() => {
|
||||
const canPerformActions = this.canPerformActions();
|
||||
this._pdf.isCompareMode();
|
||||
const isCompareMode = this._pdf.isCompareMode();
|
||||
|
||||
this.#configureTextPopup();
|
||||
|
||||
@ -109,7 +109,8 @@ export class PdfProxyService {
|
||||
this.#deactivateMultiSelect();
|
||||
}
|
||||
|
||||
this.#handleExcludedPageActions();
|
||||
const currentPage = untracked(this._pdf.currentPage);
|
||||
this.#handleExcludedPageActions(currentPage);
|
||||
},
|
||||
{ allowSignalWrites: true },
|
||||
);
|
||||
@ -227,8 +228,9 @@ export class PdfProxyService {
|
||||
this.redactTextRequested$.next({ manualRedactionEntry, type });
|
||||
}
|
||||
|
||||
#handleExcludedPageActions() {
|
||||
const isCurrentPageExcluded = this._state.file().isPageExcluded(this._pdf.currentPage());
|
||||
#handleExcludedPageActions(currentPage: number) {
|
||||
const isCurrentPageExcluded = this._state.file().isPageExcluded(currentPage);
|
||||
|
||||
if (!isCurrentPageExcluded) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
|
||||
import { List } from '@iqser/common-ui/lib/utils';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { Core } from '@pdftron/webviewer';
|
||||
import { IRectangle, ISectionRectangle, IPoint, SuperTypes } from '@red/domain';
|
||||
import { IPoint, IRectangle, ISectionRectangle, SuperTypes } from '@red/domain';
|
||||
import { DefaultColorsService } from '@services/entity-services/default-colors.service';
|
||||
import { hexToRgb } from '@utils/functions';
|
||||
import { BoundingBox, Table } from '../../file-preview/services/tables.service';
|
||||
@ -169,7 +169,7 @@ export class AnnotationDrawService {
|
||||
const annotation = this._pdf.textHighlight();
|
||||
annotation.Quads = this.#rectanglesToQuads(annotationWrapper.positions, pageNumber);
|
||||
annotation.Opacity = annotationWrapper.isRemoved ? DEFAULT_REMOVED_ANNOTATION_OPACITY : DEFAULT_TEXT_ANNOTATION_OPACITY;
|
||||
annotation.setContents(annotationWrapper.content);
|
||||
annotation.setContents(annotationWrapper.content.untranslatedContent);
|
||||
annotation.PageNumber = pageNumber;
|
||||
annotation.StrokeColor = this.convertColor(annotationWrapper.color);
|
||||
annotation.Id = annotationWrapper.id;
|
||||
|
||||
@ -19,14 +19,14 @@ const MOVE_OPTION = 'move';
|
||||
|
||||
@Injectable()
|
||||
export class REDAnnotationManager {
|
||||
resizingAnnotationId?: string = undefined;
|
||||
annotationHasBeenResized?: boolean = false;
|
||||
readonly #hidden = signal(new Set<string>());
|
||||
readonly hidden = this.#hidden.asReadonly();
|
||||
#manager: AnnotationManager;
|
||||
readonly #logger = inject(NGXLogger);
|
||||
readonly #annotationSelected$ = new Subject<[Annotation[], string]>();
|
||||
readonly annotationSelected$ = this.#annotationSelected$.asObservable();
|
||||
resizingAnnotationId?: string = undefined;
|
||||
annotationHasBeenResized?: boolean = false;
|
||||
readonly hidden = this.#hidden.asReadonly();
|
||||
|
||||
get selected() {
|
||||
return this.#manager.getSelectedAnnotations();
|
||||
@ -128,21 +128,15 @@ export class REDAnnotationManager {
|
||||
annotations.forEach(annotation => this.#manager.redrawAnnotation(annotation));
|
||||
}
|
||||
|
||||
add(annotations: Annotation | Annotation[]) {
|
||||
async add(annotations: Annotation | Annotation[]): Promise<void> {
|
||||
try {
|
||||
annotations = asList(annotations);
|
||||
this.#manager.addAnnotations(annotations, { imported: true });
|
||||
return this.#manager.drawAnnotationsFromList(annotations);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
showHidden() {
|
||||
const hidden = this.#getByIds([...this.hidden().values()]);
|
||||
this.show(hidden);
|
||||
}
|
||||
|
||||
#listenForAnnotationSelected() {
|
||||
this.#manager.addEventListener('annotationSelected', async (annotations: Annotation[], action: string) => {
|
||||
this.#logger.info('[PDF] Annotation selected: ', annotations, action);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { effect, inject, Injectable, signal } from '@angular/core';
|
||||
import { computed, effect, inject, Injectable, signal } from '@angular/core';
|
||||
import { HeaderElements } from '../../file-preview/utils/constants';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
@ -16,18 +16,7 @@ export class LayersService {
|
||||
private readonly _pdf: PdfViewer,
|
||||
private readonly _documentViewer: REDDocumentViewer,
|
||||
private readonly _translateService: TranslateService,
|
||||
) {
|
||||
effect(() => {
|
||||
this.active();
|
||||
this.#updateButton();
|
||||
});
|
||||
}
|
||||
|
||||
get toggleLayersBtnTitle(): string {
|
||||
return this._translateService.instant(_('pdf-viewer.toggle-layers'), {
|
||||
active: this.active(),
|
||||
});
|
||||
}
|
||||
) {}
|
||||
|
||||
get toggleLayersBtnIcon(): string {
|
||||
return this.#icon;
|
||||
@ -45,13 +34,16 @@ export class LayersService {
|
||||
}
|
||||
});
|
||||
|
||||
this.updateIconState();
|
||||
|
||||
this._documentViewer.document.setLayersArray(layers);
|
||||
this._documentViewer.refreshAndUpdateView();
|
||||
}
|
||||
|
||||
updateIconState() {
|
||||
updateState() {
|
||||
this.#updateIconState();
|
||||
this.#updateButton();
|
||||
}
|
||||
|
||||
#updateIconState() {
|
||||
const element = this._pdf.instance.UI.iframeWindow.document.querySelector(`[data-element=${HeaderElements.TOGGLE_LAYERS}]`);
|
||||
if (!element) return;
|
||||
if (this.active()) {
|
||||
@ -63,7 +55,9 @@ export class LayersService {
|
||||
|
||||
#updateButton() {
|
||||
this._pdf.instance?.UI.updateElement(HeaderElements.TOGGLE_LAYERS, {
|
||||
title: this.toggleLayersBtnTitle,
|
||||
title: this._translateService.instant(_('pdf-viewer.header.toggle-layers'), {
|
||||
active: this.active(),
|
||||
}),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ import { takeUntilDestroyed, toObservable, toSignal } from '@angular/core/rxjs-i
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { environment } from '@environments/environment';
|
||||
import { ErrorService, getConfig } from '@iqser/common-ui';
|
||||
import { ErrorService, getConfig, LanguageService } from '@iqser/common-ui';
|
||||
import { shareDistinctLast, UI_ROOT_PATH_FN } from '@iqser/common-ui/lib/utils';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import WebViewer, { Core, WebViewerInstance, WebViewerOptions } from '@pdftron/webviewer';
|
||||
@ -70,6 +70,7 @@ export class PdfViewer {
|
||||
private readonly _errorService: ErrorService,
|
||||
private readonly _userPreferenceService: UserPreferenceService,
|
||||
private readonly _annotationManager: REDAnnotationManager,
|
||||
private readonly _languageService: LanguageService,
|
||||
) {
|
||||
this.totalPages = this.#totalPages.asReadonly();
|
||||
this.isCompareMode = this.#isCompareMode.asReadonly();
|
||||
@ -152,6 +153,7 @@ export class PdfViewer {
|
||||
|
||||
await this.runWithCleanup(async () => {
|
||||
this.#instance.UI.setTheme(this._userPreferenceService.getTheme());
|
||||
await this.#instance.UI.setLanguage(this._languageService.currentLanguage);
|
||||
this._logger.info('[PDF] Initialized');
|
||||
|
||||
this.documentViewer = this.#instance.Core.documentViewer;
|
||||
|
||||
@ -29,24 +29,13 @@ export class ReadableRedactionsService {
|
||||
return this.#active$.getValue();
|
||||
}
|
||||
|
||||
get toggleReadableRedactionsBtnTitle(): string {
|
||||
return this._translateService.instant(_('pdf-viewer.toggle-readable-redactions'), {
|
||||
active: this.active,
|
||||
});
|
||||
}
|
||||
|
||||
get toggleReadableRedactionsBtnIcon(): string {
|
||||
return this.active ? this.#enableIcon : this.#disableIcon;
|
||||
}
|
||||
|
||||
toggleReadableRedactions(): void {
|
||||
this.#active$.next(!this.active);
|
||||
|
||||
this._pdf.instance.UI.updateElement(HeaderElements.TOGGLE_READABLE_REDACTIONS, {
|
||||
title: this.toggleReadableRedactionsBtnTitle,
|
||||
img: this.toggleReadableRedactionsBtnIcon,
|
||||
});
|
||||
|
||||
this.updateState();
|
||||
if (!this.active) {
|
||||
this.setCustomDrawHandler();
|
||||
} else {
|
||||
@ -88,4 +77,13 @@ export class ReadableRedactionsService {
|
||||
annotation['FillColor'] = color;
|
||||
});
|
||||
}
|
||||
|
||||
updateState() {
|
||||
this._pdf.instance.UI.updateElement(HeaderElements.TOGGLE_READABLE_REDACTIONS, {
|
||||
title: this._translateService.instant(_('pdf-viewer.header.toggle-readable-redactions'), {
|
||||
active: this.active,
|
||||
}),
|
||||
img: this.toggleReadableRedactionsBtnIcon,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,21 +15,11 @@ export class TooltipsService {
|
||||
private readonly _translateService: TranslateService,
|
||||
) {}
|
||||
|
||||
get toggleTooltipsBtnTitle(): string {
|
||||
return this._translateService.instant(_('pdf-viewer.toggle-tooltips'), {
|
||||
active: this._userPreferenceService.getFilePreviewTooltipsPreference(),
|
||||
});
|
||||
}
|
||||
|
||||
async toggleTooltips(): Promise<void> {
|
||||
await this._userPreferenceService.toggleFilePreviewTooltipsPreference();
|
||||
this._documentViewer.updateTooltipsVisibility();
|
||||
|
||||
this.updateIconState();
|
||||
|
||||
this._pdf.instance.UI.updateElement(HeaderElements.TOGGLE_TOOLTIPS, {
|
||||
title: this.toggleTooltipsBtnTitle,
|
||||
});
|
||||
this.updateState();
|
||||
}
|
||||
|
||||
updateIconState() {
|
||||
@ -40,4 +30,13 @@ export class TooltipsService {
|
||||
element.classList.remove('active');
|
||||
}
|
||||
}
|
||||
|
||||
updateState() {
|
||||
this.updateIconState();
|
||||
this._pdf.instance.UI.updateElement(HeaderElements.TOGGLE_TOOLTIPS, {
|
||||
title: this._translateService.instant(_('pdf-viewer.header.toggle-tooltips'), {
|
||||
active: this._userPreferenceService.getFilePreviewTooltipsPreference(),
|
||||
}),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,6 +16,8 @@ import { PdfViewer } from './pdf-viewer.service';
|
||||
import { ReadableRedactionsService } from './readable-redactions.service';
|
||||
import { TooltipsService } from './tooltips.service';
|
||||
import { UI_ROOT_PATH_FN } from '@common-ui/utils';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { viewerHeaderButtonsTranslations } from '@translations/pdf-viewer-translations';
|
||||
|
||||
const divider: IHeaderElement = {
|
||||
type: 'divider',
|
||||
@ -90,7 +92,7 @@ export class ViewerHeaderService {
|
||||
toolGroup: 'rectangleTools',
|
||||
dataElement: HeaderElements.SHAPE_TOOL_GROUP_BUTTON,
|
||||
img: this.#convertPath('/assets/icons/general/pdftron-rectangle.svg'),
|
||||
title: 'annotation.rectangle',
|
||||
title: viewerHeaderButtonsTranslations[HeaderElements.SHAPE_TOOL_GROUP_BUTTON],
|
||||
};
|
||||
}
|
||||
|
||||
@ -99,7 +101,6 @@ export class ViewerHeaderService {
|
||||
type: 'actionButton',
|
||||
element: HeaderElements.TOGGLE_TOOLTIPS,
|
||||
dataElement: HeaderElements.TOGGLE_TOOLTIPS,
|
||||
title: this._tooltipsService.toggleTooltipsBtnTitle,
|
||||
img: this.#convertPath('/assets/icons/general/pdftron-action-enable-tooltips.svg'),
|
||||
onClick: () => this._ngZone.run(() => this._tooltipsService.toggleTooltips()),
|
||||
};
|
||||
@ -110,7 +111,6 @@ export class ViewerHeaderService {
|
||||
type: 'actionButton',
|
||||
element: HeaderElements.TOGGLE_LAYERS,
|
||||
dataElement: HeaderElements.TOGGLE_LAYERS,
|
||||
title: this._layersService.toggleLayersBtnTitle,
|
||||
img: this._layersService.toggleLayersBtnIcon,
|
||||
onClick: () => this._ngZone.run(() => this._layersService.toggleLayers()),
|
||||
};
|
||||
@ -121,7 +121,6 @@ export class ViewerHeaderService {
|
||||
type: 'actionButton',
|
||||
element: HeaderElements.TOGGLE_READABLE_REDACTIONS,
|
||||
dataElement: HeaderElements.TOGGLE_READABLE_REDACTIONS,
|
||||
title: this._readableRedactionsService.toggleReadableRedactionsBtnTitle,
|
||||
img: this._readableRedactionsService.toggleReadableRedactionsBtnIcon,
|
||||
onClick: () => this._ngZone.run(() => this._readableRedactionsService.toggleReadableRedactions()),
|
||||
};
|
||||
@ -130,7 +129,7 @@ export class ViewerHeaderService {
|
||||
get #loadAllAnnotations(): IHeaderElement {
|
||||
return {
|
||||
type: 'actionButton',
|
||||
title: this._translateService.instant('viewer-header.load-all-annotations'),
|
||||
title: viewerHeaderButtonsTranslations[HeaderElements.LOAD_ALL_ANNOTATIONS],
|
||||
img: this.#convertPath('/assets/icons/general/pdftron-action-load-all-annotations.svg'),
|
||||
onClick: () => this._ngZone.run(() => this.#events$.next({ type: ViewerEvents.LOAD_ALL_ANNOTATIONS })),
|
||||
dataElement: HeaderElements.LOAD_ALL_ANNOTATIONS,
|
||||
@ -143,7 +142,7 @@ export class ViewerHeaderService {
|
||||
element: HeaderElements.ROTATE_LEFT_BUTTON,
|
||||
dataElement: HeaderElements.ROTATE_LEFT_BUTTON,
|
||||
img: this.#convertPath('/assets/icons/general/rotate-left.svg'),
|
||||
title: 'Rotate page left',
|
||||
title: viewerHeaderButtonsTranslations[HeaderElements.ROTATE_LEFT_BUTTON],
|
||||
onClick: () =>
|
||||
this._ngZone.run(() => {
|
||||
this._rotationService.addRotation(RotationTypes.LEFT);
|
||||
@ -203,7 +202,7 @@ export class ViewerHeaderService {
|
||||
element: HeaderElements.ROTATE_RIGHT_BUTTON,
|
||||
dataElement: HeaderElements.ROTATE_RIGHT_BUTTON,
|
||||
img: this.#convertPath('/assets/icons/general/rotate-right.svg'),
|
||||
title: 'Rotate page right',
|
||||
title: viewerHeaderButtonsTranslations[HeaderElements.ROTATE_RIGHT_BUTTON],
|
||||
onClick: () =>
|
||||
this._ngZone.run(() => {
|
||||
this._rotationService.addRotation(RotationTypes.RIGHT);
|
||||
@ -218,7 +217,7 @@ export class ViewerHeaderService {
|
||||
element: HeaderElements.COMPARE_BUTTON,
|
||||
dataElement: HeaderElements.COMPARE_BUTTON,
|
||||
img: this.#convertPath('/assets/icons/general/pdftron-action-compare.svg'),
|
||||
title: 'Compare',
|
||||
title: viewerHeaderButtonsTranslations[HeaderElements.COMPARE_BUTTON],
|
||||
onClick: () =>
|
||||
this._ngZone.run(async () => {
|
||||
document.getElementById('compareFileInput').click();
|
||||
@ -310,24 +309,27 @@ export class ViewerHeaderService {
|
||||
header.getItems().splice(startButtons, header.getItems().length - deleteCount, ...enabledItems);
|
||||
});
|
||||
|
||||
this._pdf.instance?.UI.updateElement('selectToolButton', {
|
||||
img: this.#convertPath('/assets/icons/general/pdftron-cursor.svg'),
|
||||
});
|
||||
|
||||
if (this._pdf.instance) {
|
||||
this._tooltipsService.updateIconState();
|
||||
this._layersService.updateIconState();
|
||||
this._pdf.instance.UI.updateElement('selectToolButton', {
|
||||
img: this.#convertPath('/assets/icons/general/pdftron-cursor.svg'),
|
||||
title: this._translateService.instant(viewerHeaderButtonsTranslations['selectToolButton']),
|
||||
});
|
||||
|
||||
this._tooltipsService.updateState();
|
||||
this._layersService.updateState();
|
||||
this._readableRedactionsService.updateState();
|
||||
const closeCompareButton = this._pdf.instance.UI.iframeWindow.document.querySelector(
|
||||
`[data-element=${HeaderElements.CLOSE_COMPARE_BUTTON}]`,
|
||||
);
|
||||
closeCompareButton?.classList.add('active');
|
||||
this.#configTooltips();
|
||||
}
|
||||
}
|
||||
|
||||
disableLoadAllAnnotations(): void {
|
||||
this._pdf.instance.UI.updateElement(HeaderElements.LOAD_ALL_ANNOTATIONS, {
|
||||
img: this.#convertPath('/assets/icons/general/pdftron-action-load-all-annotations-disabled.svg'),
|
||||
title: this._translateService.instant('viewer-header.all-annotations-loaded'),
|
||||
title: this._translateService.instant(_('pdf-viewer.header.all-annotations-loaded')),
|
||||
onClick: undefined,
|
||||
});
|
||||
}
|
||||
@ -370,6 +372,37 @@ export class ViewerHeaderService {
|
||||
this._pdf.navigateTo(1);
|
||||
}
|
||||
|
||||
#configTooltips() {
|
||||
const elements: (string | HeaderElementType)[] = [
|
||||
'leftPanelButton',
|
||||
'thumbnailsPanelButton',
|
||||
'outlinesPanelButton',
|
||||
'outlineMultiSelect',
|
||||
'layersPanelButton',
|
||||
'signaturePanelButton',
|
||||
'zoomInButton',
|
||||
'zoomOutButton',
|
||||
'panToolButton',
|
||||
HeaderElements.COMPARE_BUTTON,
|
||||
HeaderElements.ROTATE_LEFT_BUTTON,
|
||||
HeaderElements.ROTATE_RIGHT_BUTTON,
|
||||
HeaderElements.LOAD_ALL_ANNOTATIONS,
|
||||
HeaderElements.SHAPE_TOOL_GROUP_BUTTON,
|
||||
];
|
||||
|
||||
elements.forEach(element => {
|
||||
if (this.#buttons.has(element as HeaderElementType)) {
|
||||
this._pdf.instance.UI.updateElement(element, {
|
||||
title: this._translateService.instant(this.#buttons.get(element as HeaderElementType).title),
|
||||
});
|
||||
} else {
|
||||
this._pdf.instance.UI.updateElement(element, {
|
||||
title: this._translateService.instant(viewerHeaderButtonsTranslations[element]),
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#pushGroup(items: IHeaderElement[], group: HeaderElementType[]) {
|
||||
const enabledItems = group.filter(item => this.#isEnabled(item));
|
||||
if (enabledItems.length) {
|
||||
|
||||
@ -2,10 +2,10 @@
|
||||
|
||||
:host {
|
||||
height: 250px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
margin-bottom: 8px;
|
||||
overflow-y: auto;
|
||||
max-height: 240px;
|
||||
@include common-mixins.scroll-bar;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { GenericService, isIqserDevMode, Toaster } from '@iqser/common-ui';
|
||||
import { EntryStates, IEntityLog, IEntityLogEntry, ISectionGrid } from '@red/domain';
|
||||
import { GenericService, Toaster } from '@iqser/common-ui';
|
||||
import { EntryStates, IEntityLog, IEntityLogEntry } from '@red/domain';
|
||||
import { firstValueFrom, of } from 'rxjs';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
|
||||
@ -20,10 +20,6 @@ export class EntityLogService extends GenericService<unknown> {
|
||||
return entityLog;
|
||||
}
|
||||
|
||||
getSectionGrid(dossierId: string, fileId: string) {
|
||||
return this._getOne<ISectionGrid>([dossierId, fileId], 'sectionGrid');
|
||||
}
|
||||
|
||||
#filterInvalidEntries(entityLogEntry: IEntityLogEntry[]) {
|
||||
return entityLogEntry.filter(entry => {
|
||||
entry.positions = entry.positions?.filter(p => !!p.rectangle?.length);
|
||||
|
||||
22
apps/red-ui/src/app/translations/pdf-viewer-translations.ts
Normal file
22
apps/red-ui/src/app/translations/pdf-viewer-translations.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { HeaderElements, HeaderElementType } from '../modules/file-preview/utils/constants';
|
||||
|
||||
export const viewerHeaderButtonsTranslations: Record<string | HeaderElementType, string> = {
|
||||
leftPanelButton: _('pdf-viewer.header.left-panel-button'),
|
||||
thumbnailsPanelButton: _('pdf-viewer.header.thumbnails-panel-button'),
|
||||
outlinesPanelButton: _('pdf-viewer.header.outlines-panel-button'),
|
||||
outlineMultiSelect: _('pdf-viewer.header.outline-multi-select'),
|
||||
noOutlinesText: _('pdf-viewer.header.no-outlines-text'),
|
||||
layersPanelButton: _('pdf-viewer.header.layers-panel-button'),
|
||||
signaturePanelButton: _('pdf-viewer.header.signature-panel-button'),
|
||||
noSignaturesText: _('pdf-viewer.header.no-signatures-text'),
|
||||
zoomInButton: _('pdf-viewer.header.zoom-in-button'),
|
||||
zoomOutButton: _('pdf-viewer.header.zoom-out-button'),
|
||||
panToolButton: _('pdf-viewer.header.pan-tool-button'),
|
||||
selectToolButton: _('pdf-viewer.header.select-tool-button'),
|
||||
[HeaderElements.COMPARE_BUTTON]: _('pdf-viewer.header.compare-button'),
|
||||
[HeaderElements.ROTATE_LEFT_BUTTON]: _('pdf-viewer.header.rotate-left-button'),
|
||||
[HeaderElements.ROTATE_RIGHT_BUTTON]: _('pdf-viewer.header.rotate-right-button'),
|
||||
[HeaderElements.SHAPE_TOOL_GROUP_BUTTON]: _('pdf-viewer.header.rectangle-tool-button'),
|
||||
[HeaderElements.LOAD_ALL_ANNOTATIONS]: _('pdf-viewer.header.load-all-annotations'),
|
||||
};
|
||||
@ -138,7 +138,7 @@
|
||||
},
|
||||
"add-edit-entity": {
|
||||
"form": {
|
||||
"case-sensitive": "Groß-/Kleinschreibung berücksichtigen",
|
||||
"case-sensitive": "Groß-/Kleinschreibung beachten",
|
||||
"color": "Farbe {type, select, redaction{Schwärzung} hint{Hinweis} recommendation{Empfehlung} skipped{Ingorierte Schwärzung} ignored{Ignorierter Hinweis} other{}}",
|
||||
"color-placeholder": "#",
|
||||
"default-reason": "Standardgrund",
|
||||
@ -146,7 +146,7 @@
|
||||
"description": "Beschreibung",
|
||||
"description-placeholder": "Beschreibung eingeben",
|
||||
"dossier-dictionary-only": "Nur Dossier-Wörterbuch",
|
||||
"has-dictionary": "Mit Wörterbuch",
|
||||
"has-dictionary": "Hat Wörterbuch",
|
||||
"hint": "Hinweis",
|
||||
"manage-entries-in-dictionary-editor-only": "In Schwärzungs-/Bearbeitungsdialogen verfügbar",
|
||||
"name": "Anzeigename",
|
||||
@ -207,14 +207,14 @@
|
||||
"generic": "Speichern des Benutzers fehlgeschlagen."
|
||||
},
|
||||
"form": {
|
||||
"account-setup": "User account setup",
|
||||
"account-setup": "Konfiguration des Benutzerkontos",
|
||||
"email": "E-Mail",
|
||||
"first-name": "Vorname",
|
||||
"last-name": "Nachname",
|
||||
"reset-password": "Passwort zurücksetzen",
|
||||
"role": "Rolle",
|
||||
"send-email": "Do not send email requesting the user to set a password",
|
||||
"send-email-explanation": "Select this option if you use SSO. Please note that you will need to inform the user directly."
|
||||
"send-email": "Benutzer nicht per E-Mail auffordern, ein Passwort festzulegen",
|
||||
"send-email-explanation": "Wählen Sie diese Option, wenn Sie SSO verwenden. Bitte beachten Sie, dass Sie den Benutzer direkt informieren müssen."
|
||||
},
|
||||
"title": "{type, select, edit{Benutzer bearbeiten} create{Neuen Benutzer erstellen} other{}}"
|
||||
},
|
||||
@ -243,8 +243,7 @@
|
||||
}
|
||||
},
|
||||
"type": "Typ",
|
||||
"type-placeholder": "Typ auswählen...",
|
||||
"value": ""
|
||||
"type-placeholder": "Typ auswählen..."
|
||||
},
|
||||
"title": "Hinweis hinzufügen"
|
||||
}
|
||||
@ -276,6 +275,9 @@
|
||||
"watermarks": "Wasserzeichen"
|
||||
},
|
||||
"analysis-disabled": "",
|
||||
"annotation": {
|
||||
"pending": "(Analyse steht aus)"
|
||||
},
|
||||
"annotation-actions": {
|
||||
"accept-recommendation": {
|
||||
"label": "Empfehlung annehmen"
|
||||
@ -331,14 +333,14 @@
|
||||
"error": "Rekategorisierung des Bilds fehlgeschlagen: {error}",
|
||||
"success": "Bild wurde einer neuen Kategorie zugeordnet."
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"remove-hint": {
|
||||
"error": "Entfernen des Hinweises fehlgeschlagen: {error}",
|
||||
"success": "Hinweis wurde entfernt"
|
||||
},
|
||||
"undo": {
|
||||
"error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}",
|
||||
"success": "Rücksetzung erfolgreich"
|
||||
@ -351,15 +353,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"
|
||||
},
|
||||
@ -368,7 +370,7 @@
|
||||
},
|
||||
"annotation-changes": {
|
||||
"added-locally": "Lokal hinzugefügt",
|
||||
"forced-hint": "Hint wurde erzwungen",
|
||||
"forced-hint": "Hinweis wurde erzwungen",
|
||||
"forced-redaction": "Schwärzung wurde erzwungen",
|
||||
"header": "Lokale manuelle Änderungen:",
|
||||
"legal-basis": "Grund wurde geändert",
|
||||
@ -377,7 +379,7 @@
|
||||
"resized": "Schwärzungsbereich wurde geändert"
|
||||
},
|
||||
"annotation-engines": {
|
||||
"dictionary": "{isHint, select, true{Hinweis} other{Schwärzung}} basiert auf Wörterbuch",
|
||||
"dictionary": "Basiert auf Wörterbuch",
|
||||
"dossier-dictionary": "Basiert auf Dossier-Wörterbuch",
|
||||
"imported": "Importiert",
|
||||
"ner": "Basiert auf KI-Modell",
|
||||
@ -393,9 +395,6 @@
|
||||
"skipped": "Ignorierte Schwärzung",
|
||||
"text-highlight": "Markierung"
|
||||
},
|
||||
"annotation": {
|
||||
"pending": "(Analyse steht aus)"
|
||||
},
|
||||
"annotations": "Annotationen",
|
||||
"archived-dossiers-listing": {
|
||||
"no-data": {
|
||||
@ -419,7 +418,7 @@
|
||||
"approver": "Genehmiger",
|
||||
"approvers": "Genehmiger",
|
||||
"make-approver": "Zum Genehmiger machen",
|
||||
"no-reviewers": "Es wurden noch keine Prüfer zum Team hinzugefügt.",
|
||||
"no-reviewers": "Es wurden noch keine Mitglieder zum Dossier hinzugefügt, die nur die Prüfer-Berechtigung haben.",
|
||||
"reviewers": "Prüfer",
|
||||
"search": "Suche...",
|
||||
"single-user": "Besitzer"
|
||||
@ -571,7 +570,7 @@
|
||||
},
|
||||
"search": "Nach Name suchen...",
|
||||
"table-col-names": {
|
||||
"column-labels": "Column labels",
|
||||
"column-labels": "Spaltenbeschriftungen",
|
||||
"name": "Name",
|
||||
"number-of-lines": "Zeilenzahl",
|
||||
"version": "Version"
|
||||
@ -640,14 +639,14 @@
|
||||
},
|
||||
"confirmation-dialog": {
|
||||
"approve-file": {
|
||||
"confirmationText": "Approve anyway",
|
||||
"denyText": "No, cancel",
|
||||
"question": "Do you still want to approve the {questionLength, plural, one{document} other{documents}}?",
|
||||
"title": "Approval warning",
|
||||
"confirmationText": "Trotzdem genehmigen",
|
||||
"denyText": "Nein, abbrechen",
|
||||
"question": "Dieses Dokument enthält ungesehene Änderungen, die sich durch die Reanalyse ergeben haben.<br><br>Möchten Sie es trotzdem freigeben?",
|
||||
"title": "Warnung!",
|
||||
"warning-reason": {
|
||||
"legal-basis-missing": "Legal basis missing",
|
||||
"pending-changes": "Pending Changes",
|
||||
"unmapped-justification": "Unmapped justification"
|
||||
"legal-basis-missing": "Rechtsgrundlage fehlt",
|
||||
"pending-changes": "Änderungen stehen aus",
|
||||
"unmapped-justification": "Nicht gemappte Begründung"
|
||||
}
|
||||
},
|
||||
"assign-file-to-me": {
|
||||
@ -664,7 +663,7 @@
|
||||
"delete-dossier": {
|
||||
"confirmation-text": "{dossiersCount, plural, one{Dossier} other{Dossiers}} löschen",
|
||||
"deny-text": "{dossiersCount, plural, one{Dossier} other{Dossiers}} behalten",
|
||||
"question": "Möchten Sie dieses Dokument wirklich löschen?",
|
||||
"question": "Möchten Sie {dossiersCount, plural, one{dieses Dossier} other{diese Dossiers}} wirklich löschen?",
|
||||
"title": "{dossiersCount, plural, one{{dossierName}} other{selected dossiers}} löschen"
|
||||
},
|
||||
"delete-file": {
|
||||
@ -673,7 +672,7 @@
|
||||
},
|
||||
"delete-items": {
|
||||
"question": "Möchten Sie {itemsCount, plural, one{dieses Element} other{diese Elemente}} wirklich löschen?",
|
||||
"title": "{itemsCount, plural, one{{name}} other{Ausgewählte Elemente}} löschen"
|
||||
"title": "{itemsCount, plural, one{{name}} other{selected items}} löschen"
|
||||
},
|
||||
"delete-justification": {
|
||||
"question": "Möchten Sie {count, plural, one{diese Begründung} other{diese Begründungen}} wirklich löschen?",
|
||||
@ -721,7 +720,7 @@
|
||||
"key": "Typ"
|
||||
},
|
||||
"table-header": {
|
||||
"title": "{length} Standard{length, plural, one{farbe} other{farben}}"
|
||||
"title": "{length} Standard{length, plural, one{Farbe} other{Farben}}"
|
||||
},
|
||||
"types": {
|
||||
"analysisColor": "Analyse",
|
||||
@ -763,7 +762,7 @@
|
||||
"compare": {
|
||||
"compare": "Vergleichen",
|
||||
"select-dictionary": "Wörterbuch auswählen",
|
||||
"select-dossier": "Wörterbuch auswählen",
|
||||
"select-dossier": "Dossier auswählen",
|
||||
"select-dossier-template": "Dossier-Vorlage auswählen"
|
||||
},
|
||||
"download": "Aktuelle Einträge herunterladen",
|
||||
@ -853,7 +852,7 @@
|
||||
"date": "Datum",
|
||||
"image": "Bild",
|
||||
"number": "Nummer",
|
||||
"text": "Freier Text"
|
||||
"text": "Text"
|
||||
},
|
||||
"dossier-attributes-listing": {
|
||||
"action": {
|
||||
@ -945,7 +944,7 @@
|
||||
},
|
||||
"dossier-overview": {
|
||||
"approve": "Freigeben",
|
||||
"approve-disabled": "Sie können die Datei erst freigeben, wenn Sie anhand der neusten Regeln und Begriffe in den Systemwörterbüchern analysiert wurde.",
|
||||
"approve-disabled": "Sie können die Datei erst freigeben, wenn sie auf Basis der aktuellen Wörterbücher analysiert wurde.",
|
||||
"assign-approver": "Genehmiger zuweisen",
|
||||
"assign-me": "Mir zuweisen",
|
||||
"assign-reviewer": "Benutzer zuweisen",
|
||||
@ -988,8 +987,8 @@
|
||||
}
|
||||
},
|
||||
"filters": {
|
||||
"label": "Name des Dokuments",
|
||||
"search": "Name des Dokuments..."
|
||||
"label": "Dokumentname",
|
||||
"search": "Name des Dokuments eingeben..."
|
||||
},
|
||||
"header-actions": {
|
||||
"download-csv": "CSV-Bericht herunterladen",
|
||||
@ -1019,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",
|
||||
@ -1095,6 +1094,14 @@
|
||||
"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",
|
||||
@ -1129,14 +1136,6 @@
|
||||
"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.",
|
||||
@ -1168,7 +1167,7 @@
|
||||
"delta-preview": "Delta-PDF",
|
||||
"flatten": "Verflachte PDF",
|
||||
"label": "{length} Dokumenten{length, plural, one{typ} other{typen}}",
|
||||
"optimized-preview": "Optimized Preview PDF",
|
||||
"optimized-preview": "Optimierte Vorschau-PDF",
|
||||
"original": "Optimierte PDF",
|
||||
"preview": "Vorschau-PDF",
|
||||
"redacted": "Geschwärzte PDF",
|
||||
@ -1234,10 +1233,12 @@
|
||||
"save": "Speichern",
|
||||
"title": "{label} bearbeiten"
|
||||
},
|
||||
"entries-count": "",
|
||||
"false-positives": "Falsch-Positive ({count})",
|
||||
"false-recommendations": "Falsche Empfehlungen ({count})",
|
||||
"to-redact": "Schwärzungen ({count})"
|
||||
"entries": "{length} {length, plural, one{Eintrag} other{Einträge}}",
|
||||
"false-positive-entries": "{length} {length, plural, one{Falsch-Positiver} other{Falsch-Positive}}",
|
||||
"false-positives": "Falsch-Positive",
|
||||
"false-recommendation-entries": "{length} {length, plural, one{falsche Empfehlung} other{falsche Empfehlungen}}",
|
||||
"false-recommendations": "Falsche Empfehlungen",
|
||||
"to-redact": "Schwärzungen"
|
||||
},
|
||||
"general-info": {
|
||||
"form": {
|
||||
@ -1263,7 +1264,7 @@
|
||||
"choose-download": "Stellen Sie Ihr Download-Paket zusammen:",
|
||||
"dictionary": "Wörterbücher",
|
||||
"dossier-attributes": "Dossier-Attribute",
|
||||
"dossier-dictionary": "Wörterbücher",
|
||||
"dossier-dictionary": "Dossier-Einträge",
|
||||
"dossier-info": "Dossier-Info",
|
||||
"download-package": "Download-Paket",
|
||||
"general-info": "Allgemeine Informationen",
|
||||
@ -1281,11 +1282,14 @@
|
||||
"content": {
|
||||
"comment": "Kommentar",
|
||||
"comment-placeholder": "Bemerkungen oder Notizen hinzufügen...",
|
||||
"custom-rectangle": "Bereichsschwärzung",
|
||||
"imported": "Importierte Schwärzung",
|
||||
"legal-basis": "Rechtsgrundlage",
|
||||
"options": {
|
||||
"in-document": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
"in-dossier": {
|
||||
"description": "Schwärzung in jedem Dokument in {dossierName} bearbeiten.",
|
||||
"extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen",
|
||||
"label": "Typ in Dossier ändern"
|
||||
},
|
||||
"only-here": {
|
||||
"description": "Bearbeiten Sie die Schwärzung nur an dieser Stelle im Dokument.",
|
||||
@ -1328,6 +1332,15 @@
|
||||
"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."
|
||||
@ -1341,28 +1354,19 @@
|
||||
"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-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-dossier": {
|
||||
"action": "Zurück zur Übersicht",
|
||||
"label": "Das Dossier dieser Datei wurde gelöscht!"
|
||||
}
|
||||
},
|
||||
"file-preview": {
|
||||
@ -1380,6 +1384,12 @@
|
||||
},
|
||||
"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",
|
||||
@ -1390,12 +1400,6 @@
|
||||
"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": {
|
||||
@ -1471,7 +1475,7 @@
|
||||
"delete": "Attribut löschen",
|
||||
"edit": "Attribut bearbeiten"
|
||||
},
|
||||
"add-new": "Neue Attribute",
|
||||
"add-new": "Neues Attribut",
|
||||
"bulk-actions": {
|
||||
"delete": "Ausgewählte Attribute löschen"
|
||||
},
|
||||
@ -1490,7 +1494,7 @@
|
||||
"search": "Nach Attribut-Namen suchen...",
|
||||
"table-col-names": {
|
||||
"csv-column": "CSV-Spalte",
|
||||
"displayed-in-file-list": "In Dokumentenliste",
|
||||
"displayed-in-file-list": "In Dokumentenliste anzeigen",
|
||||
"filterable": "Filterbar",
|
||||
"name": "Name",
|
||||
"primary": "Primärattribut",
|
||||
@ -1521,7 +1525,7 @@
|
||||
},
|
||||
"last-assignee": "{status, select, APPROVED{Freigegeben} UNDER_APPROVAL{Geprüft} other{Zuletzt geprüft}} von:",
|
||||
"no-data": {
|
||||
"title": "An dieser Seite wurden keine Änderungen vorgenommen."
|
||||
"title": "Auf dieser Seite wurden keine Änderungen vorgenommen."
|
||||
},
|
||||
"quick-nav": {
|
||||
"jump-first": "Zur ersten Seite springen",
|
||||
@ -1529,7 +1533,7 @@
|
||||
},
|
||||
"reanalyse-notification": "Reanalyse starten",
|
||||
"redacted": "Vorschau",
|
||||
"redacted-tooltip": "Die Vorschau ist eine Vorschau der finalen geschwärzten Version und zeigt nur Schwärzungen. Sie ist nur verfügbar, wenn keine Änderungen oder Reanalysen ausstehen.",
|
||||
"redacted-tooltip": "Die Vorschau ist eine Vorschau der finalen geschwärzten Version und zeigt nur Schwärzungen.",
|
||||
"standard": "Standard",
|
||||
"standard-tooltip": "Standard zeigt alle Annotationstypen und ermöglicht die Bearbeitung.",
|
||||
"tabs": {
|
||||
@ -1540,13 +1544,13 @@
|
||||
"label": "Liste",
|
||||
"no-annotations": "Es sind keine Annotationen vorhanden.",
|
||||
"page-is": "Diese Seite ist",
|
||||
"reset": "setzen Sie die Filter",
|
||||
"reset": "Setzen Sie die Filter zurück",
|
||||
"select": "Auswählen",
|
||||
"select-all": "Alle",
|
||||
"select-none": "Keine",
|
||||
"show-skipped": "Ignorierte im Dokument anzeigen",
|
||||
"the-filters": "zurück.",
|
||||
"wrong-filters": "Keine Annotationen für die ausgewählte Filterkombination. Bitte ändern Sie die Auswahl oder"
|
||||
"the-filters": "Filter",
|
||||
"wrong-filters": "Keine Annotationen für die ausgewählte Filterkombination. Bitte ändern Sie die Auswahl oder setzen die Filter zurück."
|
||||
},
|
||||
"document-info": {
|
||||
"close": "Datei-Info schließen",
|
||||
@ -1613,6 +1617,15 @@
|
||||
"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ärzung",
|
||||
"updated": "Aktualisiert"
|
||||
},
|
||||
"filter-menu": {
|
||||
"filter-options": "Filteroptionen",
|
||||
"filter-types": "Filter",
|
||||
@ -1622,15 +1635,6 @@
|
||||
"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",
|
||||
@ -1639,7 +1643,7 @@
|
||||
"empty": "Leer",
|
||||
"filter-by": "Filter:",
|
||||
"needs-work": "Annotationen",
|
||||
"people": "Dossier-Mitglieder"
|
||||
"people": "Dossier-Mitglied(er)"
|
||||
},
|
||||
"general-config-screen": {
|
||||
"actions": {
|
||||
@ -1654,7 +1658,7 @@
|
||||
"auth": "Authentifizierung aktivieren",
|
||||
"change-credentials": "Anmeldedaten ändern",
|
||||
"envelope-from": "Envelope von",
|
||||
"envelope-from-hint": "Infotext zum Feld „Ausgangsadresse“.",
|
||||
"envelope-from-hint": "Infotext zum Feld „Envelope von“.",
|
||||
"envelope-from-placeholder": "Envelope-Absenderadresse",
|
||||
"from": "Von",
|
||||
"from-display-name": "Name für Absender",
|
||||
@ -1922,6 +1926,13 @@
|
||||
"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",
|
||||
@ -1935,7 +1946,6 @@
|
||||
"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",
|
||||
@ -1953,6 +1963,7 @@
|
||||
"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",
|
||||
@ -1960,13 +1971,6 @@
|
||||
},
|
||||
"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 +2062,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": {
|
||||
@ -2082,10 +2086,6 @@
|
||||
"edit-text": "Text bearbeiten",
|
||||
"legal-basis": "Rechtsgrundlage",
|
||||
"options": {
|
||||
"in-document": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Fügen Sie die Schwärzung zu jedem Dokument in {dossierName} hinzu.",
|
||||
"extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen",
|
||||
@ -2101,8 +2101,7 @@
|
||||
"revert-text": "Zurück zu ursprünglicher Auswahl",
|
||||
"type": "Typ",
|
||||
"type-placeholder": "Typ auswählen...",
|
||||
"unchanged": "Ungeändert",
|
||||
"value": ""
|
||||
"unchanged": "Ungeändert"
|
||||
},
|
||||
"title": "Text schwärzen"
|
||||
}
|
||||
@ -2126,10 +2125,6 @@
|
||||
"description-bulk": "",
|
||||
"label": "In diesem Kontext aus dem Dossier entfernen"
|
||||
},
|
||||
"in-document": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Annotieren Sie den Begriff in diesem Dossier nicht.",
|
||||
"description-bulk": "",
|
||||
@ -2170,10 +2165,6 @@
|
||||
"extraOptionLabel": "In alle aktiven und zukünftigen Dossiers übernehmen",
|
||||
"label": "In diesem Kontext aus Dossier entfernen"
|
||||
},
|
||||
"in-document": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Der Begriff wird in keinem Dokument dieses Dossiers {type, select, hint{annotiert} other{automatisch geschwärzt}}.",
|
||||
"description-bulk": "Die ausgewählten Begriffe werden in diesem Dossier nicht {type, select, hint{annotiert} other{automatisch geschwärzt}}.",
|
||||
@ -2316,6 +2307,12 @@
|
||||
"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",
|
||||
@ -2339,12 +2336,6 @@
|
||||
"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": {
|
||||
@ -2418,7 +2409,7 @@
|
||||
},
|
||||
"label": "Papierkorb",
|
||||
"no-data": {
|
||||
"title": "Es gibt noch keine gelöschten Elemente."
|
||||
"title": "Im Papierkorb befinden sich keine gelöschten Elemente."
|
||||
},
|
||||
"no-match": {
|
||||
"title": "Die ausgewählten Filter treffen auf kein Element zu."
|
||||
|
||||
@ -265,7 +265,7 @@
|
||||
"entities": "Entities",
|
||||
"entity-info": "Info",
|
||||
"entity-rule-editor": "Entity rule editor",
|
||||
"false-positive": "False positive",
|
||||
"false-positive": "False positives",
|
||||
"false-recommendations": "False recommendations",
|
||||
"file-attributes": "File attributes",
|
||||
"justifications": "Justifications",
|
||||
@ -376,6 +376,7 @@
|
||||
"removed-manual": "Redaction/Hint removed",
|
||||
"resized": "Redaction area has been modified"
|
||||
},
|
||||
"annotation-content": "{hasRule, select, true {Rule {matchedRule} matched{ruleSymbol}} other {}} {hasReason, select, true {{reason}} other {}} {hasLb, select, true {Legal basis: {legalBasis}} other {}} {hasOverride, select, true {Removed by manual override} other {}} {hasSection, select, true {{shouldLower, plural, =0 {I} other {i}}n section{sectionSymbol} \"{section}\"} other {}}",
|
||||
"annotation-engines": {
|
||||
"dictionary": "Based on dictionary",
|
||||
"dossier-dictionary": "Based on dossier dictionary",
|
||||
@ -642,8 +643,8 @@
|
||||
"approve-file": {
|
||||
"confirmationText": "Approve anyway",
|
||||
"denyText": "No, cancel",
|
||||
"question": "Do you still want to approve the {questionLength, plural, one{document} other{documents}}?",
|
||||
"title": "Approval warning",
|
||||
"question": "This document contains unseen changes that have been added during the reanalysis.<br><br>Do you still want to approve it?",
|
||||
"title": "Warning!",
|
||||
"warning-reason": {
|
||||
"legal-basis-missing": "Legal basis missing",
|
||||
"pending-changes": "Pending Changes",
|
||||
@ -945,7 +946,7 @@
|
||||
},
|
||||
"dossier-overview": {
|
||||
"approve": "Approve",
|
||||
"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.",
|
||||
"approve-disabled": "File can only be approved once it has been analysed with the latest dictionaries.",
|
||||
"assign-approver": "Assign approver",
|
||||
"assign-me": "Assign to me",
|
||||
"assign-reviewer": "Assign user",
|
||||
@ -1235,9 +1236,9 @@
|
||||
"title": "Edit {label}"
|
||||
},
|
||||
"entries-count": "{count} {count, plural, one{entry} other{entries}}",
|
||||
"false-positives": "False positives ({count})",
|
||||
"false-recommendations": "False recommendations ({count})",
|
||||
"to-redact": "Entries ({count})"
|
||||
"false-positives": "False positives",
|
||||
"false-recommendations": "False recommendations",
|
||||
"to-redact": "To redact"
|
||||
},
|
||||
"general-info": {
|
||||
"form": {
|
||||
@ -1289,7 +1290,7 @@
|
||||
},
|
||||
"only-here": {
|
||||
"description": "Edit redaction only at this position in this document.",
|
||||
"label": "Change only here"
|
||||
"label": "Change type only here"
|
||||
}
|
||||
},
|
||||
"reason": "Reason",
|
||||
@ -1546,7 +1547,7 @@
|
||||
"select-none": "None",
|
||||
"show-skipped": "Show skipped in document",
|
||||
"the-filters": "the filters",
|
||||
"wrong-filters": "No annotations for the selected filter combination. Please adjust or"
|
||||
"wrong-filters": "No annotations for the selected filter combination. Please adjust or or reset the filters"
|
||||
},
|
||||
"document-info": {
|
||||
"close": "Close document info",
|
||||
@ -1628,12 +1629,12 @@
|
||||
"hint": "Hints only",
|
||||
"image": "Images",
|
||||
"none": "No annotations",
|
||||
"redaction": "Redacted",
|
||||
"redaction": "Redaction",
|
||||
"updated": "Updated"
|
||||
},
|
||||
"filters": {
|
||||
"assigned-people": "Assignee(s)",
|
||||
"documents-status": "Documents state",
|
||||
"documents-status": "Document state",
|
||||
"dossier-state": "Dossier state",
|
||||
"dossier-templates": "Dossier templates",
|
||||
"empty": "Empty",
|
||||
@ -2013,14 +2014,34 @@
|
||||
"previous": "Prev"
|
||||
},
|
||||
"pdf-viewer": {
|
||||
"header": {
|
||||
"all-annotations-loaded": "All annotations loaded",
|
||||
"compare-button": "Compare",
|
||||
"layers-panel-button": "Layers",
|
||||
"left-panel-button": "Panel",
|
||||
"load-all-annotations": "Load all annotations",
|
||||
"no-outlines-text": "No outlines available",
|
||||
"no-signatures-text": "This document has NO signature fields",
|
||||
"outline-multi-select": "Edit",
|
||||
"outlines-panel-button": "Outlines",
|
||||
"pan-tool-button": "Pan",
|
||||
"rectangle-tool-button": "Rectangle",
|
||||
"rotate-left-button": "Rotate page left",
|
||||
"rotate-right-button": "Rotate page right",
|
||||
"select-tool-button": "Select",
|
||||
"signature-panel-button": "Signatures",
|
||||
"thumbnails-panel-button": "Thumbnails",
|
||||
"toggle-layers": "{active, select, true{Disable} false{Enable} other{}} layout grid",
|
||||
"toggle-readable-redactions": "Show redactions {active, select, true{as in final document} false{in preview color} other{}}",
|
||||
"toggle-tooltips": "{active, select, true{Disable} false{Enable} other{}} annotation tooltips",
|
||||
"zoom-in-button": "Zoom In",
|
||||
"zoom-out-button": "Zoom Out"
|
||||
},
|
||||
"text-popup": {
|
||||
"actions": {
|
||||
"search": "Search for selected text"
|
||||
}
|
||||
},
|
||||
"toggle-layers": "{active, select, true{Disable} false{Enable} other{}} layout grid",
|
||||
"toggle-readable-redactions": "Show redactions {active, select, true{as in final document} false{in preview color} other{}}",
|
||||
"toggle-tooltips": "{active, select, true{Disable} false{Enable} other{}} annotation tooltips"
|
||||
}
|
||||
},
|
||||
"permissions-screen": {
|
||||
"dossier": {
|
||||
@ -2158,14 +2179,14 @@
|
||||
"comment-placeholder": "Add remarks or notes...",
|
||||
"options": {
|
||||
"do-not-recommend": {
|
||||
"description": "Do not recommend the selected {isImage, select, image{image} other{term}} in any document of this dossier.",
|
||||
"description-bulk": "Do not recommend the selected {isImage, select, image{images} other{terms}} in any document of this dossier.",
|
||||
"description": "Do not recommend the selected term in any document of this dossier.",
|
||||
"description-bulk": "Do not recommend the selected terms in any document of this dossier.",
|
||||
"extraOptionLabel": "Apply to all active and future dossiers",
|
||||
"label": "Remove from dossier"
|
||||
},
|
||||
"false-positive": {
|
||||
"description": "Mark this redaction as a false-positive. The {isImage, select, image{image} other{term}} will not be redacted in this dossier if it occurs in the same context.",
|
||||
"description-bulk": "Mark these redactions as false-positives. The {isImage, select, image{images} other{terms}} will not be redacted in this dossier if they occur in the same context.",
|
||||
"description": "Mark this redaction as a false-positive. The term will not be redacted in this dossier if it occurs in the same context.",
|
||||
"description-bulk": "Mark these redactions as false-positives. The terms will not be redacted in this dossier if they occur in the same context.",
|
||||
"extraOptionDescription": "Dossier template access is required to reverse this action. As a regular user you can only reverse it for this dossier.",
|
||||
"extraOptionLabel": "Apply to all active and future dossiers",
|
||||
"label": "Remove from dossier in this context"
|
||||
@ -2175,15 +2196,15 @@
|
||||
"label": "Remove from document"
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Do not {type, select, hint{annotate} other{auto-redact}} the selected {isImage, select, image{image} other{term}} in any document of this dossier.",
|
||||
"description-bulk": "Do not {type, select, hint{annotate} other{auto-redact}} the selected {isImage, select, image{images} other{terms}} in this dossier.",
|
||||
"description": "Do not {type, select, hint{annotate} other{auto-redact}} the selected term in any document of this dossier.",
|
||||
"description-bulk": "Do not {type, select, hint{annotate} other{auto-redact}} the selected terms in this dossier.",
|
||||
"extraOptionLabel": "Apply to all active and future dossiers",
|
||||
"label": "Remove from dossier",
|
||||
"label-bulk": "Remove from dossier"
|
||||
},
|
||||
"only-here": {
|
||||
"description": "Do not {type, select, hint{annotate} other{redact}} the {isImage, select, image{image} other{term}} at this position in the current document.",
|
||||
"description-bulk": "Do not {type, select, hint{annotate} other{redact}} the selected {isImage, select, image{images} other{terms}} at this position in the current document.",
|
||||
"description": "Do not {type, select, hint{annotate} other{redact}} the term at this position in the current document.",
|
||||
"description-bulk": "Do not {type, select, hint{annotate} other{redact}} the selected terms at this position in the current document.",
|
||||
"label": "Remove here"
|
||||
}
|
||||
}
|
||||
@ -2535,10 +2556,6 @@
|
||||
"view-as": "View as:",
|
||||
"workflow": "Workflow"
|
||||
},
|
||||
"viewer-header": {
|
||||
"all-annotations-loaded": "All annotations loaded",
|
||||
"load-all-annotations": "Load all annotations"
|
||||
},
|
||||
"watermark-screen": {
|
||||
"action": {
|
||||
"change-success": "Watermark has been updated.",
|
||||
@ -2567,6 +2584,10 @@
|
||||
"orientation": "Orientation",
|
||||
"text-label": "Watermark text",
|
||||
"text-placeholder": "Enter text"
|
||||
},
|
||||
"pagination": {
|
||||
"landscape": "Landscape",
|
||||
"portrait": "Portrait"
|
||||
}
|
||||
},
|
||||
"watermarks-listing": {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -37,7 +37,7 @@
|
||||
"save-and-add-members": "Save and edit team"
|
||||
},
|
||||
"errors": {
|
||||
"dossier-already-exists": "Dossier with this name already exists! If it is in the trash, you need to permanently delete it first to re-use the name. If it is an active or archived dossier, please choose a different name."
|
||||
"dossier-already-exists": "<strong>Dossier name already exists.</strong>\n<ul><li>If the dossier is in trash, you can delete it permanently to reuse the name.</li><li>If the dossier is active or archived, please use a different name.</li></ul>"
|
||||
},
|
||||
"form": {
|
||||
"description": {
|
||||
@ -159,8 +159,8 @@
|
||||
"template-and-dossier-dictionaries": ""
|
||||
},
|
||||
"success": {
|
||||
"create": "Entity added!",
|
||||
"edit": "Entity updated. Please note that other users need to refresh the browser to see your changes."
|
||||
"create": "Success: Entity created.",
|
||||
"edit": "<strong>Success: Entity updated.</strong><br><br>Please ask the users to refresh the browser to see the changes."
|
||||
}
|
||||
},
|
||||
"add-edit-file-attribute": {
|
||||
@ -204,7 +204,7 @@
|
||||
},
|
||||
"error": {
|
||||
"email-already-used": "This e-mail address is already in use by a different user!",
|
||||
"generic": "Failed to save user!"
|
||||
"generic": "Failed to save user."
|
||||
},
|
||||
"form": {
|
||||
"account-setup": "User account setup",
|
||||
@ -265,7 +265,7 @@
|
||||
"entities": "Entities",
|
||||
"entity-info": "Info",
|
||||
"entity-rule-editor": "Entity rule editor",
|
||||
"false-positive": "False positive",
|
||||
"false-positive": "False positives",
|
||||
"false-recommendations": "False recommendations",
|
||||
"file-attributes": "File attributes",
|
||||
"justifications": "Justifications",
|
||||
@ -303,7 +303,7 @@
|
||||
},
|
||||
"remove": {
|
||||
"error": "Failed to remove dictionary entry: {error}",
|
||||
"success": "Dictionary entry removed!"
|
||||
"success": "Dictionary entry removed"
|
||||
},
|
||||
"undo": {
|
||||
"error": "Failed to undo: {error}",
|
||||
@ -313,15 +313,15 @@
|
||||
"manual-redaction": {
|
||||
"add": {
|
||||
"error": "Failed to save annotation: {error}",
|
||||
"success": "Annotation added!"
|
||||
"success": "Annotation added"
|
||||
},
|
||||
"force-hint": {
|
||||
"error": "Failed to save hint: {error}",
|
||||
"success": "Hint added!"
|
||||
"success": "Hint added"
|
||||
},
|
||||
"force-redaction": {
|
||||
"error": "Failed to save annotation: {error}",
|
||||
"success": "Annotation added!"
|
||||
"success": "Annotation added"
|
||||
},
|
||||
"recategorize-annotation": {
|
||||
"error": "",
|
||||
@ -333,11 +333,11 @@
|
||||
},
|
||||
"remove-hint": {
|
||||
"error": "Failed to remove hint: {error}",
|
||||
"success": "Hint removed!"
|
||||
"success": "Hint removed"
|
||||
},
|
||||
"remove": {
|
||||
"error": "Failed to remove annotation: {error}",
|
||||
"success": "Annotation removed!"
|
||||
"success": "Annotation removed"
|
||||
},
|
||||
"undo": {
|
||||
"error": "Failed to undo: {error}",
|
||||
@ -376,6 +376,7 @@
|
||||
"removed-manual": "Annotation/Hint removed",
|
||||
"resized": "Annotation area has been modified"
|
||||
},
|
||||
"annotation-content": "{hasRule, select, true {Rule {matchedRule} matched{ruleSymbol}} other {}} {hasReason, select, true {{reason}} other {}} {hasLb, select, true {Legal basis: {legalBasis}} other {}} {hasOverride, select, true {Removed by manual override} other {}} {hasSection, select, true {{shouldLower, plural, =0 {I} other {i}}n section{sectionSymbol} \"{section}\"} other {}}",
|
||||
"annotation-engines": {
|
||||
"dictionary": "{isHint, select, true{Hint} other{Annotation}} based on dictionary",
|
||||
"dossier-dictionary": "Annotation based on dossier dictionary",
|
||||
@ -481,7 +482,7 @@
|
||||
},
|
||||
"auth-error": {
|
||||
"heading": "Your user is successfully logged in but has no role assigned yet. Please contact your DocuMine administrator to assign appropriate roles.",
|
||||
"heading-with-link": "Your user is successfully logged in but has no role assigned yet. Please contact <a href={adminUrl} target=_blank >your DocuMine administrator</a> to assign appropriate roles!",
|
||||
"heading-with-link": "Your user is successfully logged in but has no role assigned yet. Please ask <a href={adminUrl} target=_blank >your DocuMine administrator</a> to assign a role to you.",
|
||||
"heading-with-name": "Your user is successfully logged in but has no role assigned yet. Please contact {adminName} to assign appropriate roles.",
|
||||
"heading-with-name-and-link": "Your user is successfully logged in but has no role assigned yet. Please contact <a href={adminUrl} target=_blank >{adminName}</a> to assign appropriate roles.",
|
||||
"logout": "Logout"
|
||||
@ -599,22 +600,22 @@
|
||||
"checkbox": {
|
||||
"documents": "All documents will be archived and cannot be put back to active"
|
||||
},
|
||||
"details": "Restoring an archived dossier is not possible anymore, once it got archived.",
|
||||
"details": "Be aware that archiving is an irreversible action. Documents archived will no longer be available for active use.",
|
||||
"title": "Archive {dossierName}",
|
||||
"toast-error": "Please confirm that you understand the ramifications of your action!",
|
||||
"toast-error": "Please confirm that you understand the consequences of this action.",
|
||||
"warning": "Are you sure you want to archive the dossier?"
|
||||
},
|
||||
"confirm-delete-attribute": {
|
||||
"cancel": "Keep {count, plural, one{attribute} other{attributes}}",
|
||||
"delete": "Delete {count, plural, one{attribute} other{attributes}}",
|
||||
"dossier-impacted-documents": "All dossiers based on this template will be affected",
|
||||
"dossier-lost-details": "All values for this attribute will be lost",
|
||||
"dossier-impacted-documents": "This action will affect all dossiers that use this template.",
|
||||
"dossier-lost-details": "The attribute values entered by users on document level will be lost.",
|
||||
"file-impacted-documents": "All documents {count, plural, one{it is} other{they are}} used on will be impacted",
|
||||
"file-lost-details": "All inputted details on the documents will be lost",
|
||||
"impacted-report": "{reportsCount} reports use the placeholder for this attribute and need to be adjusted",
|
||||
"file-lost-details": "All information entered by users on document level will be lost.",
|
||||
"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 ramifications of your action!",
|
||||
"warning": "Warning: this cannot be undone!"
|
||||
"toast-error": "Please confirm that you understand the consequences of this action.",
|
||||
"warning": "Warning: This action cannot be undone!"
|
||||
},
|
||||
"confirm-delete-dossier-state": {
|
||||
"cancel": "Cancel",
|
||||
@ -622,9 +623,9 @@
|
||||
"delete-replace": "Delete and replace",
|
||||
"form": {
|
||||
"state": "Replace state",
|
||||
"state-placeholder": "Choose another state"
|
||||
"state-placeholder": "Select another state"
|
||||
},
|
||||
"question": "Replace the {count, plural, one{dossier's} other{dossiers'}} state with another state",
|
||||
"question": "Select another state to replace the current {count, plural, one{dossier} other{dossier}} state",
|
||||
"success": "Successfully deleted state!",
|
||||
"title": "Delete dossier state",
|
||||
"warning": "The {name} state is assigned to {count} {count, plural, one{dossier} other{dossiers}}."
|
||||
@ -635,15 +636,15 @@
|
||||
"impacted-documents": "All documents pending review from the {usersCount, plural, one{user} other{users}} will be impacted",
|
||||
"impacted-dossiers": "{dossiersCount} {dossiersCount, plural, one{dossier} other{dossiers}} will be impacted",
|
||||
"title": "Delete {usersCount, plural, one{user} other{users}} from workspace",
|
||||
"toast-error": "Please confirm that you understand the ramifications of your action!",
|
||||
"toast-error": "Please confirm that you understand the consequences of this action.",
|
||||
"warning": "Warning: this cannot be undone!"
|
||||
},
|
||||
"confirmation-dialog": {
|
||||
"approve-file": {
|
||||
"confirmationText": "Approve anyway",
|
||||
"denyText": "No, cancel",
|
||||
"question": "Do you still want to approve the {questionLength, plural, one{document} other{documents}}?",
|
||||
"title": "Approval warning",
|
||||
"question": "This document contains unseen changes that have been added during the reanalysis.\n<br><br>Do you still want to approve it?",
|
||||
"title": "Warning!",
|
||||
"warning-reason": {
|
||||
"legal-basis-missing": "Legal basis missing",
|
||||
"pending-changes": "Pending Changes",
|
||||
@ -653,19 +654,19 @@
|
||||
"assign-file-to-me": {
|
||||
"question": {
|
||||
"multiple": "At least one document is currently assigned to someone else. Are you sure you want to replace them and assign yourself to these documents?",
|
||||
"single": "This document is currently assigned to someone else. Are you sure you want to replace it and assign yourself to this document?"
|
||||
"single": "This document is currently assigned to another user. Do you still want to assign the files to yourself?"
|
||||
},
|
||||
"title": "Re-assign user"
|
||||
},
|
||||
"compare-file": {
|
||||
"question": "<strong>Warning!</strong> <br><br> Number of pages does not match, current document has <strong>{currentDocumentPageCount} page(s)</strong>. Uploaded document has <strong>{compareDocumentPageCount} page(s)</strong>. <br><br> Do you wish to proceed?",
|
||||
"question": "<strong>Warning: page count mismatch</strong><br><br> Current document: \n<strong>{currentDocumentPageCount} page(s)</strong>.<br><br>Upload document: \n<strong>{compareDocumentPageCount} page(s)</strong>. <br><be>This appears to be a different document. Do you wish to proceed?",
|
||||
"title": "Compare with file: {fileName}"
|
||||
},
|
||||
"delete-dossier": {
|
||||
"confirmation-text": "Delete {dossiersCount, plural, one{dossier} other{dossiers}}",
|
||||
"deny-text": "Keep {dossiersCount, plural, one{dossier} other{dossiers}}",
|
||||
"question": "Are you sure you want to delete {dossiersCount, plural, one{this dossier} other{these dossiers}}?",
|
||||
"title": "Delete {dossiersCount, plural, one{{dossierName}} other{Selected Dossiers}}"
|
||||
"title": "Delete {dossiersCount, plural, one{{dossierName}} other{selected dossiers}}"
|
||||
},
|
||||
"delete-file": {
|
||||
"question": "Do you wish to proceed?",
|
||||
@ -688,23 +689,23 @@
|
||||
},
|
||||
"unsaved-changes": {
|
||||
"confirmation-text": "Save and leave",
|
||||
"details": "If you leave the tab without saving, all the unsaved changes will be lost.",
|
||||
"details": "Please save your changes. If you leave now, any unsaved progress will be lost.",
|
||||
"discard-changes-text": "DISCARD CHANGES",
|
||||
"question": "Are you sure you want to leave the tab? You have unsaved changes.",
|
||||
"question": "Do you still want to leave the tab?",
|
||||
"title": "You have unsaved changes"
|
||||
},
|
||||
"upload-report-template": {
|
||||
"alternate-confirmation-text": "Upload as multi-file report",
|
||||
"confirmation-text": "Upload as single-file report",
|
||||
"deny-text": "Cancel upload",
|
||||
"question": "Please choose if <b>{fileName}</b> is a single or multi-file report template",
|
||||
"question": "Please indicate if <b>{fileName}</b> is a single or multi-file report template",
|
||||
"title": "Report template upload"
|
||||
}
|
||||
},
|
||||
"content": "Reason",
|
||||
"dashboard": {
|
||||
"empty-template": {
|
||||
"description": "This template does not contain any dossiers. Start by creating a dossier to use it on.",
|
||||
"description": "This template does not contain any dossiers. Create a dossier that applies this ruleset.",
|
||||
"new-dossier": "New dossier"
|
||||
},
|
||||
"greeting": {
|
||||
@ -768,13 +769,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": "Something went wrong... 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 update.",
|
||||
"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!"
|
||||
}
|
||||
@ -784,11 +785,11 @@
|
||||
"actions": {
|
||||
"back": "Back",
|
||||
"cancel": "Cancel",
|
||||
"certificate-not-valid-error": "Uploaded certificate is not valid!",
|
||||
"certificate-not-valid-error": "Uploaded certificate is invalid.",
|
||||
"continue": "Continue",
|
||||
"save": "Save configurations",
|
||||
"save-error": "Failed to save digital signature!",
|
||||
"save-success": "Digital signature certificate successfully saved!"
|
||||
"save-success": "Digital signature certificate saved successfully"
|
||||
},
|
||||
"forms": {
|
||||
"kms": {
|
||||
@ -810,11 +811,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"
|
||||
}
|
||||
},
|
||||
@ -832,7 +833,7 @@
|
||||
"remove": "Remove",
|
||||
"save": "Save changes",
|
||||
"save-error": "Failed to save digital signature!",
|
||||
"save-success": "Digital signature certificate successfully saved!"
|
||||
"save-success": "No digital signature certificate available.<br/>Please configure a certificate to sign redacted documents."
|
||||
},
|
||||
"no-data": {
|
||||
"action": "Configure certificate",
|
||||
@ -884,7 +885,7 @@
|
||||
"dossier-details": {
|
||||
"assign-members": "Assign members",
|
||||
"collapse": "Hide details",
|
||||
"document-status": "Document status",
|
||||
"document-status": "Document processing status",
|
||||
"edit-owner": "Edit owner",
|
||||
"expand": "Show details",
|
||||
"members": "Members",
|
||||
@ -896,7 +897,7 @@
|
||||
"add-new": "New dossier",
|
||||
"archive": {
|
||||
"action": "Archive dossier",
|
||||
"archive-failed": "Failed to archive dossier {dossierName}!",
|
||||
"archive-failed": "Failed to archive dossier {dossierName}.",
|
||||
"archive-succeeded": "Successfully archived dossier {dossierName}."
|
||||
},
|
||||
"delete": {
|
||||
@ -1235,9 +1236,9 @@
|
||||
"title": ""
|
||||
},
|
||||
"entries-count": "{count} {count, plural, one{entry} other{entries}}",
|
||||
"false-positives": "False positives ({count})",
|
||||
"false-recommendations": "False recommendations ({count})",
|
||||
"to-redact": "To redact ({count})"
|
||||
"false-positives": "False positives",
|
||||
"false-recommendations": "False recommendations",
|
||||
"to-redact": "To redact"
|
||||
},
|
||||
"general-info": {
|
||||
"form": {
|
||||
@ -1367,12 +1368,12 @@
|
||||
},
|
||||
"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",
|
||||
@ -1392,7 +1393,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!"
|
||||
}
|
||||
},
|
||||
@ -1428,7 +1429,7 @@
|
||||
"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-sample-data-for": "No sample data for {column}.",
|
||||
@ -1449,7 +1450,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"
|
||||
},
|
||||
@ -1477,8 +1478,8 @@
|
||||
},
|
||||
"configurations": "Configurations",
|
||||
"error": {
|
||||
"conflict": "File-Attribute with this name already exists!",
|
||||
"generic": "Failed to add file attribute"
|
||||
"conflict": "File attribute name already exists. Please try another name.",
|
||||
"generic": "Failed to add file attribute."
|
||||
},
|
||||
"no-data": {
|
||||
"title": "There are no file attributes yet."
|
||||
@ -1494,7 +1495,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"
|
||||
},
|
||||
@ -1508,20 +1509,20 @@
|
||||
"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 extraction",
|
||||
"excluded-from-redaction": "excluded",
|
||||
"excluded-from-redaction": "Excluded",
|
||||
"fullscreen": "Full screen (F)",
|
||||
"get-tables": "Draw tables",
|
||||
"highlights": {
|
||||
"convert": "Convert earmarks",
|
||||
"remove": "Remove earmarks"
|
||||
},
|
||||
"last-assignee": "Last assignee",
|
||||
"last-assignee": "{status, select, APPROVED{Approved} UNDER_APPROVAL{Reviewed} other{Last reviewed}} by:",
|
||||
"no-data": {
|
||||
"title": "This page does not contain annotations for the selected component or filter."
|
||||
"title": "There have been no changes to this page."
|
||||
},
|
||||
"quick-nav": {
|
||||
"jump-first": "Jump to first page",
|
||||
@ -1538,7 +1539,7 @@
|
||||
"jump-to-next": "Jump to next",
|
||||
"jump-to-previous": "Jump to previous",
|
||||
"label": "Workload",
|
||||
"no-annotations": "There are no annotations for the selected component. \n",
|
||||
"no-annotations": "There are no annotations for the selected component.\n",
|
||||
"page-is": "This page is",
|
||||
"reset": "reset",
|
||||
"select": "Select",
|
||||
@ -1546,7 +1547,7 @@
|
||||
"select-none": "None",
|
||||
"show-skipped": "Show skipped in document",
|
||||
"the-filters": "the filters",
|
||||
"wrong-filters": "No annotations for the selected filter combination. Please adjust or"
|
||||
"wrong-filters": "No annotations for the selected filter combination. Please adjust or reset the filters"
|
||||
},
|
||||
"document-info": {
|
||||
"close": "Close document info",
|
||||
@ -1578,7 +1579,7 @@
|
||||
}
|
||||
},
|
||||
"text-highlights": "Earmarks",
|
||||
"text-highlights-tooltip": "Shows all text-earmarks and allows removing or importing them as components",
|
||||
"text-highlights-tooltip": "Earmark allows removing text highlights or converting them into redactions.",
|
||||
"toggle-analysis": {
|
||||
"disable": "Disable extraction",
|
||||
"enable": "Enable for extraction",
|
||||
@ -1587,7 +1588,7 @@
|
||||
},
|
||||
"file-status": {
|
||||
"analyse": "Analyzing",
|
||||
"approved": "Done",
|
||||
"approved": "Approved",
|
||||
"error": "Re-processing required",
|
||||
"figure-detection-analyzing": "",
|
||||
"full-processing": "Processing",
|
||||
@ -1618,7 +1619,7 @@
|
||||
"filter-types": "Filter",
|
||||
"label": "Filter",
|
||||
"pages-without-annotations": "Only pages without annotations",
|
||||
"redaction-changes": "Only annotations with changes",
|
||||
"redaction-changes": "Only annotations with local manual changes",
|
||||
"unseen-pages": "Only annotations on unseen pages",
|
||||
"with-comments": "Only annotations with comments"
|
||||
},
|
||||
@ -1693,7 +1694,7 @@
|
||||
"title": "System preferences"
|
||||
},
|
||||
"test": {
|
||||
"error": "Test e-mail could not be sent! Please revise the e-mail address.",
|
||||
"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."
|
||||
},
|
||||
@ -1705,12 +1706,12 @@
|
||||
},
|
||||
"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": {
|
||||
@ -2013,14 +2014,34 @@
|
||||
"previous": "Prev"
|
||||
},
|
||||
"pdf-viewer": {
|
||||
"header": {
|
||||
"all-annotations-loaded": "All annotations loaded",
|
||||
"compare-button": "Compare",
|
||||
"layers-panel-button": "Layers",
|
||||
"left-panel-button": "Panel",
|
||||
"load-all-annotations": "Load all annotations",
|
||||
"no-outlines-text": "No outlines available",
|
||||
"no-signatures-text": "This document has NO signature fields",
|
||||
"outline-multi-select": "Edit",
|
||||
"outlines-panel-button": "Outlines",
|
||||
"pan-tool-button": "Pan",
|
||||
"rectangle-tool-button": "Rectangle",
|
||||
"rotate-left-button": "Rotate page left",
|
||||
"rotate-right-button": "Rotate page right",
|
||||
"select-tool-button": "Select",
|
||||
"signature-panel-button": "Signatures",
|
||||
"thumbnails-panel-button": "Thumbnails",
|
||||
"toggle-layers": "{active, select, true{Disable} false{Enable} other{}} layout grid",
|
||||
"toggle-readable-redactions": "Show redactions {active, select, true{as in final document} false{in preview color} other{}}",
|
||||
"toggle-tooltips": "{active, select, true{Disable} false{Enable} other{}} annotation tooltips",
|
||||
"zoom-in-button": "Zoom In",
|
||||
"zoom-out-button": "Zoom Out"
|
||||
},
|
||||
"text-popup": {
|
||||
"actions": {
|
||||
"search": "Search for selected text"
|
||||
}
|
||||
},
|
||||
"toggle-layers": "{active, select, true{Disable} false{Enable} other{}} layout grid",
|
||||
"toggle-readable-redactions": "Show components {active, select, true{as in final document} false{in preview color} other{}}",
|
||||
"toggle-tooltips": "{active, select, true{Disable} false{Enable} other{}} annotation tooltips"
|
||||
}
|
||||
},
|
||||
"permissions-screen": {
|
||||
"dossier": {
|
||||
@ -2535,10 +2556,6 @@
|
||||
"view-as": "View as:",
|
||||
"workflow": "Workflow"
|
||||
},
|
||||
"viewer-header": {
|
||||
"all-annotations-loaded": "All annotations loaded",
|
||||
"load-all-annotations": "Load all annotations"
|
||||
},
|
||||
"watermark-screen": {
|
||||
"action": {
|
||||
"change-success": "Watermark has been updated!",
|
||||
@ -2567,6 +2584,10 @@
|
||||
"orientation": "Orientation",
|
||||
"text-label": "Watermark text",
|
||||
"text-placeholder": "Enter text"
|
||||
},
|
||||
"pagination": {
|
||||
"landscape": "",
|
||||
"portrait": ""
|
||||
}
|
||||
},
|
||||
"watermarks-listing": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user