Merge branch 'master' into RED-10139
This commit is contained in:
commit
7ef5fc7bc9
@ -50,7 +50,7 @@
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "node_modules/@pdftron/webviewer/public/",
|
||||
"output": "/assets/wv-resources/10.10.1/"
|
||||
"output": "/assets/wv-resources/11.0.0/"
|
||||
},
|
||||
{
|
||||
"glob": "**/*",
|
||||
@ -73,7 +73,7 @@
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": ["./apps/red-ui/src/assets/styles", "./libs/common-ui/src/assets/styles"]
|
||||
},
|
||||
"scripts": ["node_modules/@pdftron/webviewer/webviewer.min.js", "node_modules/chart.js/auto/auto.cjs"],
|
||||
"scripts": ["node_modules/chart.js/auto/auto.cjs"],
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true,
|
||||
"optimization": false,
|
||||
|
||||
@ -11,7 +11,9 @@ import { DictionaryService } from '@services/entity-services/dictionary.service'
|
||||
import { DefaultColorsService } from '@services/entity-services/default-colors.service';
|
||||
import { WatermarkService } from '@services/entity-services/watermark.service';
|
||||
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
|
||||
import { getConfig } from '@iqser/common-ui';
|
||||
import { getConfig, Toaster } from '@iqser/common-ui';
|
||||
import { RulesService } from '../modules/admin/services/rules.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
|
||||
export function templateExistsWhenEnteringAdmin(): CanActivateFn {
|
||||
return async function (route: ActivatedRouteSnapshot): Promise<boolean> {
|
||||
@ -50,6 +52,8 @@ export function templateExistsWhenEnteringDossierList(): CanActivateFn {
|
||||
const dictionaryService = inject(DictionaryService);
|
||||
const defaultColorsService = inject(DefaultColorsService);
|
||||
const watermarksService = inject(WatermarkService);
|
||||
const rulesService = inject(RulesService);
|
||||
const toaster = inject(Toaster);
|
||||
const isDocumine = getConfig().IS_DOCUMINE;
|
||||
|
||||
await firstValueFrom(dashboardStatsService.loadForTemplate(dossierTemplateId));
|
||||
@ -64,6 +68,10 @@ export function templateExistsWhenEnteringDossierList(): CanActivateFn {
|
||||
await firstValueFrom(fileAttributesService.loadFileAttributesConfig(dossierTemplateId));
|
||||
await firstValueFrom(dictionaryService.loadDictionaryDataForDossierTemplate(dossierTemplateId));
|
||||
await firstValueFrom(defaultColorsService.loadForDossierTemplate(dossierTemplateId));
|
||||
const rules = await firstValueFrom(rulesService.getFor(dossierTemplateId));
|
||||
if (rules.timeoutDetected) {
|
||||
toaster.error(_('dossier-listing.rules.timeoutError'));
|
||||
}
|
||||
if (!isDocumine) {
|
||||
await firstValueFrom(watermarksService.loadForDossierTemplate(dossierTemplateId));
|
||||
}
|
||||
|
||||
@ -16,11 +16,7 @@ export const canForceRedaction = (annotation: AnnotationWrapper, canAddRedaction
|
||||
export const canAcceptRecommendation = (annotation: AnnotationWrapper) => annotation.isRecommendation && !annotation.pending;
|
||||
|
||||
export const canMarkAsFalsePositive = (annotation: AnnotationWrapper, annotationEntity: Dictionary) =>
|
||||
annotation.canBeMarkedAsFalsePositive &&
|
||||
!annotation.hasBeenResizedLocally &&
|
||||
!annotation.isRemovedLocally &&
|
||||
!annotation.hasBeenForcedRedaction &&
|
||||
annotationEntity?.hasDictionary;
|
||||
annotation.canBeMarkedAsFalsePositive && !annotation.hasBeenResizedLocally && annotationEntity?.hasDictionary;
|
||||
|
||||
export const canRemoveOnlyHere = (annotation: AnnotationWrapper, canAddRedaction: boolean, autoAnalysisDisabled: boolean) =>
|
||||
canAddRedaction &&
|
||||
|
||||
@ -109,7 +109,10 @@ export class AnnotationWrapper implements IListable {
|
||||
|
||||
get canBeMarkedAsFalsePositive() {
|
||||
return (
|
||||
(this.isRecommendation || this.superType === SuperTypes.Redaction || (this.isSkipped && this.isDictBased)) &&
|
||||
(this.isRecommendation ||
|
||||
this.superType === SuperTypes.Redaction ||
|
||||
(this.isSkipped && this.isDictBased) ||
|
||||
(this.isRemovedLocally && this.isDictBased)) &&
|
||||
!this.isImage &&
|
||||
!this.imported &&
|
||||
!this.pending &&
|
||||
|
||||
@ -3,10 +3,8 @@ import { ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup, Validators }
|
||||
import { AdminDialogService } from '../../../services/admin-dialog.service';
|
||||
import { BaseFormComponent, IconButtonComponent, LoadingService, Toaster } from '@iqser/common-ui';
|
||||
import { rolesTranslations } from '@translations/roles-translations';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { User } from '@red/domain';
|
||||
import { UserService } from '@users/user.service';
|
||||
import { HttpStatusCode } from '@angular/common/http';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { IProfileUpdateRequest } from '@iqser/common-ui/lib/users';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
@ -101,11 +99,7 @@ export class UserDetailsComponent extends BaseFormComponent implements OnInit {
|
||||
this.closeDialog.emit(true);
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.status === HttpStatusCode.Conflict) {
|
||||
this._toaster.error(_('add-edit-user.error.email-already-used'));
|
||||
} else {
|
||||
this._toaster.error(_('add-edit-user.error.generic'));
|
||||
}
|
||||
this._toaster.error(null, { error });
|
||||
this._loadingService.stop();
|
||||
});
|
||||
} else {
|
||||
|
||||
@ -17,7 +17,7 @@ import { RouterHistoryService } from '@services/router-history.service';
|
||||
import { auditCategoriesTranslations } from '@translations/audit-categories-translations';
|
||||
import { Roles } from '@users/roles';
|
||||
import { applyIntervalConstraints } from '@utils/date-inputs-utils';
|
||||
import { Dayjs } from 'dayjs';
|
||||
import dayjs, { Dayjs } from 'dayjs';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { AuditService } from '../../services/audit.service';
|
||||
@ -139,16 +139,9 @@ export class AuditScreenComponent extends ListingComponent<Audit> implements OnI
|
||||
const promises = [];
|
||||
const category = this.form.get('category').value;
|
||||
const userId = this.form.get('userId').value;
|
||||
const from = this.form.get('from').value;
|
||||
let to = this.form.get('to').value;
|
||||
if (to) {
|
||||
const hoursLeft = new Date(to).getHours();
|
||||
const minutesLeft = new Date(to).getMinutes();
|
||||
to = to
|
||||
.clone()
|
||||
.add(24 - hoursLeft - 1, 'h')
|
||||
.add(60 - minutesLeft - 1);
|
||||
}
|
||||
const from = this.form.get('from').value ? dayjs(this.form.get('from').value).startOf('day').toISOString() : null;
|
||||
const to = this.form.get('to').value ? dayjs(this.form.get('to').value).endOf('day').toISOString() : null;
|
||||
|
||||
const logsRequestBody: IAuditSearchRequest = {
|
||||
pageSize: PAGE_SIZE,
|
||||
page: page,
|
||||
|
||||
@ -42,6 +42,15 @@
|
||||
type="text"
|
||||
/>
|
||||
</div>
|
||||
<div class="iqser-input-group required w-150">
|
||||
<label translate="add-edit-component-mapping.form.quote-char"></label>
|
||||
<input
|
||||
[placeholder]="'add-edit-component-mapping.form.quote-char-placeholder' | translate"
|
||||
formControlName="quoteChar"
|
||||
name="quoteChar"
|
||||
type="text"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="iqser-input-group required w-150">
|
||||
<label translate="add-edit-component-mapping.form.encoding-type"></label>
|
||||
|
||||
@ -17,12 +17,14 @@ interface DialogData {
|
||||
dossierTemplateId: string;
|
||||
mapping: IComponentMapping;
|
||||
}
|
||||
|
||||
interface DialogResult {
|
||||
id: string;
|
||||
name: string;
|
||||
file: Blob;
|
||||
encoding: string;
|
||||
delimiter: string;
|
||||
quoteChar: string;
|
||||
fileName?: string;
|
||||
}
|
||||
|
||||
@ -72,14 +74,14 @@ export class AddEditComponentMappingDialogComponent
|
||||
const file = new Blob([fileContent.body as Blob], { type: 'text/csv' });
|
||||
this.form.get('file').setValue(file);
|
||||
this.initialFormValue = this.form.getRawValue();
|
||||
this.#disableEncodingAndDelimiter();
|
||||
this.#disableEncodingAndQuoteCharAndDelimiter();
|
||||
}
|
||||
}
|
||||
|
||||
changeFile(file: File) {
|
||||
this.form.get('file').setValue(file);
|
||||
this.form.get('fileName').setValue(file?.name);
|
||||
this.#enableEncodingAndDelimiter();
|
||||
this.#enableEncodingAndQuoteCharAndDelimiter();
|
||||
}
|
||||
|
||||
save() {
|
||||
@ -93,16 +95,19 @@ export class AddEditComponentMappingDialogComponent
|
||||
fileName: [this.data?.mapping?.fileName, Validators.required],
|
||||
encoding: this.encodingTypeOptions.find(e => e === this.data?.mapping?.encoding) ?? this.encodingTypeOptions[0],
|
||||
delimiter: [this.data?.mapping?.delimiter ?? ',', Validators.required],
|
||||
quoteChar: [this.data?.mapping?.quoteChar ?? '"', Validators.required],
|
||||
});
|
||||
}
|
||||
|
||||
#disableEncodingAndDelimiter() {
|
||||
#disableEncodingAndQuoteCharAndDelimiter() {
|
||||
this.form.get('encoding').disable();
|
||||
this.form.get('delimiter').disable();
|
||||
this.form.get('quoteChar').disable();
|
||||
}
|
||||
|
||||
#enableEncodingAndDelimiter() {
|
||||
#enableEncodingAndQuoteCharAndDelimiter() {
|
||||
this.form.get('encoding').enable();
|
||||
this.form.get('delimiter').enable();
|
||||
this.form.get('quoteChar').enable();
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,8 +99,8 @@ export default class ComponentMappingsScreenComponent extends ListingComponent<C
|
||||
const result = await dialog.result();
|
||||
if (result) {
|
||||
this._loadingService.start();
|
||||
const { id, name, encoding, delimiter, fileName } = result;
|
||||
const newMapping = { id, name, encoding, delimiter, fileName };
|
||||
const { id, name, encoding, delimiter, fileName, quoteChar } = result;
|
||||
const newMapping = { id, name, encoding, delimiter, fileName, quoteChar };
|
||||
await firstValueFrom(
|
||||
this._componentMappingService.createUpdateComponentMapping(this.#dossierTemplateId, newMapping, result.file),
|
||||
);
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
<div class="dialog-header">
|
||||
<div class="heading-l" translate="general-config-screen.general.title"></div>
|
||||
<div translate="general-config-screen.general.subtitle"></div>
|
||||
</div>
|
||||
<form (submit)="save()" *ngIf="form" [formGroup]="form">
|
||||
<div class="dialog-content">
|
||||
|
||||
@ -17,8 +17,17 @@
|
||||
type="text"
|
||||
/>
|
||||
</div>
|
||||
<div class="iqser-input-group">
|
||||
<label translate="add-edit-entity.form.technical-name"></label>
|
||||
<div class="technical-name">{{ this.technicalName() || '-' }}</div>
|
||||
<span
|
||||
[translateParams]="{ type: data.justification ? 'edit' : 'create' }"
|
||||
[translate]="'add-edit-entity.form.technical-name-hint'"
|
||||
class="hint"
|
||||
></span>
|
||||
</div>
|
||||
|
||||
<div class="iqser-input-group required w-400">
|
||||
<div class="iqser-input-group w-400">
|
||||
<label translate="add-edit-justification.form.reason"></label>
|
||||
<input
|
||||
[placeholder]="'add-edit-justification.form.reason-placeholder' | translate"
|
||||
@ -28,7 +37,7 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="iqser-input-group required w-400">
|
||||
<div class="iqser-input-group w-400">
|
||||
<label translate="add-edit-justification.form.description"></label>
|
||||
<textarea
|
||||
[placeholder]="'add-edit-justification.form.description-placeholder' | translate"
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, computed, Inject, untracked } from '@angular/core';
|
||||
import { ReactiveFormsModule, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { Justification } from '@red/domain';
|
||||
import { JustificationsService } from '@services/entity-services/justifications.service';
|
||||
import { BaseDialogComponent, CircleButtonComponent, IconButtonComponent } from '@iqser/common-ui';
|
||||
import { BaseDialogComponent, CircleButtonComponent, HasScrollbarDirective, IconButtonComponent } from '@iqser/common-ui';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
import { formValueToSignal } from '@common-ui/utils';
|
||||
|
||||
interface DialogData {
|
||||
justification?: Justification;
|
||||
@ -16,9 +18,29 @@ interface DialogData {
|
||||
templateUrl: './add-edit-justification-dialog.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [TranslateModule, ReactiveFormsModule, IconButtonComponent, CircleButtonComponent],
|
||||
imports: [TranslateModule, ReactiveFormsModule, IconButtonComponent, CircleButtonComponent, HasScrollbarDirective],
|
||||
})
|
||||
export class AddEditJustificationDialogComponent extends BaseDialogComponent {
|
||||
readonly form = this.#getForm();
|
||||
readonly name = formValueToSignal(this.form.controls['name']);
|
||||
readonly allJustifications = toSignal(this._justificationService.all$);
|
||||
readonly technicalName = computed(() => {
|
||||
if (this.data.justification) {
|
||||
return this.data.justification.technicalName;
|
||||
}
|
||||
if (!this.name()) {
|
||||
return null;
|
||||
}
|
||||
let currentTechnicalName = Justification.toTechnicalName(this.name());
|
||||
const existingTechnicalNames = untracked(this.allJustifications).map(justification => justification.technicalName);
|
||||
let suffix = 1;
|
||||
while (existingTechnicalNames.includes(currentTechnicalName)) {
|
||||
currentTechnicalName =
|
||||
currentTechnicalName === '_' ? `${currentTechnicalName}${suffix++}` : [currentTechnicalName, suffix++].join('_');
|
||||
}
|
||||
return currentTechnicalName;
|
||||
});
|
||||
|
||||
constructor(
|
||||
private readonly _justificationService: JustificationsService,
|
||||
protected readonly _dialogRef: MatDialogRef<AddEditJustificationDialogComponent>,
|
||||
@ -26,7 +48,6 @@ export class AddEditJustificationDialogComponent extends BaseDialogComponent {
|
||||
) {
|
||||
super(_dialogRef, !!data.justification);
|
||||
|
||||
this.form = this._getForm();
|
||||
this.initialFormValue = this.form.getRawValue();
|
||||
}
|
||||
|
||||
@ -34,7 +55,8 @@ export class AddEditJustificationDialogComponent extends BaseDialogComponent {
|
||||
const dossierTemplateId = this.data.dossierTemplateId;
|
||||
this._loadingService.start();
|
||||
try {
|
||||
await firstValueFrom(this._justificationService.createOrUpdate(this.form.getRawValue() as Justification, dossierTemplateId));
|
||||
const formValue = { ...this.form.getRawValue(), technicalName: this.technicalName() };
|
||||
await firstValueFrom(this._justificationService.createOrUpdate(formValue as Justification, dossierTemplateId));
|
||||
await firstValueFrom(this._justificationService.loadAll(dossierTemplateId));
|
||||
this._dialogRef.close(true);
|
||||
} catch (error) {
|
||||
@ -43,11 +65,12 @@ export class AddEditJustificationDialogComponent extends BaseDialogComponent {
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
private _getForm(): UntypedFormGroup {
|
||||
#getForm(): UntypedFormGroup {
|
||||
return this._formBuilder.group({
|
||||
name: [{ value: this.data.justification?.name, disabled: !!this.data.justification }, Validators.required],
|
||||
reason: [this.data.justification?.reason, Validators.required],
|
||||
description: [this.data.justification?.description, Validators.required],
|
||||
reason: [this.data.justification?.reason],
|
||||
description: [this.data.justification?.description],
|
||||
technicalName: [this.data.justification?.technicalName ?? null],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,9 +78,9 @@ export class LicenseRetentionCapacityComponent {
|
||||
|
||||
return [
|
||||
{
|
||||
data: monthlyData.flatMap(d => d.activeFilesUploadedBytes),
|
||||
label: this._translateService.instant('license-info-screen.retention-capacity-usage.active-documents'),
|
||||
...getLineConfig(ChartGreen, false, 'origin'),
|
||||
data: monthlyData.flatMap(d => d.trashFilesUploadedBytes),
|
||||
label: this._translateService.instant('license-info-screen.retention-capacity-usage.trash-documents'),
|
||||
...getLineConfig(ChartRed, false, 'origin'),
|
||||
stack: 'storage',
|
||||
},
|
||||
{
|
||||
@ -90,9 +90,9 @@ export class LicenseRetentionCapacityComponent {
|
||||
stack: 'storage',
|
||||
},
|
||||
{
|
||||
data: monthlyData.flatMap(d => d.trashFilesUploadedBytes),
|
||||
label: this._translateService.instant('license-info-screen.retention-capacity-usage.trash-documents'),
|
||||
...getLineConfig(ChartRed, false, '-1'),
|
||||
data: monthlyData.flatMap(d => d.activeFilesUploadedBytes),
|
||||
label: this._translateService.instant('license-info-screen.retention-capacity-usage.active-documents'),
|
||||
...getLineConfig(ChartGreen, false, 'origin'),
|
||||
stack: 'storage',
|
||||
},
|
||||
{
|
||||
|
||||
@ -83,9 +83,9 @@ interface WatermarkForm {
|
||||
AsyncPipe,
|
||||
ReactiveFormsModule,
|
||||
HasScrollbarDirective,
|
||||
MatTooltip,
|
||||
NgForOf,
|
||||
NgClass,
|
||||
MatTooltip,
|
||||
MatIcon,
|
||||
MatSlider,
|
||||
ColorPickerModule,
|
||||
@ -246,14 +246,15 @@ export class WatermarkScreenComponent implements OnInit {
|
||||
}
|
||||
|
||||
async #loadViewer() {
|
||||
this.instance = await WebViewer(
|
||||
this.instance = await WebViewer.Iframe(
|
||||
{
|
||||
licenseKey: this._licenseService.activeLicenseKey,
|
||||
path: this.#convertPath('/assets/wv-resources/10.10.1'),
|
||||
path: this.#convertPath('/assets/wv-resources/11.0.0'),
|
||||
css: this.#convertPath('/assets/pdftron/stylesheet.css'),
|
||||
fullAPI: true,
|
||||
isReadOnly: true,
|
||||
backendType: 'ems',
|
||||
ui: 'legacy',
|
||||
},
|
||||
// use nativeElement instead of document.getElementById('viwer')
|
||||
// because WebViewer works better with this approach
|
||||
@ -269,7 +270,7 @@ export class WatermarkScreenComponent implements OnInit {
|
||||
});
|
||||
|
||||
if (environment.production) {
|
||||
this.instance.Core.setCustomFontURL('https://' + window.location.host + this.#convertPath('/assets/pdftron'));
|
||||
this.instance.Core.setCustomFontURL(window.location.origin + this.#convertPath('/assets/pdftron/fonts'));
|
||||
}
|
||||
|
||||
this.#disableElements();
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { GenericService } from '@iqser/common-ui';
|
||||
import { GenericService, QueryParam } from '@iqser/common-ui';
|
||||
import { IRules } from '@red/domain';
|
||||
import { Observable } from 'rxjs';
|
||||
import { List } from '@common-ui/utils';
|
||||
|
||||
@Injectable()
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class RulesService extends GenericService<IRules> {
|
||||
protected readonly _defaultModelPath = 'rules';
|
||||
|
||||
@ -13,4 +15,8 @@ export class RulesService extends GenericService<IRules> {
|
||||
uploadRules(body: IRules) {
|
||||
return this._post<unknown>({ ...body, ruleFileType: body.ruleFileType ?? 'ENTITY' });
|
||||
}
|
||||
|
||||
getFor<R = IRules>(entityId: string, queryParams?: List<QueryParam>): Observable<R> {
|
||||
return super.getFor(entityId, queryParams);
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,13 +59,12 @@
|
||||
class="edit-input"
|
||||
iqserStopPropagation
|
||||
>
|
||||
<form [formGroup]="form">
|
||||
<form [formGroup]="form" [style.width]="inputFormWidth()">
|
||||
<iqser-dynamic-input
|
||||
(closedDatepicker)="closedDatepicker = $event"
|
||||
(keyup.enter)="form.valid && save()"
|
||||
(keydown.escape)="close()"
|
||||
[style.max-width]="editFieldWidth()"
|
||||
[style.min-width]="editFieldWidth()"
|
||||
[style.width]="inputFieldWidth()"
|
||||
[formControlName]="fileAttribute().id"
|
||||
[id]="fileAttribute().id"
|
||||
[ngClass]="{ 'workflow-input': mode === 'workflow' || fileNameColumn(), 'file-name-input': fileNameColumn() }"
|
||||
|
||||
@ -97,7 +97,7 @@
|
||||
iqser-circle-button {
|
||||
margin-left: 15px;
|
||||
|
||||
@media screen and (max-width: 1395px) {
|
||||
@media screen and (max-width: 1745px) {
|
||||
margin-left: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,8 +53,6 @@ export class FileAttributeComponent extends BaseFormComponent {
|
||||
readonly dossier = input<Dossier>();
|
||||
readonly fileNameColumn = input(false);
|
||||
readonly width = input<number>();
|
||||
readonly editFieldWidth = computed(() => (this.width() ? `${this.width() * this.#widthFactor}px` : 'unset'));
|
||||
readonly attributeValueWidth = computed(() => (this.width() ? `${this.width() * 0.9}px` : 'unset'));
|
||||
|
||||
readonly isText = computed(() => this.fileAttribute().type === FileAttributeConfigTypes.TEXT);
|
||||
readonly value = computed(() => this.file().fileAttributes.attributeIdToValue[this.fileAttribute().id]);
|
||||
@ -68,9 +66,10 @@ export class FileAttributeComponent extends BaseFormComponent {
|
||||
this.file().fileId !== this.fileAttributesService.fileEdit())) ||
|
||||
!this.fileAttributesService.openAttributeEdits().length,
|
||||
);
|
||||
|
||||
#widthFactor = window.innerWidth >= 1800 ? 0.85 : 0.7;
|
||||
#readonlyAttrs: string[] = [];
|
||||
readonlyAttrs: string[] = [];
|
||||
readonly inputFormWidth = computed(() => (this.width() ? this.width() + 'px' : 'unset'));
|
||||
readonly inputFieldWidth = computed(() => (this.width() ? this.width() - 50 + 'px' : 'unset'));
|
||||
readonly attributeValueWidth = computed(() => (this.width() ? `${this.width() * 0.9}px` : 'unset'));
|
||||
|
||||
constructor(
|
||||
private readonly _toaster: Toaster,
|
||||
@ -99,15 +98,6 @@ export class FileAttributeComponent extends BaseFormComponent {
|
||||
);
|
||||
}
|
||||
|
||||
@HostListener('window:resize')
|
||||
onResize() {
|
||||
if (window.innerWidth >= 1800) {
|
||||
this.#widthFactor = 0.85;
|
||||
} else {
|
||||
this.#widthFactor = 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
@Debounce(60)
|
||||
@HostListener('document:click', ['$event'])
|
||||
clickOutside($event: MouseEvent) {
|
||||
@ -195,7 +185,7 @@ export class FileAttributeComponent extends BaseFormComponent {
|
||||
#initFileAttributes() {
|
||||
const file = untracked(this.file);
|
||||
const configs = this.fileAttributesService.getFileAttributeConfig(file.dossierTemplateId).fileAttributeConfigs;
|
||||
this.#readonlyAttrs = configs.filter(config => config.editable === false).map(config => config.id);
|
||||
this.readonlyAttrs = configs.filter(config => config.editable === false).map(config => config.id);
|
||||
configs.forEach(config => {
|
||||
if (!file.fileAttributes.attributeIdToValue[config.id]) {
|
||||
file.fileAttributes.attributeIdToValue[config.id] = null;
|
||||
@ -212,7 +202,7 @@ export class FileAttributeComponent extends BaseFormComponent {
|
||||
config[key] = [
|
||||
{
|
||||
value: dayjs(attrValue, 'YYYY-MM-DD', true).isValid() ? dayjs(attrValue).toDate() : attrValue,
|
||||
disabled: this.#readonlyAttrs.includes(key),
|
||||
disabled: this.readonlyAttrs.includes(key),
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
@ -1,9 +1,17 @@
|
||||
<div class="needs-work">
|
||||
@if (file().analysisRequired) {
|
||||
<redaction-annotation-icon [color]="analysisColor$ | async" label="A" type="square"></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
[color]="analysisColor$ | async"
|
||||
[label]="(workloadTranslations['analysis'] | translate)[0]"
|
||||
type="square"
|
||||
></redaction-annotation-icon>
|
||||
}
|
||||
@if (updated()) {
|
||||
<redaction-annotation-icon [color]="updatedColor$ | async" label="U" type="square"></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
[color]="updatedColor$ | async"
|
||||
[label]="(workloadTranslations['updated'] | translate)[0]"
|
||||
type="square"
|
||||
></redaction-annotation-icon>
|
||||
}
|
||||
@if (file().hasRedactions) {
|
||||
<redaction-annotation-icon
|
||||
@ -13,10 +21,18 @@
|
||||
></redaction-annotation-icon>
|
||||
}
|
||||
@if (file().hasImages) {
|
||||
<redaction-annotation-icon [color]="imageColor$ | async" label="I" type="square"></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
[color]="imageColor$ | async"
|
||||
[label]="(workloadTranslations['image'] | translate)[0]"
|
||||
type="square"
|
||||
></redaction-annotation-icon>
|
||||
}
|
||||
@if (file().hintsOnly) {
|
||||
<redaction-annotation-icon [color]="hintColor$ | async" label="H" type="circle"></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
[color]="hintColor$ | async"
|
||||
[label]="(workloadTranslations['hint'] | translate)[0]"
|
||||
type="circle"
|
||||
></redaction-annotation-icon>
|
||||
}
|
||||
@if (file().hasAnnotationComments) {
|
||||
<mat-icon svgIcon="red:comment"></mat-icon>
|
||||
|
||||
@ -10,6 +10,7 @@ import { AnnotationIconComponent } from '@shared/components/annotation-icon/anno
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
import { workloadTranslations } from '@translations/workload-translations';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-file-workload',
|
||||
@ -27,6 +28,7 @@ export class FileWorkloadComponent implements OnInit {
|
||||
analysisColor$: Observable<string>;
|
||||
hintColor$: Observable<string>;
|
||||
redactionColor$: Observable<string>;
|
||||
readonly workloadTranslations = workloadTranslations;
|
||||
|
||||
readonly updated = computed(
|
||||
() => this.file().hasUpdates && this.file().assignee === this._userService.currentUser.id && !this.file().isApproved,
|
||||
|
||||
@ -15,7 +15,6 @@ import {
|
||||
import { DossierStatsService } from '@services/dossiers/dossier-stats.service';
|
||||
import { DefaultColorsService } from '@services/entity-services/default-colors.service';
|
||||
import { DossierStatesMapService } from '@services/entity-services/dossier-states-map.service';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { SharedDialogService } from '@shared/services/dialog.service';
|
||||
import { workflowFileStatusTranslations } from '@translations/file-status-translations';
|
||||
import { workloadTranslations } from '@translations/workload-translations';
|
||||
@ -40,7 +39,6 @@ export class ConfigService {
|
||||
private readonly _dossierStatsService: DossierStatsService,
|
||||
private readonly _dossierStatesMapService: DossierStatesMapService,
|
||||
private readonly _dialogService: SharedDialogService,
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
private readonly _defaultColorsService: DefaultColorsService,
|
||||
) {}
|
||||
|
||||
@ -67,9 +65,10 @@ export class ConfigService {
|
||||
{
|
||||
label: _('dossier-listing.add-new'),
|
||||
action: () => this.#openAddDossierDialog(dossierTemplate.id),
|
||||
hide: !this._permissionsService.canCreateDossier(dossierTemplate),
|
||||
icon: 'iqser:plus',
|
||||
type: 'primary',
|
||||
tooltip: dossierTemplate.isInactive ? _('dossier-listing.template-inactive') : null,
|
||||
disabled: dossierTemplate.isInactive,
|
||||
helpModeKey: 'new_dossier',
|
||||
},
|
||||
];
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<section>
|
||||
<iqser-page-header [buttonConfigs]="buttonConfigs" [helpModeKey]="'dossier'">
|
||||
<iqser-page-header [buttonConfigs]="buttonConfigs()" [helpModeKey]="'dossier'">
|
||||
<ng-container slot="beforeFilters">
|
||||
<redaction-dossiers-type-switch></redaction-dossiers-type-switch>
|
||||
</ng-container>
|
||||
@ -35,7 +35,7 @@
|
||||
</section>
|
||||
|
||||
<ng-template #needsWorkFilterTemplate let-filter="filter">
|
||||
<redaction-type-filter [dossierTemplateId]="dossierTemplate.id" [filter]="filter"></redaction-type-filter>
|
||||
<redaction-type-filter [dossierTemplateId]="dossierTemplate().id" [filter]="filter"></redaction-type-filter>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #tableItemTemplate let-dossier="entity">
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import { ChangeDetectionStrategy, Component, computed, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
||||
import { Dossier, DOSSIER_TEMPLATE_ID, DossierTemplate } from '@red/domain';
|
||||
import { Dossier, DOSSIER_TEMPLATE_ID } from '@red/domain';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import {
|
||||
ButtonConfig,
|
||||
HasScrollbarDirective,
|
||||
IqserListingModule,
|
||||
ListingComponent,
|
||||
@ -25,6 +24,7 @@ import { DossiersListingDetailsComponent } from '../components/dossiers-listing-
|
||||
import { AsyncPipe, NgIf } from '@angular/common';
|
||||
import { TypeFilterComponent } from '@shared/components/type-filter/type-filter.component';
|
||||
import { TableItemComponent } from '../components/table-item/table-item.component';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
templateUrl: './dossiers-listing-screen.component.html',
|
||||
@ -47,9 +47,11 @@ import { TableItemComponent } from '../components/table-item/table-item.componen
|
||||
export class DossiersListingScreenComponent extends ListingComponent<Dossier> implements OnInit, OnAttach {
|
||||
readonly tableColumnConfigs = this._configService.tableConfig;
|
||||
readonly tableHeaderLabel = _('dossier-listing.table-header.title');
|
||||
readonly buttonConfigs: ButtonConfig[];
|
||||
readonly dossierTemplate: DossierTemplate;
|
||||
readonly canCreateDossier = computed(() => this.permissionsService.canCreateDossier(this.dossierTemplate));
|
||||
readonly dossierTemplateId = this.router.routerState.snapshot.root.firstChild.firstChild.paramMap.get(DOSSIER_TEMPLATE_ID);
|
||||
readonly dossierTemplates = toSignal(this.dossierTemplatesService.all$);
|
||||
readonly dossierTemplate = computed(() => this.dossierTemplates().find(template => this.dossierTemplateId === template.id));
|
||||
readonly buttonConfigs = computed(() => this._configService.buttonsConfig(this.dossierTemplate()));
|
||||
readonly canCreateDossier = computed(() => this.permissionsService.canCreateDossier(this.dossierTemplate()));
|
||||
readonly computeFilters$ = this._activeDossiersService.all$.pipe(tap(() => this.#computeAllFilters()));
|
||||
@ViewChild('needsWorkFilterTemplate', {
|
||||
read: TemplateRef,
|
||||
@ -69,20 +71,19 @@ export class DossiersListingScreenComponent extends ListingComponent<Dossier> im
|
||||
readonly dossierTemplatesService: DossierTemplatesService,
|
||||
) {
|
||||
super();
|
||||
const dossierTemplateId = router.routerState.snapshot.root.firstChild.firstChild.paramMap.get(DOSSIER_TEMPLATE_ID);
|
||||
this.dossierTemplate = dossierTemplatesService.find(dossierTemplateId);
|
||||
this.buttonConfigs = this._configService.buttonsConfig(this.dossierTemplate);
|
||||
this.entitiesService.setEntities(this._activeDossiersService.all.filter(d => d.dossierTemplateId === this.dossierTemplate.id));
|
||||
this.entitiesService.setEntities(this._activeDossiersService.all.filter(d => d.dossierTemplateId === this.dossierTemplate().id));
|
||||
}
|
||||
|
||||
openAddDossierDialog(): void {
|
||||
this._dialogService.openDialog('addDossier', { dossierTemplateId: this.dossierTemplate.id });
|
||||
this._dialogService.openDialog('addDossier', { dossierTemplateId: this.dossierTemplate().id });
|
||||
}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
await this._userPreferenceService.saveLastDossierTemplate(this.dossierTemplate.id);
|
||||
await this._userPreferenceService.saveLastDossierTemplate(this.dossierTemplate().id);
|
||||
this.addSubscription = this._activeDossiersService.all$
|
||||
.pipe(tap(dossiers => this.entitiesService.setEntities(dossiers.filter(d => d.dossierTemplateId === this.dossierTemplate.id))))
|
||||
.pipe(
|
||||
tap(dossiers => this.entitiesService.setEntities(dossiers.filter(d => d.dossierTemplateId === this.dossierTemplate().id))),
|
||||
)
|
||||
.subscribe();
|
||||
this._loadingService.stop();
|
||||
}
|
||||
@ -96,7 +97,7 @@ export class DossiersListingScreenComponent extends ListingComponent<Dossier> im
|
||||
const filterGroups = this._configService.filterGroups(
|
||||
this.entitiesService.all,
|
||||
this._needsWorkFilterTemplate,
|
||||
this.dossierTemplate.id,
|
||||
this.dossierTemplate().id,
|
||||
);
|
||||
this.filterService.addFilterGroups(filterGroups);
|
||||
}
|
||||
|
||||
@ -133,14 +133,14 @@ export class AnnotationActionsComponent {
|
||||
const viewerAnnotations = untracked(this.viewerAnnotations);
|
||||
this._annotationManager.hide(viewerAnnotations);
|
||||
this._annotationManager.deselect();
|
||||
this._annotationManager.addToHidden(viewerAnnotations[0].Id);
|
||||
viewerAnnotations.forEach(a => this._annotationManager.addToHidden(a.Id));
|
||||
}
|
||||
|
||||
showAnnotation() {
|
||||
const viewerAnnotations = untracked(this.viewerAnnotations);
|
||||
this._annotationManager.show(viewerAnnotations);
|
||||
this._annotationManager.deselect();
|
||||
this._annotationManager.removeFromHidden(viewerAnnotations[0].Id);
|
||||
viewerAnnotations.forEach(a => this._annotationManager.removeFromHidden(a.Id));
|
||||
}
|
||||
|
||||
resize() {
|
||||
|
||||
@ -6,10 +6,9 @@
|
||||
overflow-y: auto;
|
||||
@include common-mixins.scroll-bar;
|
||||
|
||||
&.has-scrollbar:hover redaction-annotation-wrapper::ng-deep,
|
||||
&::ng-deep.documine-wrapper {
|
||||
.annotation {
|
||||
padding-right: 5px;
|
||||
redaction-annotation-wrapper.documine-wrapper {
|
||||
&::ng-deep.annotation {
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ import { JsonPipe, NgForOf, NgIf } from '@angular/common';
|
||||
import { HighlightsSeparatorComponent } from '../highlights-separator/highlights-separator.component';
|
||||
import { AnnotationWrapperComponent } from '../annotation-wrapper/annotation-wrapper.component';
|
||||
import { AnnotationReferencesListComponent } from '../annotation-references-list/annotation-references-list.component';
|
||||
import { Clipboard } from '@angular/cdk/clipboard';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-annotations-list',
|
||||
@ -54,11 +55,15 @@ export class AnnotationsListComponent extends HasScrollbarDirective {
|
||||
private readonly _annotationManager: REDAnnotationManager,
|
||||
private readonly _listingService: AnnotationsListingService,
|
||||
readonly annotationReferencesService: AnnotationReferencesService,
|
||||
private readonly clipboard: Clipboard,
|
||||
) {
|
||||
super(_elementRef);
|
||||
}
|
||||
|
||||
annotationClicked(annotation: AnnotationWrapper, $event: MouseEvent): void {
|
||||
if ($event.ctrlKey && $event.altKey) {
|
||||
this.clipboard.copy(annotation.id);
|
||||
}
|
||||
if (this._userPreferenceService.isIqserDevMode) {
|
||||
console.log('Selected Annotation:', annotation);
|
||||
}
|
||||
|
||||
@ -596,7 +596,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
|
||||
@HostListener('document: click')
|
||||
clickOutsideWorkloadView() {
|
||||
if (this.multiSelectService.active()) {
|
||||
if (this.multiSelectService.active() && !this._dialog.openDialogs.length) {
|
||||
this.multiSelectService.deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
class="dialog-header heading-l"
|
||||
></div>
|
||||
|
||||
<div [class.fixed-height]="isRedacted && isImage" class="dialog-content redaction">
|
||||
<div [class.image-dialog]="isRedacted && isImage" [class.rectangle-dialog]="allRectangles" class="dialog-content redaction">
|
||||
<div *ngIf="!isImage && redactedTexts.length && !allRectangles" class="iqser-input-group">
|
||||
<redaction-selected-annotations-table
|
||||
[columns]="tableColumns"
|
||||
@ -90,7 +90,7 @@
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<div *ngIf="allRectangles" class="iqser-input-group w-400">
|
||||
<div *ngIf="allRectangles" class="iqser-input-group w-450">
|
||||
<label [translate]="'change-legal-basis-dialog.content.classification'"></label>
|
||||
<input
|
||||
[placeholder]="'edit-redaction.dialog.content.unchanged' | translate"
|
||||
@ -107,7 +107,7 @@
|
||||
formControlName="comment"
|
||||
iqserHasScrollbar
|
||||
name="comment"
|
||||
rows="4"
|
||||
rows="3"
|
||||
type="text"
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
@ -1,8 +1,16 @@
|
||||
.dialog-content {
|
||||
padding-top: 8px;
|
||||
|
||||
&.fixed-height {
|
||||
height: 386px;
|
||||
&.rectangle-dialog {
|
||||
height: 600px;
|
||||
}
|
||||
|
||||
&.image-dialog {
|
||||
height: 346px;
|
||||
}
|
||||
|
||||
.rectangle-dialog,
|
||||
.image-dialog {
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,6 +33,7 @@ import {
|
||||
LegalBasisOption,
|
||||
RectangleRedactOption,
|
||||
RectangleRedactOptions,
|
||||
RedactOrHintOptions,
|
||||
} from '../../utils/dialog-types';
|
||||
import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component';
|
||||
import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option';
|
||||
@ -89,7 +90,7 @@ export class EditRedactionDialogComponent
|
||||
{ label: redaction.value, bold: true },
|
||||
{ label: redaction.typeLabel },
|
||||
]);
|
||||
options = this.allRectangles ? getRectangleRedactOptions('edit') : getEditRedactionOptions();
|
||||
options = this.allRectangles ? getRectangleRedactOptions('edit') : getEditRedactionOptions(this.isHint);
|
||||
legalOptions: LegalBasisOption[] = [];
|
||||
dictionaries: Dictionary[] = [];
|
||||
typeSelectOptions: TypeSelectOptions[] = [];
|
||||
@ -211,7 +212,7 @@ export class EditRedactionDialogComponent
|
||||
const initialReason: LegalBasisOption = this.initialFormValue.reason;
|
||||
const initialLegalBasis = initialReason?.legalBasis ?? '';
|
||||
const pageNumbers = parseSelectedPageNumbers(
|
||||
this.form.get('option').value.additionalInput?.value,
|
||||
this.form.get('option').value?.additionalInput?.value,
|
||||
this.data.file,
|
||||
this.data.annotations[0],
|
||||
);
|
||||
@ -223,7 +224,7 @@ export class EditRedactionDialogComponent
|
||||
comment: value.comment,
|
||||
type: value.type,
|
||||
value: this.allRectangles ? value.value : null,
|
||||
option: value.option.value,
|
||||
option: value.option?.value ?? RedactOrHintOptions.ONLY_HERE,
|
||||
position,
|
||||
pageNumbers,
|
||||
});
|
||||
@ -260,7 +261,10 @@ export class EditRedactionDialogComponent
|
||||
disabled: this.isImported,
|
||||
}),
|
||||
section: new FormControl<string>({ value: sameSection ? this.annotations[0].section : null, disabled: this.isImported }),
|
||||
option: new FormControl<DetailsRadioOption<EditRedactionOption | RectangleRedactOption>>(this.options[0], validatePageRange()),
|
||||
option: new FormControl<DetailsRadioOption<EditRedactionOption | RectangleRedactOption>>(
|
||||
this.options[0],
|
||||
validatePageRange(this.data.file.numberOfPages),
|
||||
),
|
||||
value: new FormControl<string>(this.allRectangles ? this.annotations[0].value : null),
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,19 +1,17 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { ReactiveFormsModule, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, ReactiveFormsModule, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import {
|
||||
BaseDialogComponent,
|
||||
CircleButtonComponent,
|
||||
getConfig,
|
||||
HasScrollbarDirective,
|
||||
HelpButtonComponent,
|
||||
IconButtonComponent,
|
||||
IqserDenyDirective,
|
||||
IqserDialogComponent,
|
||||
} from '@iqser/common-ui';
|
||||
import { JustificationsService } from '@services/entity-services/justifications.service';
|
||||
import { Dossier, ILegalBasisChangeRequest } from '@red/domain';
|
||||
import { ILegalBasisChangeRequest } from '@red/domain';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { Roles } from '@users/roles';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import {
|
||||
@ -21,21 +19,20 @@ import {
|
||||
ValueColumn,
|
||||
} from '../../components/selected-annotations-table/selected-annotations-table.component';
|
||||
import { NgForOf, NgIf } from '@angular/common';
|
||||
import { MatFormField } from '@angular/material/form-field';
|
||||
import { MatOption, MatSelect, MatSelectTrigger } from '@angular/material/select';
|
||||
import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option';
|
||||
import { ForceAnnotationData, ForceAnnotationOption, ForceAnnotationResult, LegalBasisOption } from '../../utils/dialog-types';
|
||||
import { getForceAnnotationOptions } from '../../utils/dialog-options';
|
||||
import { SystemDefaults } from '../../../account/utils/dialog-defaults';
|
||||
import { MatFormField } from '@angular/material/form-field';
|
||||
import { MatTooltip } from '@angular/material/tooltip';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { DetailsRadioOption } from '@common-ui/inputs/details-radio/details-radio-option';
|
||||
import { ForceAnnotationOption, LegalBasisOption } from '../../utils/dialog-types';
|
||||
import { getForceAnnotationOptions } from '../../utils/dialog-options';
|
||||
import { DetailsRadioComponent } from '@common-ui/inputs/details-radio/details-radio.component';
|
||||
import { SystemDefaults } from '../../../account/utils/dialog-defaults';
|
||||
import { formValueToSignal } from '@common-ui/utils';
|
||||
|
||||
const DOCUMINE_LEGAL_BASIS = 'n-a.';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-force-annotation-dialog',
|
||||
templateUrl: './force-annotation-dialog.component.html',
|
||||
styleUrls: ['./force-annotation-dialog.component.scss'],
|
||||
standalone: true,
|
||||
@ -58,19 +55,24 @@ const DOCUMINE_LEGAL_BASIS = 'n-a.';
|
||||
DetailsRadioComponent,
|
||||
],
|
||||
})
|
||||
export class ForceAnnotationDialogComponent extends BaseDialogComponent implements OnInit {
|
||||
export class ForceAnnotationDialogComponent
|
||||
extends IqserDialogComponent<ForceAnnotationDialogComponent, ForceAnnotationData, ForceAnnotationResult>
|
||||
implements OnInit
|
||||
{
|
||||
readonly isDocumine = getConfig().IS_DOCUMINE;
|
||||
readonly options: DetailsRadioOption<ForceAnnotationOption>[];
|
||||
|
||||
readonly form: FormGroup;
|
||||
readonly tableColumns: ValueColumn[] = [{ label: 'Value' }, { label: 'Type' }];
|
||||
readonly tableData: ValueColumn[][] = this._data.annotations.map(redaction => [
|
||||
readonly tableData: ValueColumn[][] = this.data.annotations.map(redaction => [
|
||||
{ label: redaction.value, bold: true },
|
||||
{ label: redaction.typeLabel },
|
||||
]);
|
||||
|
||||
legalOptions: LegalBasisOption[] = [];
|
||||
readonly isImageHint = this._data.annotations.every(annotation => annotation.IMAGE_HINT);
|
||||
readonly isHintDialog = this._data.hint;
|
||||
readonly isImageHint = this.data.annotations.every(annotation => annotation.IMAGE_HINT);
|
||||
readonly isHintDialog = this.data.hint;
|
||||
readonly isImageDialog = this.data.image;
|
||||
readonly dialogTitle = this.#dialogTitle;
|
||||
|
||||
readonly reasonValue = formValueToSignal<ILegalBasisChangeRequest>(this.form.get('reason'));
|
||||
@ -79,12 +81,10 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen
|
||||
|
||||
constructor(
|
||||
private readonly _justificationsService: JustificationsService,
|
||||
protected readonly _dialogRef: MatDialogRef<ForceAnnotationDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA)
|
||||
private readonly _data: { readonly dossier: Dossier; readonly hint: boolean; annotations: AnnotationWrapper[] },
|
||||
private readonly _formBuilder: FormBuilder,
|
||||
) {
|
||||
super(_dialogRef);
|
||||
this.options = getForceAnnotationOptions(this.isDocumine, this.isHintDialog);
|
||||
super();
|
||||
this.options = getForceAnnotationOptions(this.isDocumine, this.isHintDialog, this.isImageDialog);
|
||||
this.form = this.#getForm();
|
||||
}
|
||||
|
||||
@ -102,7 +102,7 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen
|
||||
|
||||
async ngOnInit() {
|
||||
if (!this.isDocumine) {
|
||||
const data = await firstValueFrom(this._justificationsService.getForDossierTemplate(this._data.dossier.dossierTemplateId));
|
||||
const data = await firstValueFrom(this._justificationsService.getForDossierTemplate(this.data.dossier.dossierTemplateId));
|
||||
|
||||
this.legalOptions = data.map(lbm => ({
|
||||
legalBasis: lbm.reason,
|
||||
@ -113,8 +113,8 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen
|
||||
this.legalOptions.sort((a, b) => a.label.localeCompare(b.label));
|
||||
|
||||
// Set pre-existing reason if it exists
|
||||
const existingReason = this.legalOptions.find(option => option.legalBasis === this._data.annotations[0].legalBasis);
|
||||
if (!this._data.hint && existingReason) {
|
||||
const existingReason = this.legalOptions.find(option => option.legalBasis === this.data.annotations[0].legalBasis);
|
||||
if (!this.data.hint && existingReason) {
|
||||
this.form.patchValue({ reason: existingReason }, { emitEvent: false });
|
||||
}
|
||||
}
|
||||
@ -122,12 +122,12 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen
|
||||
}
|
||||
|
||||
save() {
|
||||
this._dialogRef.close(this.#createForceRedactionRequest());
|
||||
this.close(this.#createForceRedactionRequest());
|
||||
}
|
||||
|
||||
#getForm(): UntypedFormGroup {
|
||||
return this._formBuilder.group({
|
||||
reason: this._data.hint ? ['Forced Hint'] : [null, !this.isDocumine ? Validators.required : null],
|
||||
reason: this.data.hint ? ['Forced Hint'] : [null, !this.isDocumine ? Validators.required : null],
|
||||
comment: [null],
|
||||
option: this.options.find(o => o.value === SystemDefaults.FORCE_REDACTION_DEFAULT),
|
||||
});
|
||||
@ -139,7 +139,7 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen
|
||||
request.legalBasis = !this.isDocumine ? this.form.get('reason').value.legalBasis : DOCUMINE_LEGAL_BASIS;
|
||||
request.comment = this.form.get('comment').value;
|
||||
request.reason = this.form.get('reason').value.description;
|
||||
request.option = this.form.get('option').value.value;
|
||||
request.option = this.form.get('option').value?.value;
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<form (submit)="save()" [formGroup]="form">
|
||||
<div [translate]="'manual-annotation.dialog.header.redaction'" class="dialog-header heading-l"></div>
|
||||
|
||||
<div class="dialog-content">
|
||||
<div class="dialog-content redaction">
|
||||
<iqser-details-radio
|
||||
[options]="options"
|
||||
(extraOptionChanged)="extraOptionChanged($event)"
|
||||
@ -43,7 +43,7 @@
|
||||
|
||||
<div class="iqser-input-group w-450">
|
||||
<label [translate]="'manual-annotation.dialog.content.comment'"></label>
|
||||
<textarea formControlName="comment" iqserHasScrollbar name="comment" rows="4" type="text"></textarea>
|
||||
<textarea formControlName="comment" iqserHasScrollbar name="comment" rows="3" type="text"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
}
|
||||
|
||||
.dialog-content {
|
||||
height: 610px;
|
||||
overflow-y: auto;
|
||||
height: 600px;
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
.apply-on-multiple-pages {
|
||||
|
||||
@ -131,7 +131,7 @@ export class RectangleAnnotationDialog
|
||||
reason: [null, Validators.required],
|
||||
comment: [null],
|
||||
classification: [NON_READABLE_CONTENT],
|
||||
option: [this.#getOption(SystemDefaults.RECTANGLE_REDACT_DEFAULT), validatePageRange()],
|
||||
option: [this.#getOption(SystemDefaults.RECTANGLE_REDACT_DEFAULT), validatePageRange(this.data.file.numberOfPages)],
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -159,7 +159,11 @@ export class RedactRecommendationDialogComponent
|
||||
}
|
||||
|
||||
#setDictionaries() {
|
||||
this.dictionaries = this._dictionaryService.getRedactTextDictionaries(this.#dossier.dossierId, !this.#applyToAllDossiers);
|
||||
this.dictionaries = this._dictionaryService.getRedactTextDictionaries(
|
||||
this.#dossier.dossierId,
|
||||
!this.#applyToAllDossiers,
|
||||
this.#dossier.dossierTemplateId,
|
||||
);
|
||||
}
|
||||
|
||||
#selectReason() {
|
||||
|
||||
@ -141,7 +141,7 @@ export class RedactTextDialogComponent
|
||||
|
||||
get #applyToAll() {
|
||||
return this.#isSystemDefault || this._userPreferences.getAddRedactionDefaultExtraOption() === 'undefined'
|
||||
? this.data.applyToAllDossiers ?? true
|
||||
? (this.data.applyToAllDossiers ?? true)
|
||||
: stringToBoolean(this._userPreferences.getAddRedactionDefaultExtraOption());
|
||||
}
|
||||
|
||||
@ -222,7 +222,11 @@ export class RedactTextDialogComponent
|
||||
}
|
||||
|
||||
#setDictionaries() {
|
||||
this.dictionaries = this._dictionaryService.getRedactTextDictionaries(this.#dossier.dossierId, !this.#applyToAllDossiers);
|
||||
this.dictionaries = this._dictionaryService.getRedactTextDictionaries(
|
||||
this.#dossier.dossierId,
|
||||
!this.#applyToAllDossiers,
|
||||
this.#dossier.dossierTemplateId,
|
||||
);
|
||||
}
|
||||
|
||||
#getForm(): FormGroup {
|
||||
|
||||
@ -32,9 +32,11 @@ import {
|
||||
RemoveRedactionResult,
|
||||
ResizeOptions,
|
||||
} from '../../utils/dialog-types';
|
||||
import { formValueToSignal, isJustOne } from '@common-ui/utils';
|
||||
import { isJustOne } from '@common-ui/utils';
|
||||
import { validatePageRange } from '../../utils/form-validators';
|
||||
import { parseRectanglePosition, parseSelectedPageNumbers, prefillPageRange } from '../../utils/enhance-manual-redaction-request.utils';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
templateUrl: './remove-redaction-dialog.component.html',
|
||||
@ -110,13 +112,12 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent<
|
||||
readonly redactedTexts = this.data.redactions.map(annotation => annotation.value);
|
||||
form: UntypedFormGroup = this._formBuilder.group({
|
||||
comment: [null],
|
||||
option: [this.#defaultOption, validatePageRange(true)],
|
||||
option: [this.#defaultOption, validatePageRange(this.data.file.numberOfPages, true)],
|
||||
});
|
||||
|
||||
readonly optionValue = formValueToSignal<DetailsRadioOption<RectangleRedactOption | RemoveRedactionOption>>(this.form.controls.option);
|
||||
readonly isFalsePositive = computed(() => this.optionValue().value === RemoveRedactionOptions.FALSE_POSITIVE);
|
||||
readonly selectedOption = toSignal(this.form.get('option').valueChanges.pipe(map(value => value.value)));
|
||||
readonly isFalsePositive = computed(() => this.selectedOption() === RemoveRedactionOptions.FALSE_POSITIVE);
|
||||
readonly hasFalsePositiveOption = !!this.options.find(option => option.value === RemoveRedactionOptions.FALSE_POSITIVE);
|
||||
|
||||
readonly tableColumns = computed<ValueColumn[]>(() => [
|
||||
{ label: 'Value', width: '25%' },
|
||||
{ label: 'Type', width: '25%' },
|
||||
@ -170,12 +171,9 @@ export class RemoveRedactionDialogComponent extends IqserDialogComponent<
|
||||
}
|
||||
|
||||
save(): void {
|
||||
const optionValue = this.form.controls.option.value.value;
|
||||
const pageNumbers = parseSelectedPageNumbers(
|
||||
this.form.get('option').value.additionalInput?.value,
|
||||
this.data.file,
|
||||
this.data.redactions[0],
|
||||
);
|
||||
const optionValue = this.form.controls.option?.value?.value;
|
||||
const optionInputValue = this.form.controls.option?.value?.additionalInput?.value;
|
||||
const pageNumbers = parseSelectedPageNumbers(optionInputValue, this.data.file, this.data.redactions[0]);
|
||||
const position = parseRectanglePosition(this.data.redactions[0]);
|
||||
|
||||
this.close({
|
||||
|
||||
@ -77,7 +77,7 @@ export class ResizeRedactionDialogComponent extends IqserDialogComponent<
|
||||
|
||||
save() {
|
||||
const formValue = this.form.getRawValue();
|
||||
const updateDictionary = formValue.option.value === ResizeOptions.IN_DOSSIER;
|
||||
const updateDictionary = formValue.option?.value === ResizeOptions.IN_DOSSIER;
|
||||
|
||||
super.close({
|
||||
comment: formValue.comment,
|
||||
|
||||
@ -72,6 +72,7 @@ import { FileHeaderComponent } from './components/file-header/file-header.compon
|
||||
import { StructuredComponentManagementComponent } from './components/structured-component-management/structured-component-management.component';
|
||||
import { DocumentInfoService } from './services/document-info.service';
|
||||
import { RectangleAnnotationDialog } from './dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component';
|
||||
import { ANNOTATION_ACTION_ICONS, ANNOTATION_ACTIONS } from './utils/constants';
|
||||
|
||||
@Component({
|
||||
templateUrl: './file-preview-screen.component.html',
|
||||
@ -248,6 +249,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
this._viewerHeaderService.enableLoadAllAnnotations(); // Reset the button state (since the viewer is reused between files)
|
||||
super.ngOnDetach();
|
||||
this.pdf.instance.UI.hotkeys.off('esc');
|
||||
this.pdf.instance.UI.iframeWindow.document.removeEventListener('click', this.handleViewerClick);
|
||||
this._changeRef.markForCheck();
|
||||
}
|
||||
|
||||
@ -279,10 +281,26 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
}
|
||||
|
||||
@Bind()
|
||||
handleViewerClick() {
|
||||
handleViewerClick(event: MouseEvent) {
|
||||
this._ngZone.run(() => {
|
||||
if (this._multiSelectService.active()) {
|
||||
this._multiSelectService.deactivate();
|
||||
if (event.isTrusted) {
|
||||
const clickedElement = event.target as HTMLElement;
|
||||
const actionIconClicked = ANNOTATION_ACTION_ICONS.some(action =>
|
||||
(clickedElement as HTMLImageElement).src?.includes(action),
|
||||
);
|
||||
const actionClicked = ANNOTATION_ACTIONS.some(action => clickedElement.getAttribute('aria-label')?.includes(action));
|
||||
if (this._multiSelectService.active() && !actionIconClicked && !actionClicked) {
|
||||
if (
|
||||
clickedElement.querySelector('#selectionrect') ||
|
||||
clickedElement.id === `pageWidgetContainer${this.pdf.currentPage()}`
|
||||
) {
|
||||
if (!this._annotationManager.selected.length) {
|
||||
this._multiSelectService.deactivate();
|
||||
}
|
||||
} else {
|
||||
this._multiSelectService.deactivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -317,6 +335,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
this.#restoreOldFilters();
|
||||
this.pdf.instance.UI.hotkeys.on('esc', this.handleEscInsideViewer);
|
||||
this._viewerHeaderService.resetLayers();
|
||||
this.pdf.instance.UI.iframeWindow.document.removeEventListener('click', this.handleViewerClick);
|
||||
this.pdf.instance.UI.iframeWindow.document.addEventListener('click', this.handleViewerClick);
|
||||
}
|
||||
|
||||
|
||||
@ -10,7 +10,6 @@ import {
|
||||
EarmarkOperation,
|
||||
type IBulkLocalRemoveRequest,
|
||||
IBulkRecategorizationRequest,
|
||||
ILegalBasisChangeRequest,
|
||||
IRecategorizationRequest,
|
||||
IRectangle,
|
||||
type IRemoveRedactionRequest,
|
||||
@ -51,6 +50,7 @@ import { FilePreviewStateService } from './file-preview-state.service';
|
||||
import { ManualRedactionService } from './manual-redaction.service';
|
||||
import { SkippedService } from './skipped.service';
|
||||
import { NON_READABLE_CONTENT } from '../dialogs/rectangle-annotation-dialog/rectangle-annotation-dialog.component';
|
||||
import { ForceAnnotationDialogComponent } from '../dialogs/force-redaction-dialog/force-annotation-dialog.component';
|
||||
|
||||
@Injectable()
|
||||
export class AnnotationActionsService {
|
||||
@ -81,40 +81,46 @@ export class AnnotationActionsService {
|
||||
this._dialogService.openDialog('highlightAction', data);
|
||||
}
|
||||
|
||||
forceAnnotation(annotations: AnnotationWrapper[], hint: boolean = false) {
|
||||
async forceAnnotation(annotations: AnnotationWrapper[], hint: boolean = false) {
|
||||
const { dossierId, fileId } = this._state;
|
||||
const data = { dossier: this._state.dossier(), annotations, hint };
|
||||
this._dialogService.openDialog('forceAnnotation', data, (request: ILegalBasisChangeRequest) => {
|
||||
let obs$: Observable<unknown>;
|
||||
if (request.option === ForceAnnotationOptions.ONLY_HERE) {
|
||||
obs$ = this._manualRedactionService.bulkForce(
|
||||
annotations.map(a => ({ ...request, annotationId: a.id })),
|
||||
dossierId,
|
||||
fileId,
|
||||
annotations[0].isIgnoredHint,
|
||||
);
|
||||
} else {
|
||||
const addAnnotationRequest = annotations.map(a => ({
|
||||
comment: request.comment,
|
||||
legalBasis: request.legalBasis,
|
||||
reason: request.reason,
|
||||
positions: a.positions,
|
||||
type: a.type,
|
||||
value: a.value,
|
||||
}));
|
||||
obs$ = this._manualRedactionService.addAnnotation(addAnnotationRequest, dossierId, fileId, {
|
||||
hint,
|
||||
bulkLocal: true,
|
||||
});
|
||||
}
|
||||
this.#processObsAndEmit(obs$).then();
|
||||
});
|
||||
const image = annotations.every(a => a.isImage);
|
||||
const data = { dossier: this._state.dossier(), annotations, hint, image };
|
||||
|
||||
const dialogRef = this._iqserDialog.openDefault(ForceAnnotationDialogComponent, { data });
|
||||
const result = await dialogRef.result();
|
||||
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
|
||||
let obs$: Observable<unknown>;
|
||||
if (result.option === ForceAnnotationOptions.ONLY_HERE || hint || image) {
|
||||
obs$ = this._manualRedactionService.bulkForce(
|
||||
annotations.map(a => ({ ...result, annotationId: a.id })),
|
||||
dossierId,
|
||||
fileId,
|
||||
annotations[0].isIgnoredHint,
|
||||
);
|
||||
} else {
|
||||
const addAnnotationRequest = annotations.map(a => ({
|
||||
comment: result.comment,
|
||||
legalBasis: result.legalBasis,
|
||||
reason: result.reason,
|
||||
positions: a.positions,
|
||||
type: a.type,
|
||||
value: a.value,
|
||||
}));
|
||||
obs$ = this._manualRedactionService.addAnnotation(addAnnotationRequest, dossierId, fileId, {
|
||||
hint,
|
||||
bulkLocal: true,
|
||||
});
|
||||
}
|
||||
this.#processObsAndEmit(obs$).then();
|
||||
}
|
||||
|
||||
async editRedaction(annotations: AnnotationWrapper[]) {
|
||||
const { dossierId, file } = this._state;
|
||||
const allFileAnnotations = this._fileDataService.annotations();
|
||||
const includeUnprocessed = annotations.every(annotation => this.#includeUnprocessed(annotation, true));
|
||||
const data = {
|
||||
annotations,
|
||||
allFileAnnotations,
|
||||
@ -147,15 +153,11 @@ export class AnnotationActionsService {
|
||||
return body;
|
||||
});
|
||||
} else {
|
||||
const originTypes = annotations.map(a => a.type);
|
||||
const originLegalBases = annotations.map(a => a.legalBasis);
|
||||
recategorizeBody = {
|
||||
value: annotations[0].value,
|
||||
type: result.type,
|
||||
legalBasis: result.legalBasis,
|
||||
section: result.section,
|
||||
originTypes,
|
||||
originLegalBases,
|
||||
rectangle: annotations[0].AREA,
|
||||
pageNumbers: result.pageNumbers,
|
||||
position: result.position,
|
||||
@ -170,7 +172,6 @@ export class AnnotationActionsService {
|
||||
dossierId,
|
||||
file().id,
|
||||
this.#getChangedFields(annotations, result),
|
||||
includeUnprocessed,
|
||||
result.option === RedactOrHintOptions.IN_DOCUMENT || !!result.pageNumbers.length,
|
||||
)
|
||||
.pipe(log()),
|
||||
@ -206,8 +207,8 @@ export class AnnotationActionsService {
|
||||
}
|
||||
|
||||
if (
|
||||
result.option.value === RemoveRedactionOptions.FALSE_POSITIVE ||
|
||||
result.option.value === RemoveRedactionOptions.DO_NOT_RECOMMEND
|
||||
result.option?.value === RemoveRedactionOptions.FALSE_POSITIVE ||
|
||||
result.option?.value === RemoveRedactionOptions.DO_NOT_RECOMMEND
|
||||
) {
|
||||
this.#setAsFalsePositive(redactions, result);
|
||||
} else {
|
||||
@ -269,7 +270,6 @@ export class AnnotationActionsService {
|
||||
|
||||
async acceptResize(annotation: AnnotationWrapper, permissions: AnnotationPermissions): Promise<void> {
|
||||
const textAndPositions = await this.#extractTextAndPositions(annotation.id);
|
||||
const includeUnprocessed = this.#includeUnprocessed(annotation);
|
||||
if (annotation.isRecommendation) {
|
||||
const recommendation = {
|
||||
...annotation,
|
||||
@ -320,16 +320,16 @@ export class AnnotationActionsService {
|
||||
await this.cancelResize(annotation);
|
||||
|
||||
const { fileId, dossierId } = this._state;
|
||||
const request = this._manualRedactionService.resize([resizeRequest], dossierId, fileId, includeUnprocessed);
|
||||
const request = this._manualRedactionService.resize([resizeRequest], dossierId, fileId);
|
||||
return this.#processObsAndEmit(request);
|
||||
}
|
||||
|
||||
async cancelResize(annotationWrapper: AnnotationWrapper) {
|
||||
this._annotationManager.resizingAnnotationId = undefined;
|
||||
this._annotationManager.annotationHasBeenResized = false;
|
||||
this._annotationManager.deselect();
|
||||
this._annotationManager.delete(annotationWrapper);
|
||||
await this._annotationDrawService.draw([annotationWrapper], this._skippedService.hideSkipped(), this._state.dossierTemplateId);
|
||||
this._annotationManager.deselect();
|
||||
}
|
||||
|
||||
#generateRectangle(annotationWrapper: AnnotationWrapper) {
|
||||
@ -476,8 +476,7 @@ export class AnnotationActionsService {
|
||||
}
|
||||
|
||||
#removeRedaction(redactions: AnnotationWrapper[], dialogResult: RemoveRedactionResult) {
|
||||
const removeFromDictionary = dialogResult.option.value === RemoveRedactionOptions.IN_DOSSIER;
|
||||
const includeUnprocessed = redactions.every(redaction => this.#includeUnprocessed(redaction, true));
|
||||
const removeFromDictionary = dialogResult.option?.value === RemoveRedactionOptions.IN_DOSSIER;
|
||||
const body = this.#getRemoveRedactionBody(redactions, dialogResult);
|
||||
// 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);
|
||||
@ -505,7 +504,6 @@ export class AnnotationActionsService {
|
||||
fileId,
|
||||
removeFromDictionary,
|
||||
isHint,
|
||||
includeUnprocessed,
|
||||
dialogResult.bulkLocal,
|
||||
),
|
||||
),
|
||||
@ -521,7 +519,6 @@ export class AnnotationActionsService {
|
||||
fileId,
|
||||
removeFromDictionary,
|
||||
isHint,
|
||||
includeUnprocessed,
|
||||
dialogResult.bulkLocal || !!dialogResult.pageNumbers.length,
|
||||
),
|
||||
).then();
|
||||
@ -580,20 +577,6 @@ export class AnnotationActionsService {
|
||||
return { changes: changedFields.join(', ') };
|
||||
}
|
||||
|
||||
//TODO this is temporary, based on RED-8950. Should be removed when a better solution will be found
|
||||
#includeUnprocessed(annotation: AnnotationWrapper, isRemoveOrRecategorize = false) {
|
||||
const processed = annotation.entry.manualChanges.at(-1)?.processed;
|
||||
if (!processed) {
|
||||
const autoAnalysisDisabled = this._state.file().excludedFromAutomaticAnalysis;
|
||||
const addedLocallyWhileDisabled = annotation.manual;
|
||||
if (autoAnalysisDisabled) {
|
||||
return addedLocallyWhileDisabled;
|
||||
}
|
||||
return isRemoveOrRecategorize && addedLocallyWhileDisabled;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#getRemoveRedactionBody(
|
||||
redactions: AnnotationWrapper[],
|
||||
dialogResult: RemoveRedactionResult,
|
||||
@ -603,8 +586,6 @@ export class AnnotationActionsService {
|
||||
return {
|
||||
value: redaction.value,
|
||||
rectangle: redaction.value === NON_READABLE_CONTENT,
|
||||
originTypes: [redaction.entry.type],
|
||||
originLegalBases: [redaction.legalBasis],
|
||||
pageNumbers: dialogResult.pageNumbers,
|
||||
position: dialogResult.position,
|
||||
comment: dialogResult.comment,
|
||||
@ -615,8 +596,8 @@ export class AnnotationActionsService {
|
||||
annotationId: redaction.id,
|
||||
value: redaction.value,
|
||||
comment: dialogResult.comment,
|
||||
removeFromDictionary: dialogResult.option.value === RemoveRedactionOptions.IN_DOSSIER,
|
||||
removeFromAllDossiers: !!dialogResult.option.additionalCheck?.checked || !!dialogResult.applyToAllDossiers,
|
||||
removeFromDictionary: dialogResult.option?.value === RemoveRedactionOptions.IN_DOSSIER,
|
||||
removeFromAllDossiers: !!dialogResult.option?.additionalCheck?.checked || !!dialogResult.applyToAllDossiers,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,10 +3,9 @@ import { MatDialog } from '@angular/material/dialog';
|
||||
import { ConfirmationDialogComponent, DialogConfig, DialogService } from '@iqser/common-ui';
|
||||
import { ChangeLegalBasisDialogComponent } from '../dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component';
|
||||
import { DocumentInfoDialogComponent } from '../dialogs/document-info-dialog/document-info-dialog.component';
|
||||
import { ForceAnnotationDialogComponent } from '../dialogs/force-redaction-dialog/force-annotation-dialog.component';
|
||||
import { HighlightActionDialogComponent } from '../dialogs/highlight-action-dialog/highlight-action-dialog.component';
|
||||
|
||||
type DialogType = 'confirm' | 'documentInfo' | 'changeLegalBasis' | 'forceAnnotation' | 'highlightAction';
|
||||
type DialogType = 'confirm' | 'documentInfo' | 'changeLegalBasis' | 'highlightAction';
|
||||
|
||||
@Injectable()
|
||||
export class FilePreviewDialogService extends DialogService<DialogType> {
|
||||
@ -22,9 +21,6 @@ export class FilePreviewDialogService extends DialogService<DialogType> {
|
||||
changeLegalBasis: {
|
||||
component: ChangeLegalBasisDialogComponent,
|
||||
},
|
||||
forceAnnotation: {
|
||||
component: ForceAnnotationDialogComponent,
|
||||
},
|
||||
highlightAction: {
|
||||
component: HighlightActionDialogComponent,
|
||||
},
|
||||
|
||||
@ -75,13 +75,10 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
|
||||
body: List<IRecategorizationRequest> | IBulkRecategorizationRequest,
|
||||
dossierId: string,
|
||||
fileId: string,
|
||||
successMessageParameters?: {
|
||||
[key: string]: string;
|
||||
},
|
||||
includeUnprocessed = false,
|
||||
successMessageParameters?: { [p: string]: string },
|
||||
bulkLocal = false,
|
||||
) {
|
||||
return this.#recategorize(body, dossierId, fileId, includeUnprocessed, bulkLocal).pipe(
|
||||
return this.#recategorize(body, dossierId, fileId, bulkLocal).pipe(
|
||||
this.#showToast('recategorize-annotation', false, successMessageParameters),
|
||||
);
|
||||
}
|
||||
@ -117,10 +114,9 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
|
||||
fileId: string,
|
||||
removeFromDictionary = false,
|
||||
isHint = false,
|
||||
includeUnprocessed = false,
|
||||
bulkLocal = false,
|
||||
) {
|
||||
return this.#remove(body, dossierId, fileId, includeUnprocessed, bulkLocal).pipe(
|
||||
return this.#remove(body, dossierId, fileId, bulkLocal).pipe(
|
||||
this.#showToast(!isHint ? 'remove' : 'remove-hint', removeFromDictionary),
|
||||
);
|
||||
}
|
||||
@ -154,36 +150,23 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
|
||||
return this._post(body, `${this.#bulkRedaction}/force/${dossierId}/${fileId}`).pipe(this.#log('Force redaction', body));
|
||||
}
|
||||
|
||||
resize(body: List<IResizeRequest>, dossierId: string, fileId: string, includeUnprocessed = false) {
|
||||
return this._post(body, `${this.#bulkRedaction}/resize/${dossierId}/${fileId}?includeUnprocessed=${includeUnprocessed}`).pipe(
|
||||
this.#log('Resize', body),
|
||||
);
|
||||
resize(body: List<IResizeRequest>, dossierId: string, fileId: string) {
|
||||
return this._post(body, `${this.#bulkRedaction}/resize/${dossierId}/${fileId}`).pipe(this.#log('Resize', body));
|
||||
}
|
||||
|
||||
#recategorize(
|
||||
body: List<IRecategorizationRequest> | IBulkRecategorizationRequest,
|
||||
dossierId: string,
|
||||
fileId: string,
|
||||
includeUnprocessed = false,
|
||||
bulkLocal = false,
|
||||
) {
|
||||
const bulkPath = bulkLocal ? this.#bulkLocal : this.#bulkRedaction;
|
||||
return this._post(body, `${bulkPath}/recategorize/${dossierId}/${fileId}?includeUnprocessed=${includeUnprocessed}`).pipe(
|
||||
this.#log('Recategorize', body),
|
||||
);
|
||||
return this._post(body, `${bulkPath}/recategorize/${dossierId}/${fileId}`).pipe(this.#log('Recategorize', body));
|
||||
}
|
||||
|
||||
#remove(
|
||||
body: List<IRemoveRedactionRequest> | IBulkLocalRemoveRequest,
|
||||
dossierId: string,
|
||||
fileId: string,
|
||||
includeUnprocessed = false,
|
||||
bulkLocal = false,
|
||||
) {
|
||||
#remove(body: List<IRemoveRedactionRequest> | IBulkLocalRemoveRequest, dossierId: string, fileId: string, bulkLocal = false) {
|
||||
const bulkPath = bulkLocal ? this.#bulkLocal : this.#bulkRedaction;
|
||||
return this._post(body, `${bulkPath}/remove/${dossierId}/${fileId}?includeUnprocessed=${includeUnprocessed}`).pipe(
|
||||
this.#log('Remove', body),
|
||||
);
|
||||
return this._post(body, `${bulkPath}/remove/${dossierId}/${fileId}`).pipe(this.#log('Remove', body));
|
||||
}
|
||||
|
||||
#log(action: string, body: unknown) {
|
||||
|
||||
@ -26,7 +26,7 @@ export class PdfAnnotationActionsService {
|
||||
get(annotations: AnnotationWrapper[], annotationChangesAllowed: boolean): IHeaderElement[] {
|
||||
const availableActions: IHeaderElement[] = [];
|
||||
const permissions = this.#getAnnotationsPermissions(annotations);
|
||||
const sameType = annotations.every(a => a.type === annotations[0].type);
|
||||
const sameType = annotations.every(a => a.superType === annotations[0].superType);
|
||||
|
||||
// you can only resize one annotation at a time
|
||||
if (permissions.canResizeAnnotation && annotationChangesAllowed) {
|
||||
|
||||
@ -389,10 +389,10 @@ export class PdfProxyService {
|
||||
this._ngZone.run(() => {
|
||||
if (allAreVisible) {
|
||||
this._annotationManager.hide(viewerAnnotations);
|
||||
this._annotationManager.addToHidden(viewerAnnotations[0].Id);
|
||||
viewerAnnotations.forEach(a => this._annotationManager.addToHidden(a.Id));
|
||||
} else {
|
||||
this._annotationManager.show(viewerAnnotations);
|
||||
this._annotationManager.removeFromHidden(viewerAnnotations[0].Id);
|
||||
viewerAnnotations.forEach(a => this._annotationManager.removeFromHidden(a.Id));
|
||||
}
|
||||
this._annotationManager.deselect();
|
||||
});
|
||||
|
||||
@ -45,3 +45,31 @@ export const TextPopups = {
|
||||
} as const;
|
||||
|
||||
export const HIDE_SKIPPED = 'hide-skipped';
|
||||
|
||||
export const ANNOTATION_ACTION_ICONS = [
|
||||
'resize',
|
||||
'edit',
|
||||
'trash',
|
||||
'check',
|
||||
'thumb-up',
|
||||
'pdftron-action-add-redaction',
|
||||
'visibility-off',
|
||||
] as const;
|
||||
export const ANNOTATION_ACTIONS = [
|
||||
'Resize',
|
||||
'Größe ändern',
|
||||
'Edit',
|
||||
'Bearbeiten',
|
||||
'Remove',
|
||||
'Entfernen',
|
||||
'Accept recommendation',
|
||||
'Empfehlung annehmen',
|
||||
'Force redaction',
|
||||
'Schwärzung erzwingen',
|
||||
'Force hint',
|
||||
'Hinweis erzwingen',
|
||||
'Redact',
|
||||
'Schwärzen',
|
||||
'Hide',
|
||||
'Ausblenden',
|
||||
] as const;
|
||||
|
||||
@ -30,7 +30,11 @@ const DOCUMENT_ICON = 'iqser:document';
|
||||
const FOLDER_ICON = 'red:folder';
|
||||
const REMOVE_FROM_DICT_ICON = 'red:remove-from-dict';
|
||||
|
||||
export const getEditRedactionOptions = (): DetailsRadioOption<EditRedactionOption>[] => {
|
||||
export const getEditRedactionOptions = (hint: boolean): DetailsRadioOption<EditRedactionOption>[] => {
|
||||
if (hint) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
label: editRedactionTranslations.onlyHere.label,
|
||||
@ -118,6 +122,7 @@ export const getRectangleRedactOptions = (action: 'add' | 'edit' | 'remove' = 'a
|
||||
description: translations.multiplePages.extraOptionDescription,
|
||||
placeholder: translations.multiplePages.extraOptionPlaceholder,
|
||||
value: '',
|
||||
errorCode: 'invalidRange',
|
||||
},
|
||||
},
|
||||
];
|
||||
@ -131,22 +136,21 @@ export const getResizeRedactionOptions = (
|
||||
isApprover: boolean,
|
||||
canResizeInDictionary: boolean,
|
||||
): DetailsRadioOption<ResizeRedactionOption>[] => {
|
||||
if (isRss || !canResizeInDictionary) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const translations = resizeRedactionTranslations;
|
||||
const options: DetailsRadioOption<ResizeRedactionOption>[] = [
|
||||
const dictBasedType = redaction.isModifyDictionary;
|
||||
|
||||
return [
|
||||
{
|
||||
label: translations.onlyHere.label,
|
||||
description: translations.onlyHere.description,
|
||||
icon: PIN_ICON,
|
||||
value: ResizeOptions.ONLY_HERE,
|
||||
},
|
||||
];
|
||||
|
||||
if (isRss) {
|
||||
return options;
|
||||
}
|
||||
if (canResizeInDictionary) {
|
||||
const dictBasedType = redaction.isModifyDictionary;
|
||||
options.push({
|
||||
{
|
||||
label: translations.inDossier.label,
|
||||
description: translations.inDossier.description,
|
||||
descriptionParams: { dossierName: dossier.dossierName },
|
||||
@ -159,9 +163,8 @@ export const getResizeRedactionOptions = (
|
||||
checked: applyToAllDossiers,
|
||||
hidden: !isApprover,
|
||||
},
|
||||
});
|
||||
}
|
||||
return options;
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
export const getRemoveRedactionOptions = (
|
||||
@ -172,9 +175,10 @@ export const getRemoveRedactionOptions = (
|
||||
const translations = isDocumine ? removeAnnotationTranslations : removeRedactionTranslations;
|
||||
const { permissions, redactions, isApprover, falsePositiveContext } = data;
|
||||
const isBulk = redactions.length > 1;
|
||||
const isImage = redactions.reduce((acc, next) => acc && next.isImage, true);
|
||||
|
||||
const options: DetailsRadioOption<RemoveRedactionOption>[] = [];
|
||||
if (permissions.canRemoveOnlyHere) {
|
||||
if (permissions.canRemoveOnlyHere && !isImage) {
|
||||
options.push({
|
||||
label: translations.ONLY_HERE.label,
|
||||
description: isBulk ? translations.ONLY_HERE.descriptionBulk : translations.ONLY_HERE.description,
|
||||
@ -187,15 +191,15 @@ export const getRemoveRedactionOptions = (
|
||||
value: RemoveRedactionOptions.ONLY_HERE,
|
||||
});
|
||||
|
||||
options.push({
|
||||
label: removeRedactionTranslations.IN_DOCUMENT.label,
|
||||
description: removeRedactionTranslations.IN_DOCUMENT.description,
|
||||
descriptionParams: {
|
||||
isImage: redactions[0].isImage ? 'image' : redactions[0].typeLabel,
|
||||
},
|
||||
icon: DOCUMENT_ICON,
|
||||
value: RemoveRedactionOptions.IN_DOCUMENT,
|
||||
});
|
||||
const isHint = redactions.reduce((acc, next) => acc && next.isHint, true);
|
||||
if (!isHint) {
|
||||
options.push({
|
||||
label: removeRedactionTranslations.IN_DOCUMENT.label,
|
||||
description: removeRedactionTranslations.IN_DOCUMENT.description,
|
||||
icon: DOCUMENT_ICON,
|
||||
value: RemoveRedactionOptions.IN_DOCUMENT,
|
||||
});
|
||||
}
|
||||
}
|
||||
if (permissions.canRemoveFromDictionary) {
|
||||
options.push({
|
||||
@ -264,8 +268,12 @@ export const getRemoveRedactionOptions = (
|
||||
return options;
|
||||
};
|
||||
|
||||
export const getForceAnnotationOptions = (isDocumine: boolean, isHint: boolean): DetailsRadioOption<ForceAnnotationOption>[] => {
|
||||
if (isDocumine || isHint) {
|
||||
export const getForceAnnotationOptions = (
|
||||
isDocumine: boolean,
|
||||
isHint: boolean,
|
||||
isImage: boolean,
|
||||
): DetailsRadioOption<ForceAnnotationOption>[] => {
|
||||
if (isDocumine || isHint || isImage) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
@ -73,6 +73,21 @@ export interface EditRedactionData {
|
||||
export type AddAnnotationData = RedactTextData;
|
||||
export type AddHintData = RedactTextData;
|
||||
|
||||
export interface ForceAnnotationData {
|
||||
readonly dossier: Dossier;
|
||||
readonly annotations: AnnotationWrapper[];
|
||||
readonly hint: boolean;
|
||||
readonly image: boolean;
|
||||
}
|
||||
|
||||
export interface ForceAnnotationResult {
|
||||
readonly annotationId?: string;
|
||||
readonly comment?: string;
|
||||
readonly legalBasis?: string;
|
||||
readonly reason?: string;
|
||||
readonly option?: ForceAnnotationOption;
|
||||
}
|
||||
|
||||
export interface RedactTextResult {
|
||||
redaction: IManualRedactionEntry;
|
||||
dictionary: Dictionary;
|
||||
|
||||
@ -1,12 +1,26 @@
|
||||
import { AbstractControl, ValidatorFn } from '@angular/forms';
|
||||
|
||||
export const validatePageRange = (allowEmpty = false): ValidatorFn => {
|
||||
export const validatePageRange = (numberOfPages: number, allowEmpty = false): ValidatorFn => {
|
||||
return (control: AbstractControl): { [key: string]: any } | null => {
|
||||
const option = control.value;
|
||||
if (option?.additionalInput) {
|
||||
const value = option.additionalInput.value;
|
||||
const validRange = /^(\d+(-\d+)?)(,\d+(-\d+)?)*$/.test(value);
|
||||
return validRange || (!value.length && allowEmpty) ? null : { invalidRange: true };
|
||||
|
||||
if (!validRange && !(value.length === 0 && allowEmpty)) {
|
||||
return { invalidRange: true };
|
||||
}
|
||||
|
||||
const ranges = value.split(',');
|
||||
const isWithinRange = ranges.every(range => {
|
||||
const [start, end] = range.split('-').map(Number);
|
||||
if (end) {
|
||||
return start >= 1 && end <= numberOfPages && start < end;
|
||||
}
|
||||
return start >= 1 && start <= numberOfPages;
|
||||
});
|
||||
|
||||
return isWithinRange || (value.length === 0 && allowEmpty) ? null : { invalidRange: true };
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
@ -148,7 +148,7 @@ export class PdfViewer {
|
||||
this.#instance = await this.#getInstance(htmlElement);
|
||||
|
||||
if (environment.production) {
|
||||
this.#instance.Core.setCustomFontURL('https://' + window.location.host + this.#convertPath('/assets/pdftron'));
|
||||
this.#instance.Core.setCustomFontURL(window.location.origin + this.#convertPath('/assets/pdftron/fonts'));
|
||||
}
|
||||
|
||||
await this.runWithCleanup(async () => {
|
||||
@ -359,12 +359,16 @@ export class PdfViewer {
|
||||
const options: WebViewerOptions = {
|
||||
licenseKey: this.#licenseKey,
|
||||
fullAPI: true,
|
||||
path: this.#convertPath('/assets/wv-resources/10.10.1'),
|
||||
path: this.#convertPath('/assets/wv-resources/11.0.0'),
|
||||
css: this.#convertPath('/assets/pdftron/stylesheet.css'),
|
||||
backendType: 'ems',
|
||||
// This should be migrated to v11
|
||||
ui: 'legacy',
|
||||
};
|
||||
|
||||
return WebViewer(options, htmlElement);
|
||||
// This should be migrated to v11
|
||||
// https://docs.apryse.com/web/get-started/migrating-to-v11/
|
||||
return WebViewer.Iframe(options, htmlElement);
|
||||
}
|
||||
|
||||
#isElementActive(element: string): boolean {
|
||||
|
||||
@ -8,7 +8,9 @@
|
||||
>
|
||||
<redaction-annotation-icon
|
||||
[color]="dictionary.hexColor"
|
||||
[label]="dictionary.hint ? 'H' : 'R'"
|
||||
[label]="
|
||||
dictionary.hint ? (workloadTranslations['hint'] | translate)[0] : (workloadTranslations['redaction'] | translate)[0]
|
||||
"
|
||||
type="square"
|
||||
></redaction-annotation-icon>
|
||||
<div class="details">
|
||||
|
||||
@ -20,6 +20,7 @@ import { AnnotationIconComponent } from '@shared/components/annotation-icon/anno
|
||||
import { MatTooltip } from '@angular/material/tooltip';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { workloadTranslations } from '@translations/workload-translations';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-edit-dossier-dictionary',
|
||||
@ -47,6 +48,7 @@ export class EditDossierDictionaryComponent implements OnInit {
|
||||
activeEntryType = DictionaryEntryTypes.ENTRY;
|
||||
entriesToDisplay: List = [];
|
||||
readonly entryTypes = DictionaryEntryTypes;
|
||||
protected readonly workloadTranslations = workloadTranslations;
|
||||
@ViewChild(DictionaryManagerComponent, { static: false }) private readonly _dictionaryManager: DictionaryManagerComponent;
|
||||
|
||||
constructor(
|
||||
|
||||
@ -44,11 +44,15 @@
|
||||
<div class="iqser-input-group w-300">
|
||||
<label translate="edit-dossier-dialog.general-info.form.dossier-state.label"></label>
|
||||
<mat-form-field>
|
||||
<mat-select [placeholder]="statusPlaceholder" formControlName="dossierStatusId">
|
||||
<mat-option *ngFor="let stateId of states" [value]="stateId">
|
||||
<div [matTooltip]="getStateName(stateId)" class="flex-align-items-center" matTooltipPosition="after">
|
||||
<iqser-small-chip *ngIf="!!stateId" [color]="getStateColor(stateId)"></iqser-small-chip>
|
||||
<div class="clamp-1">{{ getStateName(stateId) }}</div>
|
||||
<mat-select [placeholder]="statePlaceholder()" formControlName="dossierStatusId">
|
||||
<mat-option *ngFor="let stateId of states()" [value]="stateId">
|
||||
<div
|
||||
[matTooltip]="stateNameAndColor()[stateId]?.name"
|
||||
class="flex-align-items-center"
|
||||
matTooltipPosition="after"
|
||||
>
|
||||
<iqser-small-chip *ngIf="!!stateId" [color]="stateNameAndColor()[stateId]?.color"></iqser-small-chip>
|
||||
<div class="clamp-1">{{ stateNameAndColor()[stateId]?.name }}</div>
|
||||
</div>
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
@ -80,7 +84,7 @@
|
||||
<div class="dialog-actions">
|
||||
<iqser-icon-button
|
||||
(action)="deleteDossier()"
|
||||
*ngIf="permissionsService.canDeleteDossier(dossier)"
|
||||
*ngIf="permissionsService.canDeleteDossier(dossier())"
|
||||
[attr.help-mode-key]="'edit_dossier_delete_dossier_DIALOG'"
|
||||
[buttonId]="'deleteDossier'"
|
||||
[icon]="'iqser:trash'"
|
||||
@ -90,7 +94,7 @@
|
||||
|
||||
<iqser-icon-button
|
||||
(action)="archiveDossier()"
|
||||
*ngIf="permissionsService.canArchiveDossier(dossier)"
|
||||
*ngIf="permissionsService.canArchiveDossier(dossier())"
|
||||
[attr.help-mode-key]="'edit_dossier_archive_dossier_DIALOG'"
|
||||
[icon]="'red:archive'"
|
||||
[label]="'dossier-listing.archive.action' | translate"
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import { NgForOf, NgIf } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
|
||||
import { ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, computed, effect, input, OnInit, signal, untracked } from '@angular/core';
|
||||
import { FormGroup, ReactiveFormsModule, UntypedFormBuilder, Validators } from '@angular/forms';
|
||||
import { MatCheckbox } from '@angular/material/checkbox';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
import { MatDialogRef } from '@angular/material/dialog';
|
||||
import { MatFormField, MatSuffix } from '@angular/material/form-field';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
import { MatOption, MatSelect } from '@angular/material/select';
|
||||
import { MatOption, MatSelect, MatSelectTrigger } from '@angular/material/select';
|
||||
import { MatTooltip } from '@angular/material/tooltip';
|
||||
import { Router } from '@angular/router';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
@ -36,6 +36,16 @@ import { firstValueFrom } from 'rxjs';
|
||||
import { DossiersDialogService } from '../../../services/dossiers-dialog.service';
|
||||
import { type EditDossierDialogComponent } from '../edit-dossier-dialog.component';
|
||||
import { EditDossierSaveResult, EditDossierSectionInterface } from '../edit-dossier-section.interface';
|
||||
import { AsControl, formValueToSignal, isJustOne } from '@common-ui/utils';
|
||||
import { DossierStatesService } from '@services/entity-services/dossier-states.service';
|
||||
|
||||
interface GeneralInfoForm {
|
||||
dossierName: string;
|
||||
dossierTemplateId: string;
|
||||
dossierStatusId?: string;
|
||||
description?: string;
|
||||
dueDate?: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-edit-dossier-general-info',
|
||||
@ -59,18 +69,36 @@ import { EditDossierSaveResult, EditDossierSectionInterface } from '../edit-doss
|
||||
MatSuffix,
|
||||
IconButtonComponent,
|
||||
NgIf,
|
||||
MatSelectTrigger,
|
||||
],
|
||||
})
|
||||
export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSectionInterface {
|
||||
@Input() dossier: Dossier;
|
||||
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
|
||||
form: UntypedFormGroup;
|
||||
statusPlaceholder: string;
|
||||
readonly dossier = input<Dossier>();
|
||||
hasDueDate: boolean;
|
||||
dossierTemplates: IDossierTemplate[];
|
||||
states: string[];
|
||||
form: FormGroup<AsControl<GeneralInfoForm>> = this._formBuilder.group({
|
||||
dossierName: [null, Validators.required],
|
||||
dossierTemplateId: [null, Validators.required],
|
||||
dossierStatusId: [null],
|
||||
description: [null],
|
||||
dueDate: [null],
|
||||
});
|
||||
initialFormValue: GeneralInfoForm;
|
||||
readonly dossierStatusIdControl = formValueToSignal(this.form.controls.dossierStatusId);
|
||||
readonly dossierTemplateIdControl = formValueToSignal<GeneralInfoForm['dossierTemplateId']>(this.form.controls.dossierTemplateId);
|
||||
readonly states = signal([null]);
|
||||
readonly stateNameAndColor = computed(() => {
|
||||
const nameAndColor = {};
|
||||
this.states().forEach(stateId => {
|
||||
nameAndColor[stateId] = {
|
||||
name: this.#getStateName(stateId, untracked(this.dossierTemplateIdControl)),
|
||||
color: this.#getStateColor(stateId, untracked(this.dossierTemplateIdControl)),
|
||||
};
|
||||
});
|
||||
return nameAndColor;
|
||||
});
|
||||
readonly statePlaceholder = computed(() => this.#statePlaceholder);
|
||||
|
||||
constructor(
|
||||
readonly permissionsService: PermissionsService,
|
||||
@ -87,18 +115,40 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _archivedDossiersService: ArchivedDossiersService,
|
||||
) {}
|
||||
private readonly _changeDetectorRef: ChangeDetectorRef,
|
||||
private readonly _dossierStatesService: DossierStatesService,
|
||||
) {
|
||||
effect(() => {
|
||||
const shouldBeDisabled = this.#formValue.find(item => item.key === 'dossierTemplateId')?.disabled;
|
||||
if (
|
||||
(this.dossierStatusIdControl() !== this.initialFormValue.dossierStatusId && this.dossierStatusIdControl()) ||
|
||||
shouldBeDisabled
|
||||
) {
|
||||
this.form.controls.dossierTemplateId.disable();
|
||||
} else {
|
||||
this.form.controls.dossierTemplateId.enable();
|
||||
}
|
||||
});
|
||||
|
||||
effect(
|
||||
() => {
|
||||
this.states.set(this.#statesForDossierTemplate);
|
||||
this.#onDossierTemplateChange();
|
||||
},
|
||||
{ allowSignalWrites: true },
|
||||
);
|
||||
}
|
||||
|
||||
get changed(): boolean {
|
||||
for (const key of Object.keys(this.form.getRawValue())) {
|
||||
if (key === 'dueDate') {
|
||||
if (this.hasDueDate !== !!this.dossier.dueDate) {
|
||||
if (this.hasDueDate !== !!this.dossier().dueDate) {
|
||||
return true;
|
||||
}
|
||||
if (this.hasDueDate && !dayjs(this.dossier.dueDate).isSame(dayjs(this.form.get(key).value), 'day')) {
|
||||
if (this.hasDueDate && !dayjs(this.dossier().dueDate).isSame(dayjs(this.form.get(key).value), 'day')) {
|
||||
return true;
|
||||
}
|
||||
} else if (this.dossier[key] !== this.form.get(key).value) {
|
||||
} else if (this.dossier()[key] !== this.form.get(key).value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -114,40 +164,87 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
|
||||
return this.hasDueDate && this.form.get('dueDate').value === null;
|
||||
}
|
||||
|
||||
get #statusPlaceholder(): string {
|
||||
get #statePlaceholder(): string {
|
||||
return this._translateService.instant(
|
||||
this.states.length === 1
|
||||
isJustOne(this.states())
|
||||
? 'edit-dossier-dialog.general-info.form.dossier-state.no-state-placeholder'
|
||||
: 'dossier-state.placeholder',
|
||||
) as string;
|
||||
}
|
||||
|
||||
get #statesForDossierTemplate() {
|
||||
return [
|
||||
null,
|
||||
...this._dossierStatesMapService
|
||||
.get(this.dossierTemplateIdControl() ?? untracked(this.dossier).dossierTemplateId)
|
||||
.map(s => s.id),
|
||||
];
|
||||
}
|
||||
|
||||
get #formValue(): { key: string; value: string; disabled: boolean }[] {
|
||||
const dossier = untracked(this.dossier);
|
||||
const formFieldWithArchivedCheck = value => ({ value, disabled: !dossier.isActive });
|
||||
const states = untracked(this.states);
|
||||
return [
|
||||
{
|
||||
key: 'dossierName',
|
||||
...formFieldWithArchivedCheck(dossier.dossierName),
|
||||
},
|
||||
{
|
||||
key: 'dossierTemplateId',
|
||||
value: dossier.dossierTemplateId,
|
||||
disabled: this._dossierStatsService.get(dossier.id).hasFiles || !dossier.isActive,
|
||||
},
|
||||
{
|
||||
key: 'dossierStatusId',
|
||||
value: dossier.dossierStatusId,
|
||||
disabled: isJustOne(states) || !dossier.isActive,
|
||||
},
|
||||
{
|
||||
key: 'description',
|
||||
...formFieldWithArchivedCheck(dossier.description),
|
||||
},
|
||||
{
|
||||
key: 'dueDate',
|
||||
...formFieldWithArchivedCheck(dossier.dueDate),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.states = [null, ...this._dossierStatesMapService.get(this.dossier.dossierTemplateId).map(s => s.id)];
|
||||
this.statusPlaceholder = this.#statusPlaceholder;
|
||||
this.#filterInvalidDossierTemplates();
|
||||
this.form = this.#getForm();
|
||||
if (!this.permissionsService.canEditDossier(this.dossier)) {
|
||||
if (isJustOne(this._dossierTemplatesService.all)) {
|
||||
this._loadingService.loadWhile(
|
||||
firstValueFrom(this._dossierTemplatesService.loadOnlyDossierTemplates()).then(async () => {
|
||||
await firstValueFrom(this._dossierStatesService.loadAllForAllTemplates());
|
||||
this.#filterInvalidDossierTemplates();
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
this.#filterInvalidDossierTemplates();
|
||||
}
|
||||
this.#patchFormValue();
|
||||
if (!this.permissionsService.canEditDossier(this.dossier())) {
|
||||
this.form.disable();
|
||||
}
|
||||
this.hasDueDate = !!this.dossier.dueDate;
|
||||
this.hasDueDate = !!this.dossier().dueDate;
|
||||
}
|
||||
|
||||
revert() {
|
||||
this.form.reset({
|
||||
dossierName: this.dossier.dossierName,
|
||||
dossierTemplateId: this.dossier.dossierTemplateId,
|
||||
dossierStatusId: this.dossier.dossierStatusId,
|
||||
description: this.dossier.description,
|
||||
dueDate: this.dossier.dueDate,
|
||||
dossierName: this.dossier().dossierName,
|
||||
dossierTemplateId: this.dossier().dossierTemplateId,
|
||||
dossierStatusId: this.dossier().dossierStatusId,
|
||||
description: this.dossier().description,
|
||||
dueDate: this.dossier().dueDate,
|
||||
});
|
||||
this.hasDueDate = !!this.dossier.dueDate;
|
||||
this.hasDueDate = !!this.dossier().dueDate;
|
||||
this.initialFormValue = this.form.getRawValue();
|
||||
}
|
||||
|
||||
async save(): EditDossierSaveResult {
|
||||
const dueDate = dateWithoutTime(dayjs(this.form.get('dueDate').value));
|
||||
const dossier = {
|
||||
...this.dossier,
|
||||
...this.dossier(),
|
||||
dossierName: this.form.get('dossierName').value,
|
||||
description: this.form.get('description').value,
|
||||
dueDate: dueDate.isValid() ? dueDate.toISOString() : undefined,
|
||||
@ -156,9 +253,10 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
|
||||
} as IDossierRequest;
|
||||
|
||||
const updatedDossier = await firstValueFrom(this._dossiersService.createOrUpdate(dossier));
|
||||
if (updatedDossier && updatedDossier.dossierTemplateId !== this.dossier.dossierTemplateId) {
|
||||
if (updatedDossier && updatedDossier.dossierTemplateId !== this.dossier().dossierTemplateId) {
|
||||
await this._router.navigate([updatedDossier.routerLink]);
|
||||
}
|
||||
this.initialFormValue = this.form.getRawValue();
|
||||
return { success: !!updatedDossier };
|
||||
}
|
||||
|
||||
@ -171,14 +269,14 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
|
||||
requireInput: true,
|
||||
denyText: _('confirmation-dialog.delete-dossier.deny-text'),
|
||||
translateParams: {
|
||||
dossierName: this.dossier.dossierName,
|
||||
dossierName: this.dossier().dossierName,
|
||||
dossiersCount: 1,
|
||||
},
|
||||
};
|
||||
|
||||
this._dialogService.openDialog('confirm', data, async () => {
|
||||
this._loadingService.start();
|
||||
const successful = await this._trashService.deleteDossier(this.dossier);
|
||||
const successful = await this._trashService.deleteDossier(this.dossier());
|
||||
if (successful) {
|
||||
await this.#closeDialogAndRedirectToDossier();
|
||||
}
|
||||
@ -194,7 +292,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
|
||||
confirmationText: _('confirm-archive-dossier.archive'),
|
||||
denyText: _('confirm-archive-dossier.cancel'),
|
||||
titleColor: TitleColors.WARN,
|
||||
translateParams: { ...this.dossier },
|
||||
translateParams: { ...this.dossier() },
|
||||
checkboxes: [{ value: false, label: _('confirm-archive-dossier.checkbox.documents') }],
|
||||
toastMessage: _('confirm-archive-dossier.toast-error'),
|
||||
};
|
||||
@ -202,10 +300,10 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
|
||||
this._dialogService.openDialog('confirm', data, async result => {
|
||||
if (result === ConfirmOptions.CONFIRM) {
|
||||
this._loadingService.start();
|
||||
await firstValueFrom(this._archivedDossiersService.archive([this.dossier]));
|
||||
await firstValueFrom(this._archivedDossiersService.archive([this.dossier()]));
|
||||
this._toaster.success(_('dossier-listing.archive.archive-succeeded'), {
|
||||
params: {
|
||||
dossierName: this.dossier.dossierName,
|
||||
dossierName: this.dossier().dossierName,
|
||||
},
|
||||
});
|
||||
this._editDossierDialogRef.close();
|
||||
@ -214,15 +312,6 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
|
||||
});
|
||||
}
|
||||
|
||||
getStateName(stateId: string): string {
|
||||
return (this._dossierStatesMapService.get(this.dossier.dossierTemplateId, stateId)?.name ||
|
||||
this._translateService.instant('dossier-state.placeholder')) as string;
|
||||
}
|
||||
|
||||
getStateColor(stateId: string): string {
|
||||
return this._dossierStatesMapService.get(this.dossier.dossierTemplateId, stateId).color;
|
||||
}
|
||||
|
||||
toggleDueDateField() {
|
||||
this.hasDueDate = !this.hasDueDate;
|
||||
if (!this.hasDueDate) {
|
||||
@ -230,46 +319,63 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
|
||||
}
|
||||
}
|
||||
|
||||
#getStateName(stateId: string, templateId: string): string {
|
||||
return (this._dossierStatesMapService.get(templateId, stateId)?.name ||
|
||||
this._translateService.instant('dossier-state.placeholder')) as string;
|
||||
}
|
||||
|
||||
#getStateColor(stateId: string, templateId: string): string {
|
||||
return this._dossierStatesMapService.get(templateId, stateId)?.color;
|
||||
}
|
||||
|
||||
#patchFormValue() {
|
||||
this.#formValue.forEach(formValue => {
|
||||
this.form.patchValue({ [formValue.key]: formValue.value });
|
||||
if (formValue.disabled) this.form.get(formValue.key).disable();
|
||||
});
|
||||
this.initialFormValue = this.form.getRawValue();
|
||||
}
|
||||
|
||||
async #closeDialogAndRedirectToDossier() {
|
||||
this._editDossierDialogRef.close();
|
||||
await this._router.navigate([this.dossier.dossiersListRouterLink]);
|
||||
await this._router.navigate([this.dossier().dossiersListRouterLink]);
|
||||
this._toaster.success(_('edit-dossier-dialog.delete-successful'), {
|
||||
params: {
|
||||
dossierName: this.dossier.dossierName,
|
||||
dossierName: this.dossier().dossierName,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
#getForm(): UntypedFormGroup {
|
||||
const formFieldWithArchivedCheck = value => ({ value, disabled: !this.dossier.isActive });
|
||||
return this._formBuilder.group({
|
||||
dossierName: [formFieldWithArchivedCheck(this.dossier.dossierName), Validators.required],
|
||||
dossierTemplateId: [
|
||||
{
|
||||
value: this.dossier.dossierTemplateId,
|
||||
disabled: this._dossierStatsService.get(this.dossier.id).hasFiles || !this.dossier.isActive,
|
||||
},
|
||||
Validators.required,
|
||||
],
|
||||
dossierStatusId: [
|
||||
{
|
||||
value: this.dossier.dossierStatusId,
|
||||
disabled: this.states.length === 1 || !this.dossier.isActive,
|
||||
},
|
||||
],
|
||||
description: [formFieldWithArchivedCheck(this.dossier.description)],
|
||||
dueDate: [formFieldWithArchivedCheck(this.dossier.dueDate)],
|
||||
});
|
||||
}
|
||||
|
||||
#filterInvalidDossierTemplates() {
|
||||
const dossier = untracked(this.dossier);
|
||||
this.dossierTemplates = this._dossierTemplatesService.all.filter(r => {
|
||||
if (this.dossier?.dossierTemplateId === r.dossierTemplateId) {
|
||||
if (dossier.dossierTemplateId === r.dossierTemplateId) {
|
||||
return true;
|
||||
}
|
||||
const notYetValid = !!r.validFrom && dayjs(r.validFrom).isAfter(dayjs());
|
||||
const notValidAnymore = !!r.validTo && dayjs(r.validTo).add(1, 'd').isBefore(dayjs());
|
||||
this._changeDetectorRef.markForCheck();
|
||||
return !(notYetValid || notValidAnymore) && r.isActive;
|
||||
});
|
||||
}
|
||||
|
||||
#onDossierTemplateChange() {
|
||||
const dossierStateId = untracked(this.dossierStatusIdControl);
|
||||
const dossierTemplateId = untracked(this.dossierTemplateIdControl);
|
||||
if (!!dossierStateId && dossierTemplateId !== this.initialFormValue.dossierTemplateId) {
|
||||
this.form.controls.dossierStatusId.setValue(null);
|
||||
}
|
||||
const dossier = untracked(this.dossier);
|
||||
if (dossierTemplateId === this.initialFormValue.dossierTemplateId) {
|
||||
this.form.controls.dossierStatusId.setValue(dossier.dossierStatusId);
|
||||
}
|
||||
const states = untracked(this.states);
|
||||
if (isJustOne(states) || !dossier.isActive) {
|
||||
this.form.controls.dossierStatusId.disable();
|
||||
} else {
|
||||
this.form.controls.dossierStatusId.enable();
|
||||
}
|
||||
|
||||
this._changeDetectorRef.markForCheck();
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,6 +99,8 @@
|
||||
.error-message {
|
||||
margin-top: 2px;
|
||||
color: var(--iqser-primary);
|
||||
white-space: normal;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -45,6 +45,13 @@ export class DossierTemplatesService extends EntitiesService<IDossierTemplate, D
|
||||
);
|
||||
}
|
||||
|
||||
loadOnlyDossierTemplates(): Observable<DossierTemplate[]> {
|
||||
return this.getAll().pipe(
|
||||
mapEach(entity => new DossierTemplate(entity)),
|
||||
tap(templates => this.setEntities(templates)),
|
||||
);
|
||||
}
|
||||
|
||||
loadDossierTemplate(dossierTemplateId: string) {
|
||||
return this._getOne([dossierTemplateId], this._defaultModelPath).pipe(
|
||||
map(entity => new DossierTemplate(entity)),
|
||||
|
||||
@ -28,6 +28,7 @@ export class ComponentMappingsService extends EntitiesService<IComponentMapping,
|
||||
{ key: 'name', value: componentMapping.name },
|
||||
{ key: 'encoding', value: componentMapping.encoding },
|
||||
{ key: 'delimiter', value: componentMapping.delimiter },
|
||||
{ key: 'quoteChar', value: componentMapping.quoteChar },
|
||||
];
|
||||
|
||||
if (componentMapping.id) {
|
||||
|
||||
@ -152,8 +152,9 @@ export class DictionaryService extends EntitiesService<IDictionary, Dictionary>
|
||||
.filter(d => d.model['typeId'] && (d.hasDictionary || d.addToDictionaryAction));
|
||||
}
|
||||
|
||||
getRedactTextDictionaries(dossierId: string, dossierDictionaryOnly: boolean): Dictionary[] {
|
||||
return this.#extractDossierLevelTypes(dossierId)
|
||||
getRedactTextDictionaries(dossierId: string, dossierDictionaryOnly: boolean, dossierTemplateId: string): Dictionary[] {
|
||||
const types = dossierDictionaryOnly ? this.#extractDossierLevelTypes(dossierId) : this.getDictionariesOptions(dossierTemplateId);
|
||||
return types
|
||||
.filter(d => d.model['typeId'] && !d.hint && d.addToDictionaryAction && (dossierDictionaryOnly || !d.dossierDictionaryOnly))
|
||||
.sort((a, b) => a.label.localeCompare(b.label));
|
||||
}
|
||||
|
||||
@ -4,7 +4,6 @@ import { ProcessingFileStatus, WorkflowFileStatus } from '@red/domain';
|
||||
export const workflowFileStatusTranslations: { [key in WorkflowFileStatus]: string } = {
|
||||
APPROVED: _('file-status.approved'),
|
||||
NEW: _('file-status.new'),
|
||||
UNASSIGNED: _('file-status.unassigned'),
|
||||
UNDER_APPROVAL: _('file-status.under-approval'),
|
||||
UNDER_REVIEW: _('file-status.under-review'),
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"ADMIN_CONTACT_NAME": null,
|
||||
"ADMIN_CONTACT_URL": null,
|
||||
"API_URL": "https://dan2.iqser.cloud",
|
||||
"API_URL": "https://dan1.iqser.cloud",
|
||||
"APP_NAME": "RedactManager",
|
||||
"IS_DOCUMINE": false,
|
||||
"RULE_EDITOR_DEV_ONLY": false,
|
||||
@ -13,7 +13,7 @@
|
||||
"MAX_RETRIES_ON_SERVER_ERROR": 3,
|
||||
"OAUTH_CLIENT_ID": "redaction",
|
||||
"OAUTH_IDP_HINT": null,
|
||||
"OAUTH_URL": "https://dan2.iqser.cloud/auth",
|
||||
"OAUTH_URL": "https://dan1.iqser.cloud/auth",
|
||||
"RECENT_PERIOD_IN_HOURS": 24,
|
||||
"SELECTION_MODE": "structural",
|
||||
"MANUAL_BASE_URL": "https://docs.redactmanager.com/preview",
|
||||
|
||||
@ -108,13 +108,12 @@
|
||||
"file": "Mapping-Datei",
|
||||
"name": "Mapping-Name",
|
||||
"name-placeholder": "Mapping-Name",
|
||||
"quote-char": "Anführungszeichen",
|
||||
"quote-char-placeholder": "\"",
|
||||
"version": "Version"
|
||||
}
|
||||
},
|
||||
"add-edit-dossier-attribute": {
|
||||
"error": {
|
||||
"generic": "Speichern des Attributs fehlgeschlagen."
|
||||
},
|
||||
"form": {
|
||||
"label": "Name des Attributs",
|
||||
"label-placeholder": "Namen eingeben",
|
||||
@ -138,6 +137,9 @@
|
||||
},
|
||||
"add-edit-entity": {
|
||||
"form": {
|
||||
"ai-creation-enabled": "KI-Erstellung aktivieren",
|
||||
"ai-description": "KI-Beschreibung",
|
||||
"ai-description-placeholder": "KI-Beschreibung eingeben",
|
||||
"case-sensitive": "Groß-/Kleinschreibung beachten",
|
||||
"color": "Farbe {type, select, redaction{Schwärzung} hint{Hinweis} recommendation{Empfehlung} skipped{Ingorierte Schwärzung} ignored{Ignorierter Hinweis} other{}}",
|
||||
"color-placeholder": "#",
|
||||
@ -202,10 +204,6 @@
|
||||
"save": "Benutzer speichern",
|
||||
"save-changes": "Änderungen speichern"
|
||||
},
|
||||
"error": {
|
||||
"email-already-used": "Diese E-Mail-Adresse ist bereits mit einem anderen Benutzer verknüpft.",
|
||||
"generic": "Speichern des Benutzers fehlgeschlagen."
|
||||
},
|
||||
"form": {
|
||||
"account-setup": "Konfiguration des Benutzerkontos",
|
||||
"email": "E-Mail",
|
||||
@ -709,7 +707,7 @@
|
||||
"new-dossier": "Neues Dossier"
|
||||
},
|
||||
"greeting": {
|
||||
"subtitle": "Hier findest du deine Dossier-Vorlagen im Überblick.",
|
||||
"subtitle": "Hier finden Sie Ihre Dossier-Vorlagen im Überblick.",
|
||||
"title": "Wilkommen, {name}!"
|
||||
}
|
||||
},
|
||||
@ -775,7 +773,7 @@
|
||||
"revert-changes": "Zurücksetzen",
|
||||
"save-changes": "Änderungen speichern",
|
||||
"search": "Suche...",
|
||||
"select-dictionary": "Wählen Sie oben ein Wörterbuch für den Vergleich aus.",
|
||||
"select-dictionary": "Wählen Sie aus dem Drop-down oben ein Wörterbuch für den Vergleich aus.",
|
||||
"success": {
|
||||
"generic": "Wörterbuch wurde aktualisiert"
|
||||
}
|
||||
@ -928,6 +926,9 @@
|
||||
"reanalyse": {
|
||||
"action": "Ganzes Dossier analysieren"
|
||||
},
|
||||
"rules": {
|
||||
"timeoutError": "Regeln für Dossier-Vorlagen gesperrt!"
|
||||
},
|
||||
"stats": {
|
||||
"analyzed-pages": "{count, plural, one{Seite} other{Seiten}}",
|
||||
"total-people": "Benutzer"
|
||||
@ -942,7 +943,8 @@
|
||||
},
|
||||
"table-header": {
|
||||
"title": "{length} {length, plural, one{aktives Dossier} other{aktive Dossiers}}"
|
||||
}
|
||||
},
|
||||
"template-inactive": "Aktuell ausgewählte Dossier-Vorlage inaktiv!"
|
||||
},
|
||||
"dossier-overview": {
|
||||
"approve": "Freigeben",
|
||||
@ -1165,15 +1167,15 @@
|
||||
"queued": "Ihr Download wurde zur Warteschlange hinzugefügt.<br><br>Hier finden Sie Ihre generierten Downloads: <a href=\"{downloadHref}\">Meine Downloads<a/>."
|
||||
},
|
||||
"download-type": {
|
||||
"annotated": "Annotierte PDF",
|
||||
"annotated": "Annotiertes PDF",
|
||||
"delta-preview": "Delta-PDF",
|
||||
"flatten": "Verflachte PDF",
|
||||
"flatten": "Verflachtes PDF",
|
||||
"label": "{length} Dokumenten{length, plural, one{typ} other{typen}}",
|
||||
"optimized-preview": "Optimierte Vorschau-PDF",
|
||||
"original": "Optimierte PDF",
|
||||
"optimized-preview": "Optimiertes Vorschau-PDF",
|
||||
"original": "Optimiertes PDF",
|
||||
"preview": "Vorschau-PDF",
|
||||
"redacted": "Geschwärzte PDF",
|
||||
"redacted-only": "Geschwärzte PDF (nur freigegebene Dateien)"
|
||||
"redacted": "Geschwärztes PDF",
|
||||
"redacted-only": "Geschwärztes PDF (nur freigegebene Dateien)"
|
||||
},
|
||||
"downloads-list": {
|
||||
"actions": {
|
||||
@ -1236,9 +1238,9 @@
|
||||
"title": "{label} bearbeiten"
|
||||
},
|
||||
"entries-count": "{count} {count, plural, one{Eintrag} other{Einträge}}",
|
||||
"false-positives": "Falsch-Positive",
|
||||
"false-recommendations": "Falsche Empfehlungen",
|
||||
"to-redact": "Schwärzungen"
|
||||
"false-positives": "Falsch-Positive ({count})",
|
||||
"false-recommendations": "Falsche Empfehlungen ({count})",
|
||||
"to-redact": "Einträge ({count})"
|
||||
},
|
||||
"general-info": {
|
||||
"form": {
|
||||
@ -1250,7 +1252,7 @@
|
||||
"label": "Dossier-Status",
|
||||
"no-state-placeholder": "Für dieses Dossier ist noch kein Status festgelegt"
|
||||
},
|
||||
"due-date": "Enddatum",
|
||||
"due-date": "Termin",
|
||||
"name": {
|
||||
"label": "Dossier-Name",
|
||||
"placeholder": "Namen eingeben"
|
||||
@ -1262,7 +1264,7 @@
|
||||
"missing-owner": "Bearbeiten des Dossiers nicht möglich: Kein Besitzer zugewiesen.",
|
||||
"nav-items": {
|
||||
"choose-download": "Stellen Sie Ihr Download-Paket zusammen:",
|
||||
"dictionary": "Wörterbücher",
|
||||
"dictionary": "Dossier-Einträge",
|
||||
"dossier-attributes": "Dossier-Attribute",
|
||||
"dossier-dictionary": "Dossier-Einträge",
|
||||
"dossier-info": "Dossier-Info",
|
||||
@ -1273,6 +1275,25 @@
|
||||
},
|
||||
"side-nav-title": "Konfiguration"
|
||||
},
|
||||
"edit-rectangle": {
|
||||
"dialog": {
|
||||
"content": {
|
||||
"options": {
|
||||
"multiple-pages": {
|
||||
"description": "Bearbeiten Sie die Schwärzung auf einer Reihe von Seiten",
|
||||
"extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.",
|
||||
"extraOptionLabel": "Seiten",
|
||||
"extraOptionPlaceholder": "z. B. 1-20,22,32",
|
||||
"label": "Auf mehreren Seiten ändern"
|
||||
},
|
||||
"only-this-page": {
|
||||
"description": "Schwärzung nur an dieser Position in diesem Dokument bearbeiten",
|
||||
"label": "Nur auf dieser Seite ändern"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"edit-redaction": {
|
||||
"dialog": {
|
||||
"actions": {
|
||||
@ -1290,7 +1311,7 @@
|
||||
},
|
||||
"only-here": {
|
||||
"description": "Bearbeiten Sie die Schwärzung nur an dieser Stelle im Dokument.",
|
||||
"label": "Typ nur hier ändern"
|
||||
"label": "Nur hier ändern"
|
||||
}
|
||||
},
|
||||
"reason": "Grund",
|
||||
@ -1374,8 +1395,8 @@
|
||||
"generic": "Aktion fehlgeschlagen. Fehlercode: {status}"
|
||||
},
|
||||
"missing-types": "<strong>Dossier-Vorlage unvollständig:</strong> Fehlende Typen ({missingTypes}) können zu Anzeigefehlern führen.",
|
||||
"offline": "Du bist offline",
|
||||
"online": "Du bist online",
|
||||
"offline": "Sie sind offline",
|
||||
"online": "Sie sind online",
|
||||
"reload": "Neu laden",
|
||||
"title": "Ein Fehler ist aufgetreten."
|
||||
},
|
||||
@ -1546,8 +1567,8 @@
|
||||
"select-all": "Alle",
|
||||
"select-none": "Keine",
|
||||
"show-skipped": "Ignorierte im Dokument anzeigen",
|
||||
"the-filters": "Filter",
|
||||
"wrong-filters": "Keine Annotationen für die ausgewählte Filterkombination. Bitte ändern Sie die Auswahl oder setzen die Filter zurück."
|
||||
"the-filters": ".",
|
||||
"wrong-filters": "Keine Annotationen für die ausgewählte Filterkombination. Bitte ändern Sie die Auswahl oder"
|
||||
},
|
||||
"document-info": {
|
||||
"close": "Datei-Info schließen",
|
||||
@ -1604,7 +1625,6 @@
|
||||
"re-processing": "Erneute Verarbeitung läuft...",
|
||||
"reprocess": "Wird verarbeitet",
|
||||
"table-parsing-analyzing": "Table Parsing",
|
||||
"unassigned": "Nicht zugewiesen",
|
||||
"under-approval": "In Freigabe",
|
||||
"under-review": "In Überprüfung",
|
||||
"unprocessed": "Unverarbeitet"
|
||||
@ -1676,7 +1696,6 @@
|
||||
"form": {
|
||||
"forgot-password": "„Passwort vergessen?“-Link auf Login-Seite anzeigen"
|
||||
},
|
||||
"subtitle": "",
|
||||
"title": "Allgemeine Einstellungen"
|
||||
},
|
||||
"subtitle": "SMTP (Simple Mail Transfer Protocol) ermöglicht es Ihnen, Ihre E-Mails über die angegebenen Servereinstellungen zu versenden.",
|
||||
@ -1775,8 +1794,8 @@
|
||||
},
|
||||
"import-only-for-pages": "Nur für diese Seiten importieren",
|
||||
"range": {
|
||||
"label": "Minus (-) für Spanne und Komma (,) für Aufzählung.",
|
||||
"placeholder": "Beispiel: 1-20,22,32"
|
||||
"label": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.",
|
||||
"placeholder": "z. B. 1-20,22,32"
|
||||
},
|
||||
"title": "Dokument mit Schwärzungen importieren"
|
||||
},
|
||||
@ -1865,20 +1884,25 @@
|
||||
"save": "Speichern"
|
||||
},
|
||||
"content": {
|
||||
"apply-on-multiple-pages": "Auf mehreren Seiten anwenden",
|
||||
"apply-on-multiple-pages-hint": "Minus (-) für Bereich und Komma (,) für Aufzählung.",
|
||||
"apply-on-multiple-pages-placeholder": "z. B. 1-20,22,32",
|
||||
"classification": "Wert / Klassifizierung",
|
||||
"comment": "Kommentar",
|
||||
"dictionary": "Wörterbuch",
|
||||
"edit-selected-text": "Ausgewählten Text bearbeiten",
|
||||
"legalBasis": "Rechtsgrundlage",
|
||||
"options": {
|
||||
"multiple-pages": {
|
||||
"description": "Fügen Sie die Schwärzung auf einer Reihe von Seiten hinzu",
|
||||
"extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.",
|
||||
"extraOptionLabel": "Seiten",
|
||||
"extraOptionPlaceholder": "z. B. 1-20,22,32",
|
||||
"label": "Auf mehreren Seiten anwenden"
|
||||
},
|
||||
"only-this-page": {
|
||||
"description": "Schwärzung nur an dieser Position in diesem Dokument hinzufügen",
|
||||
"label": "Auf dieser Seite anwenden"
|
||||
}
|
||||
},
|
||||
"reason": "Grund",
|
||||
"reason-placeholder": "Grund auswählen...",
|
||||
"rectangle": "Bereich schwärzen",
|
||||
"section": "Absatz / Textstelle",
|
||||
"text": "Ausgewählter Text:",
|
||||
"type": "Entität"
|
||||
"section": "Absatz / Textstelle"
|
||||
},
|
||||
"error": "Fehler: Ungültige Seitenauswahl",
|
||||
"header": {
|
||||
@ -1897,7 +1921,7 @@
|
||||
"notification": {
|
||||
"assign-approver": "Sie wurden einem Dokument als Genehmiger zugewiesen. <br>Dokument: <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> <br>Dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>",
|
||||
"assign-reviewer": "Sie wurden einem Dokument als Prüfer zugewiesen. <br>Dokument: <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> <br>Dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>",
|
||||
"document-approved": "<b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> wurde genehmigt!",
|
||||
"document-approved": "<b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> wurde genehmigt.",
|
||||
"dossier-deleted": "Dossier: <b>{dossierName}</b> wurde gelöscht!",
|
||||
"dossier-owner-deleted": "Der Besitzer des Dossiers wurde gelöscht: <b>{dossierName}</b>",
|
||||
"dossier-owner-removed": "Der Dossier-Besitzer von <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> wurde entfernt.",
|
||||
@ -1906,9 +1930,9 @@
|
||||
"no-data": "Sie haben aktuell keine Benachrichtigungen.",
|
||||
"unassigned-from-file": "Sie wurden von einem Dokument entfernt. <br>Dokument: <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> <br>Dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>",
|
||||
"user-becomes-dossier-member": "Sie wurden zu einem Dossier hinzugefügt: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>",
|
||||
"user-demoted-to-reviewer": "<b>{user}</b> wurde im Dossier <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> auf die Prüfer-Berechtigung heruntergestuft!",
|
||||
"user-promoted-to-approver": "<b>{user}</b> wurde im Dossier <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> zum Genehmiger ernannt!",
|
||||
"user-removed-as-dossier-member": "<b>{user}</b> wurde als Mitglied von: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> entfernt!"
|
||||
"user-demoted-to-reviewer": "Sie wurden auf die Reviewer-Rolle heruntergestuft: \n<b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>",
|
||||
"user-promoted-to-approver": "Sie wurden zum Genehmiger in einem Dossier ernannt: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>",
|
||||
"user-removed-as-dossier-member": "Sie wurden als Dossier-Mitglied entfernt: \n<b>{dossierHref, select, null{{dossierName}} other\n{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>\n"
|
||||
},
|
||||
"notifications": {
|
||||
"button-text": "Benachrichtigungen",
|
||||
@ -2155,6 +2179,25 @@
|
||||
"title": "{count, plural, one{Annotation} other {Annotationen}} entfernen"
|
||||
}
|
||||
},
|
||||
"remove-rectangle": {
|
||||
"dialog": {
|
||||
"content": {
|
||||
"options": {
|
||||
"multiple-pages": {
|
||||
"description": "Entfernen Sie die Schwärzung auf einer Reihe von Seiten",
|
||||
"extraOptionDescription": "Minus (-) für Seitenbereich und Komma (,) für Aufzählung.",
|
||||
"extraOptionLabel": "Seiten",
|
||||
"extraOptionPlaceholder": "z. B. 1-20,22,32",
|
||||
"label": "Auf mehreren Seiten entfernen"
|
||||
},
|
||||
"only-this-page": {
|
||||
"description": "Schwärzung nur an dieser Stelle in diesem Dokument entfernen",
|
||||
"label": "Nur auf dieser Seite entfernen"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"remove-redaction": {
|
||||
"dialog": {
|
||||
"actions": {
|
||||
@ -2179,7 +2222,7 @@
|
||||
"label": "In diesem Kontext aus Dossier entfernen"
|
||||
},
|
||||
"in-document": {
|
||||
"description": "{isImage, select, image{Das Bild} other{der Begriff}} wird auf keiner Seite dieses Dokuments automatisch geschwärzt.",
|
||||
"description": "{isImage, select, image{Das Bild} other{Der Begriff}} wird auf keiner Seite dieses Dokuments automatisch geschwärzt.",
|
||||
"label": "Aus Dokument entfernen"
|
||||
},
|
||||
"in-dossier": {
|
||||
@ -2316,13 +2359,13 @@
|
||||
},
|
||||
"roles": {
|
||||
"inactive": "Inaktiv",
|
||||
"manager-admin": "Manager & {length, plural, one{Admin} other{Admins}}",
|
||||
"manager-admin": "Manager & Admin",
|
||||
"no-role": "Keine Rolle definiert",
|
||||
"red-admin": "{length, plural, one{Anwendungsadmin} other{Anwendungsadmins}}",
|
||||
"red-admin": "Anwendungsadmin",
|
||||
"red-manager": "Manager",
|
||||
"red-user": "Benutzer",
|
||||
"red-user-admin": "{length, plural, one{Benutzeradmin} other{Benutzeradmins}}",
|
||||
"regular": "{length, plural, one{regulärer} other{reguläre}} Benutzer"
|
||||
"red-user-admin": "Benutzeradmin",
|
||||
"regular": "regulärer Benutzer"
|
||||
},
|
||||
"search": {
|
||||
"active-dossiers": "Dokumente in aktiven Dossiers",
|
||||
@ -2439,7 +2482,7 @@
|
||||
"time-to-restore": "Verbleibende Zeit für Wiederherstellung"
|
||||
},
|
||||
"table-header": {
|
||||
"title": "{length} {length, plural, one{gelöschtes Dossier} other{gelöschte Dossiers}}"
|
||||
"title": "{length} {length, plural, one{gelöschtes Element} other{gelöschte Elemente}}"
|
||||
}
|
||||
},
|
||||
"type": "Typ",
|
||||
@ -2597,7 +2640,7 @@
|
||||
"table-header": {
|
||||
"title": "Wasserzeichen"
|
||||
},
|
||||
"watermark-is-used": "Dieses Wasserzeichen wird bereits verwendet. Möchten Sie es dennocht löschen?"
|
||||
"watermark-is-used": "Dieses Wasserzeichen wird bereits verwendet. Möchten Sie es dennoch löschen?"
|
||||
},
|
||||
"workflow": {
|
||||
"selection": {
|
||||
|
||||
@ -108,6 +108,8 @@
|
||||
"file": "Mapping file",
|
||||
"name": "Mapping name",
|
||||
"name-placeholder": "Mapping name",
|
||||
"quote-char": "Quotation marker",
|
||||
"quote-char-placeholder": "\"",
|
||||
"version": "Version"
|
||||
}
|
||||
},
|
||||
@ -202,10 +204,6 @@
|
||||
"save": "Save user",
|
||||
"save-changes": "Save changes"
|
||||
},
|
||||
"error": {
|
||||
"email-already-used": "This e-mail address is already associated with another user.",
|
||||
"generic": "Failed to save user."
|
||||
},
|
||||
"form": {
|
||||
"account-setup": "User account setup",
|
||||
"email": "E-mail",
|
||||
@ -775,7 +773,7 @@
|
||||
"revert-changes": "Revert",
|
||||
"save-changes": "Save changes",
|
||||
"search": "Search entries...",
|
||||
"select-dictionary": "Select a dictionary for comparison above.",
|
||||
"select-dictionary": "Select a dictionary for comparison from the drop-down.",
|
||||
"success": {
|
||||
"generic": "Dictionary updated"
|
||||
}
|
||||
@ -928,6 +926,9 @@
|
||||
"reanalyse": {
|
||||
"action": "Analyze entire dossier"
|
||||
},
|
||||
"rules": {
|
||||
"timeoutError": "Dossier template rules locked!"
|
||||
},
|
||||
"stats": {
|
||||
"analyzed-pages": "{count, plural, one{Page} other{Pages}}",
|
||||
"total-people": "Total users"
|
||||
@ -942,7 +943,8 @@
|
||||
},
|
||||
"table-header": {
|
||||
"title": "{length} active {length, plural, one{dossier} other{dossiers}}"
|
||||
}
|
||||
},
|
||||
"template-inactive": "Currently selected dossier template inactive!"
|
||||
},
|
||||
"dossier-overview": {
|
||||
"approve": "Approve",
|
||||
@ -1060,7 +1062,7 @@
|
||||
"dossier-states": "{count, plural, one{Dossier state} other{Dossier states}}"
|
||||
},
|
||||
"error": {
|
||||
"conflict": "Dossier state with this name already exists"
|
||||
"conflict": "Dossier state with this name already exists."
|
||||
},
|
||||
"no-data": {
|
||||
"title": "There are no dossier states."
|
||||
@ -1236,9 +1238,9 @@
|
||||
"title": "Edit {label}"
|
||||
},
|
||||
"entries-count": "{count} {count, plural, one{entry} other{entries}}",
|
||||
"false-positives": "False positives",
|
||||
"false-recommendations": "False recommendations",
|
||||
"to-redact": "To redact"
|
||||
"false-positives": "False positives ({count})",
|
||||
"false-recommendations": "False recommendations ({count})",
|
||||
"to-redact": "Entries ({count})"
|
||||
},
|
||||
"general-info": {
|
||||
"form": {
|
||||
@ -1262,7 +1264,7 @@
|
||||
"missing-owner": "Editing the dossier not possible: No owner assigned.",
|
||||
"nav-items": {
|
||||
"choose-download": "Select the documents for your download:",
|
||||
"dictionary": "Dictionaries",
|
||||
"dictionary": "Dossier entries",
|
||||
"dossier-attributes": "Dossier attributes",
|
||||
"dossier-dictionary": "Dossier entries",
|
||||
"dossier-info": "Dossier info",
|
||||
@ -1278,11 +1280,11 @@
|
||||
"content": {
|
||||
"options": {
|
||||
"multiple-pages": {
|
||||
"description": "Edit redaction on following range of pages",
|
||||
"description": "Edit redaction on a range of pages",
|
||||
"extraOptionDescription": "Minus(-) for range and comma(,) for enumeration",
|
||||
"extraOptionLabel": "Range",
|
||||
"extraOptionLabel": "Pages",
|
||||
"extraOptionPlaceholder": "e.g. 1-20,22,32",
|
||||
"label": "Change on all pages"
|
||||
"label": "Change on multiple pages"
|
||||
},
|
||||
"only-this-page": {
|
||||
"description": "Edit redaction only at this position in this document",
|
||||
@ -1460,7 +1462,7 @@
|
||||
"save": {
|
||||
"error": "Failed to create file attributes.",
|
||||
"label": "Save attributes",
|
||||
"success": "{count} file {count, plural, one{attribute} other{attributes}} created successfully!"
|
||||
"success": "{count} file {count, plural, one{attribute} other{attributes}} created successfully."
|
||||
},
|
||||
"search": {
|
||||
"placeholder": "Search by column name..."
|
||||
@ -1566,7 +1568,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 or reset the filters"
|
||||
"wrong-filters": "No annotations for the selected filter combination. Please adjust or"
|
||||
},
|
||||
"document-info": {
|
||||
"close": "Close document info",
|
||||
@ -1623,7 +1625,6 @@
|
||||
"re-processing": "Reprocessing...",
|
||||
"reprocess": "Processing",
|
||||
"table-parsing-analyzing": "Table parsing",
|
||||
"unassigned": "Unassigned",
|
||||
"under-approval": "Under approval",
|
||||
"under-review": "Under review",
|
||||
"unprocessed": "Unprocessed"
|
||||
@ -1695,7 +1696,6 @@
|
||||
"form": {
|
||||
"forgot-password": "Show 'Forgot password' link on login screen"
|
||||
},
|
||||
"subtitle": " ",
|
||||
"title": "General configurations"
|
||||
},
|
||||
"subtitle": "SMTP (Simple Mail Transfer Protocol) enables you to send your e-mails through the specified server settings.",
|
||||
@ -1773,7 +1773,7 @@
|
||||
"save": "Remove Earmarks",
|
||||
"title": "Remove earmarks"
|
||||
},
|
||||
"success": "{operation, select, convert{Converting earmarks in progress...} delete{Successfully removed earmarks!} other{}} "
|
||||
"success": "{operation, select, convert{Converting earmarks in progress...} delete{Successfully removed earmarks.} other{}} "
|
||||
},
|
||||
"highlights": "{color} - {length} {length, plural, one{earmark} other{earmarks}}",
|
||||
"image-category": {
|
||||
@ -1889,9 +1889,9 @@
|
||||
"legalBasis": "Legal basis",
|
||||
"options": {
|
||||
"multiple-pages": {
|
||||
"description": "Add redaction on following range of pages",
|
||||
"description": "Add redaction on a range of pages",
|
||||
"extraOptionDescription": "Minus(-) for range and comma(,) for enumeration",
|
||||
"extraOptionLabel": "Range",
|
||||
"extraOptionLabel": "Pages",
|
||||
"extraOptionPlaceholder": "e.g. 1-20,22,32",
|
||||
"label": "Apply on multiple pages"
|
||||
},
|
||||
@ -1921,18 +1921,18 @@
|
||||
"notification": {
|
||||
"assign-approver": "You have been assigned as approver for a document. <br>Document: <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> <br>Dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>",
|
||||
"assign-reviewer": "You have been assigned as reviewer for a document. <br>Document: <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> <br>Dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>",
|
||||
"document-approved": " <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> has been approved!",
|
||||
"dossier-deleted": "Dossier: <b>{dossierName}</b> has been deleted!",
|
||||
"dossier-owner-deleted": "The owner of dossier: <b>{dossierName}</b> has been deleted!",
|
||||
"dossier-owner-removed": "You have been removed as dossier owner from <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
|
||||
"document-approved": " <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> has been approved.",
|
||||
"dossier-deleted": "Dossier has been deleted: <b>{dossierName}</b>",
|
||||
"dossier-owner-deleted": "The dossier owner has been deleted: <b>{dossierName}</b>",
|
||||
"dossier-owner-removed": "You have been removed as dossier owner: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>\n\n",
|
||||
"dossier-owner-set": "You are now the dossier owner of <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
|
||||
"download-ready": "Your <b><a href=\"{downloadHref}\", target=\"_self\">download</a></b> is ready!",
|
||||
"no-data": "You currently have no notifications.",
|
||||
"unassigned-from-file": "You have been unassigned from a document. <br>Document: <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> <br>Dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>",
|
||||
"user-becomes-dossier-member": "You have been added to a dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>",
|
||||
"user-demoted-to-reviewer": "You have been demoted to reviewer in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>",
|
||||
"user-promoted-to-approver": "You have been promoted to approver in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
|
||||
"user-removed-as-dossier-member": "You have been removed as a member from dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!"
|
||||
"user-promoted-to-approver": "You have been promoted to approver in a dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>",
|
||||
"user-removed-as-dossier-member": "You have been removed as a member from a dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>"
|
||||
},
|
||||
"notifications-screen": {
|
||||
"category": {
|
||||
@ -2184,11 +2184,11 @@
|
||||
"content": {
|
||||
"options": {
|
||||
"multiple-pages": {
|
||||
"description": "Remove redaction on following range of pages",
|
||||
"description": "Remove redaction on a range of pages",
|
||||
"extraOptionDescription": "Minus(-) for range and comma(,) for enumeration",
|
||||
"extraOptionLabel": "Range",
|
||||
"extraOptionLabel": "Pages",
|
||||
"extraOptionPlaceholder": "e.g. 1-20,22,32",
|
||||
"label": "Remove on all pages"
|
||||
"label": "Remove on multiple pages"
|
||||
},
|
||||
"only-this-page": {
|
||||
"description": "Remove redaction only at this position in this document",
|
||||
@ -2359,12 +2359,12 @@
|
||||
},
|
||||
"roles": {
|
||||
"inactive": "Inactive",
|
||||
"manager-admin": "Manager & {length, plural, one{Admin} other{Admins}}",
|
||||
"manager-admin": "Manager & admin",
|
||||
"no-role": "No role defined",
|
||||
"red-admin": "Application {length, plural, one{admin} other{admins}}",
|
||||
"red-manager": "{length, plural, one{Manager} other{Managers}}",
|
||||
"red-user": "{length, plural, one{User} other{Users}}",
|
||||
"red-user-admin": "{length, plural, one{User} other{Users}} admin",
|
||||
"red-admin": "Application admin",
|
||||
"red-manager": "Manager",
|
||||
"red-user": "User",
|
||||
"red-user-admin": "Users admin",
|
||||
"regular": "Regular"
|
||||
},
|
||||
"search-screen": {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -18,7 +18,7 @@
|
||||
},
|
||||
"content": {
|
||||
"comment": "Comment",
|
||||
"comment-placeholder": "Add remarks or mentions...",
|
||||
"comment-placeholder": "Add remarks or notes...",
|
||||
"selected-text": "Selected text:",
|
||||
"type": "Type",
|
||||
"type-placeholder": "Select type..."
|
||||
@ -100,7 +100,7 @@
|
||||
"dialog": {
|
||||
"title": "{type, select, add{Add new} edit{Edit} other{}} component mapping"
|
||||
},
|
||||
"disabled-file-options": "Re-upload mapping file to change",
|
||||
"disabled-file-options": "Upload updated mapping file",
|
||||
"form": {
|
||||
"delimiter": "CSV delimiter",
|
||||
"delimiter-placeholder": "CSV delimiter",
|
||||
@ -108,6 +108,8 @@
|
||||
"file": "Mapping file (.csv)",
|
||||
"name": "Mapping name",
|
||||
"name-placeholder": "Mapping name",
|
||||
"quote-char": "",
|
||||
"quote-char-placeholder": "",
|
||||
"version": "Version"
|
||||
}
|
||||
},
|
||||
@ -130,7 +132,7 @@
|
||||
"rank": "Rank"
|
||||
},
|
||||
"save": "Save state",
|
||||
"success": "Successfully {type, select, edit{updated} create{created} other{}} the dossier state!",
|
||||
"success": "Successfully {type, select, edit{updated} create{created} other{}} the dossier state.",
|
||||
"title": "{type, select, edit{Edit {name}} create{Create} other{}} dossier state"
|
||||
},
|
||||
"add-edit-entity": {
|
||||
@ -202,10 +204,6 @@
|
||||
"save": "Save user",
|
||||
"save-changes": "Save changes"
|
||||
},
|
||||
"error": {
|
||||
"email-already-used": "This e-mail address is already in use by a different user!",
|
||||
"generic": "Failed to save user."
|
||||
},
|
||||
"form": {
|
||||
"account-setup": "User account setup",
|
||||
"email": "E-mail",
|
||||
@ -230,11 +228,11 @@
|
||||
},
|
||||
"content": {
|
||||
"comment": "Comment",
|
||||
"comment-placeholder": "Add remarks or mentions...",
|
||||
"comment-placeholder": "Add remarks or notes...",
|
||||
"options": {
|
||||
"in-dossier": {
|
||||
"description": "Add hint in every document in {dossierName}.",
|
||||
"extraOptionLabel": "Apply to all dossiers",
|
||||
"extraOptionLabel": "Apply to all active and future dossiers",
|
||||
"label": "Add hint in dossier"
|
||||
},
|
||||
"only-here": {
|
||||
@ -583,13 +581,13 @@
|
||||
},
|
||||
"component-rules-screen": {
|
||||
"error": {
|
||||
"generic": "Something went wrong... Component rules update failed!"
|
||||
"generic": "Something went wrong... Component rules update failed."
|
||||
},
|
||||
"errors-found": "{errors, plural, one{An error} other{{errors} errors}} found in rules",
|
||||
"revert-changes": "Revert",
|
||||
"save-changes": "Save changes",
|
||||
"success": {
|
||||
"generic": "Component rules updated!"
|
||||
"generic": "Component rules updated."
|
||||
},
|
||||
"title": "Component rule editor"
|
||||
},
|
||||
@ -615,7 +613,7 @@
|
||||
"impacted-report": "{reportsCount} reports currently use the placeholder for this attribute. Please update them.",
|
||||
"title": "Delete {count, plural, one{{name}} other{file attributes}}",
|
||||
"toast-error": "Please confirm that you understand the consequences of this action.",
|
||||
"warning": "Warning: This action cannot be undone!"
|
||||
"warning": "Warning: this action cannot be undone!"
|
||||
},
|
||||
"confirm-delete-dossier-state": {
|
||||
"cancel": "Cancel",
|
||||
@ -626,7 +624,7 @@
|
||||
"state-placeholder": "Select another state"
|
||||
},
|
||||
"question": "Select another state to replace the current {count, plural, one{dossier} other{dossier}} state",
|
||||
"success": "Successfully deleted state!",
|
||||
"success": "Successfully deleted state",
|
||||
"title": "Delete dossier state",
|
||||
"warning": "The {name} state is assigned to {count} {count, plural, one{dossier} other{dossiers}}."
|
||||
},
|
||||
@ -637,7 +635,7 @@
|
||||
"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 consequences of this action.",
|
||||
"warning": "Warning: this cannot be undone!"
|
||||
"warning": "Warning: this action cannot be undone!"
|
||||
},
|
||||
"confirmation-dialog": {
|
||||
"approve-file": {
|
||||
@ -777,7 +775,7 @@
|
||||
"search": "Search entries...",
|
||||
"select-dictionary": "Select a dictionary for comparison above.",
|
||||
"success": {
|
||||
"generic": "Dictionary updated!"
|
||||
"generic": "Dictionary updated."
|
||||
}
|
||||
},
|
||||
"digital-signature": "Digital signature",
|
||||
@ -788,7 +786,7 @@
|
||||
"certificate-not-valid-error": "Uploaded certificate is invalid.",
|
||||
"continue": "Continue",
|
||||
"save": "Save configurations",
|
||||
"save-error": "Failed to save digital signature!",
|
||||
"save-error": "Failed to save digital signature.",
|
||||
"save-success": "Digital signature certificate saved successfully"
|
||||
},
|
||||
"forms": {
|
||||
@ -829,10 +827,10 @@
|
||||
"digital-signature-screen": {
|
||||
"action": {
|
||||
"delete-error": "Failed to remove digital signature, please try again.",
|
||||
"delete-success": "Digital signature removed. Files will no longer be signed!",
|
||||
"delete-success": "Digital signature removed. Files will no longer be signed.",
|
||||
"remove": "Remove",
|
||||
"save": "Save changes",
|
||||
"save-error": "Failed to save digital signature!",
|
||||
"save-error": "Failed to save digital signature.",
|
||||
"save-success": "No digital signature certificate available.<br/>Please configure a certificate to sign redacted documents."
|
||||
},
|
||||
"no-data": {
|
||||
@ -928,6 +926,9 @@
|
||||
"reanalyse": {
|
||||
"action": "Analyze entire dossier"
|
||||
},
|
||||
"rules": {
|
||||
"timeoutError": "Dossier template rules locked!"
|
||||
},
|
||||
"stats": {
|
||||
"analyzed-pages": "{count, plural, one{Page} other{Pages}}",
|
||||
"total-people": "Total users"
|
||||
@ -942,7 +943,8 @@
|
||||
},
|
||||
"table-header": {
|
||||
"title": "{length} active {length, plural, one{dossier} other{dossiers}}"
|
||||
}
|
||||
},
|
||||
"template-inactive": "Currently selected dossier template inactive!"
|
||||
},
|
||||
"dossier-overview": {
|
||||
"approve": "Move to 'Done'",
|
||||
@ -981,7 +983,7 @@
|
||||
}
|
||||
},
|
||||
"download-file": "Download",
|
||||
"download-file-disabled": "You need to be approver in the dossier and the {count, plural, one{file needs} other{files need}} to be initially processed in order to download.",
|
||||
"download-file-disabled": "To download, ensure you are an approver in the dossier, and the {count, plural, one{file has undergone} other{files have undergone}} initial processing.",
|
||||
"file-listing": {
|
||||
"file-entry": {
|
||||
"file-error": "Re-processing required",
|
||||
@ -1060,13 +1062,13 @@
|
||||
"dossier-states": "{count, plural, one{Dossier state} other{Dossier states}}"
|
||||
},
|
||||
"error": {
|
||||
"conflict": "Dossier state with this name already exists!"
|
||||
"conflict": "Dossier state with this name already exists."
|
||||
},
|
||||
"no-data": {
|
||||
"title": "There are no dossier states."
|
||||
},
|
||||
"no-match": {
|
||||
"title": "No dossier states match your current filters."
|
||||
"title": "No dossier state matches the currently selected filters."
|
||||
},
|
||||
"search": "Search...",
|
||||
"table-col-names": {
|
||||
@ -1107,8 +1109,8 @@
|
||||
},
|
||||
"entities": "{length} {length, plural, one{entity} other{entities}}",
|
||||
"error": {
|
||||
"conflict": "Cannot delete this dossier template! At least one dossier uses this template!",
|
||||
"generic": "Cannot delete this dossier template!"
|
||||
"conflict": "<strong>Deletion denied:</strong> This dossier template is used by at least one dossier and cannot be deleted.",
|
||||
"generic": "Cannot delete this dossier template."
|
||||
},
|
||||
"no-data": {
|
||||
"title": "There are no dossier templates yet."
|
||||
@ -1141,7 +1143,7 @@
|
||||
"dossier-watermark-selector": {
|
||||
"heading": "Watermarks on documents",
|
||||
"no-watermark": "There is no watermark defined for the dossier template.<br>Contact your app admin to define one.",
|
||||
"preview": "Watermark application on preview documents",
|
||||
"preview": "Watermark on preview documents",
|
||||
"watermark": "Watermark application on documents"
|
||||
},
|
||||
"dossiers-type-switch": {
|
||||
@ -1153,7 +1155,7 @@
|
||||
"save": "Download"
|
||||
},
|
||||
"form": {
|
||||
"redaction-preview-color": "Redaction preview color",
|
||||
"redaction-preview-color": "Preview color",
|
||||
"redaction-preview-color-placeholder": "#000000"
|
||||
},
|
||||
"header": "Download options",
|
||||
@ -1161,8 +1163,8 @@
|
||||
},
|
||||
"download-includes": "Choose what is included at download:",
|
||||
"download-status": {
|
||||
"error": "The download preparation failed, please recheck the selected files and download option settings.",
|
||||
"queued": "Your download has been queued, you can find all your requested downloads here: <a href=\"{downloadHref}\">My downloads<a/>."
|
||||
"error": "<strong>Download generation failed</strong><br><br>Please check the selected files and download option settings.",
|
||||
"queued": "Your download has been added to the queue.<br><br>To see your requested downloads, visit: <a href=\"{downloadHref}\">My downloads<a/>."
|
||||
},
|
||||
"download-type": {
|
||||
"annotated": "Annotated PDF",
|
||||
@ -1236,9 +1238,9 @@
|
||||
"title": ""
|
||||
},
|
||||
"entries-count": "{count} {count, plural, one{entry} other{entries}}",
|
||||
"false-positives": "False positives",
|
||||
"false-recommendations": "False recommendations",
|
||||
"to-redact": "To redact"
|
||||
"false-positives": "False positives ({count})",
|
||||
"false-recommendations": "False recommendations ({count})",
|
||||
"to-redact": "To redact ({count})"
|
||||
},
|
||||
"general-info": {
|
||||
"form": {
|
||||
@ -1259,7 +1261,7 @@
|
||||
}
|
||||
},
|
||||
"header": "Edit {dossierName}",
|
||||
"missing-owner": "You cannot edit the dossier because the owner is missing!",
|
||||
"missing-owner": "Editing the dossier not possible: No owner assigned.",
|
||||
"nav-items": {
|
||||
"choose-download": "Choose what is included at download:",
|
||||
"dictionary": "Dictionary",
|
||||
@ -1300,12 +1302,12 @@
|
||||
},
|
||||
"content": {
|
||||
"comment": "Comment",
|
||||
"comment-placeholder": "Add remarks or mentions...",
|
||||
"comment-placeholder": "Add remarks or notes...",
|
||||
"legal-basis": "",
|
||||
"options": {
|
||||
"in-document": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
"label": "In Dokument ändern"
|
||||
},
|
||||
"only-here": {
|
||||
"description": "",
|
||||
@ -1350,13 +1352,13 @@
|
||||
},
|
||||
"entity-rules-screen": {
|
||||
"error": {
|
||||
"generic": "Something went wrong... Entity rules update failed!"
|
||||
"generic": "Error: Entity rules update failed."
|
||||
},
|
||||
"errors-found": "{errors, plural, one{An error} other{{errors} errors}} found in rules",
|
||||
"revert-changes": "Revert",
|
||||
"save-changes": "Save changes",
|
||||
"success": {
|
||||
"generic": "Entity rules updated!"
|
||||
"generic": "Entity rules updated."
|
||||
},
|
||||
"title": "Entity rule editor",
|
||||
"warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} found in rules"
|
||||
@ -1374,15 +1376,15 @@
|
||||
"deleted-entity": {
|
||||
"dossier": {
|
||||
"action": "Back to overview",
|
||||
"label": "This dossier has been deleted!"
|
||||
"label": "This dossier has been deleted."
|
||||
},
|
||||
"file-dossier": {
|
||||
"action": "Back to overview",
|
||||
"label": "The dossier of this file has been deleted!"
|
||||
"label": "The dossier of this file has been deleted."
|
||||
},
|
||||
"file": {
|
||||
"action": "Back to dossier",
|
||||
"label": "This file has been deleted!"
|
||||
"label": "This file has been deleted."
|
||||
}
|
||||
},
|
||||
"file-preview": {
|
||||
@ -1396,7 +1398,7 @@
|
||||
"offline": "Disconnected",
|
||||
"online": "Reconnected",
|
||||
"reload": "Reload",
|
||||
"title": "Oops! Something went wrong..."
|
||||
"title": "An error ocurred."
|
||||
},
|
||||
"exact-date": "{day} {month} {year} at {hour}:{minute}",
|
||||
"file": "File",
|
||||
@ -1413,7 +1415,7 @@
|
||||
"file-attribute": {
|
||||
"update": {
|
||||
"error": "Update of file attribute value failed. Please try again.",
|
||||
"success": "File attribute value has been updated successfully!"
|
||||
"success": "File attribute value has been updated successfully."
|
||||
}
|
||||
},
|
||||
"file-attributes-configurations": {
|
||||
@ -1427,8 +1429,8 @@
|
||||
"save": "Save configurations",
|
||||
"title": "Configurations",
|
||||
"update": {
|
||||
"error": "Failed to update the configuration!",
|
||||
"success": "Configuration has been updated successfully!"
|
||||
"error": "Failed to update the configuration.",
|
||||
"success": "Configuration has been updated successfully."
|
||||
}
|
||||
},
|
||||
"file-attributes-csv-import": {
|
||||
@ -1458,9 +1460,9 @@
|
||||
"none": "None"
|
||||
},
|
||||
"save": {
|
||||
"error": "Failed to create file attributes!",
|
||||
"error": "Failed to create file attributes.",
|
||||
"label": "Save attributes",
|
||||
"success": "{count} file {count, plural, one{attribute} other{attributes}} created successfully!"
|
||||
"success": "{count} file {count, plural, one{attribute} other{attributes}} created successfully."
|
||||
},
|
||||
"search": {
|
||||
"placeholder": "Search by column name..."
|
||||
@ -1551,7 +1553,7 @@
|
||||
"redacted": "Preview",
|
||||
"redacted-tooltip": "Component preview shows only annotations. Consider this a preview for the final version. This view is only available if the file has no pending changes & doesn't require a reanalysis",
|
||||
"standard": "Standard",
|
||||
"standard-tooltip": "Standard workload view shows all hints, annotations & recommendations. This view allows editing.",
|
||||
"standard-tooltip": "Standard shows all annotation types and allows for editing.",
|
||||
"tabs": {
|
||||
"annotations": {
|
||||
"hide-skipped": "",
|
||||
@ -1623,7 +1625,6 @@
|
||||
"re-processing": "Re-processing...",
|
||||
"reprocess": "Processing",
|
||||
"table-parsing-analyzing": "Table parsing",
|
||||
"unassigned": "Unassigned",
|
||||
"under-approval": "Under approval",
|
||||
"under-review": "In progress",
|
||||
"unprocessed": "Unprocessed"
|
||||
@ -1695,7 +1696,6 @@
|
||||
"form": {
|
||||
"forgot-password": "Show 'Forgot password' link on login screen"
|
||||
},
|
||||
"subtitle": " ",
|
||||
"title": "General configurations"
|
||||
},
|
||||
"subtitle": "SMTP (Simple Mail Transfer Protocol) enables you to send your e-mails through the specified server settings.",
|
||||
@ -1714,7 +1714,7 @@
|
||||
},
|
||||
"test": {
|
||||
"error": "Test e-mail could not be sent. Please double-check the email address.",
|
||||
"success": "Test e-mail was sent successfully!",
|
||||
"success": "Test e-mail was sent successfully.",
|
||||
"warning": "Admin mail address not set. Test email sent to {recipientEmail} instead."
|
||||
},
|
||||
"title": "Configure SMTP Account"
|
||||
@ -1745,7 +1745,7 @@
|
||||
"label": "Convert on all pages"
|
||||
},
|
||||
"this-page": {
|
||||
"description": "The earmarks in the selected HEX color will be converted only on the current page in view.",
|
||||
"description": "The earmarks in the selected HEX color will be converted only on the currently viewed page.",
|
||||
"label": "Convert only on this page"
|
||||
}
|
||||
},
|
||||
@ -1773,7 +1773,7 @@
|
||||
"save": "Remove earmarks",
|
||||
"title": "Remove earmarks"
|
||||
},
|
||||
"success": "{operation, select, convert{Converting earmarks in progress...} delete{Successfully removed earmarks!} other{}} "
|
||||
"success": "{operation, select, convert{Converting earmarks in progress...} delete{Successfully removed earmarks.} other{}} "
|
||||
},
|
||||
"highlights": "{color} - {length} {length, plural, one{earmark} other{earmarks}}",
|
||||
"image-category": {
|
||||
@ -1789,8 +1789,8 @@
|
||||
},
|
||||
"details": "To apply annotations from another document, you first need to upload it.",
|
||||
"http": {
|
||||
"error": "Failed to import components! {error}",
|
||||
"success": "Annotations have been imported!"
|
||||
"error": "Failed to import components: {error}",
|
||||
"success": "Annotations have been imported."
|
||||
},
|
||||
"import-only-for-pages": "Import only for pages",
|
||||
"range": {
|
||||
@ -1874,8 +1874,8 @@
|
||||
}
|
||||
},
|
||||
"license-information": "License Information",
|
||||
"load-all-annotations-success": "All annotations were loaded and are now visible in the document thumbnails",
|
||||
"load-all-annotations-threshold-exceeded": "Caution, document contains more than {threshold} annotations. Drawing all annotations will affect the performance of the app and could even block it. Do you want to proceed?",
|
||||
"load-all-annotations-success": "All annotations were loaded and are now visible in the document thumbnails.",
|
||||
"load-all-annotations-threshold-exceeded": "<strong>Alert:</strong> Document contains more than {threshold} annotations. Drawing all annotations may cause the app to slow down or freeze. Do you still want to continue?",
|
||||
"load-all-annotations-threshold-exceeded-checkbox": "Do not show this warning again",
|
||||
"loading": "Loading",
|
||||
"manual-annotation": {
|
||||
@ -1889,14 +1889,14 @@
|
||||
"legalBasis": "Legal Basis",
|
||||
"options": {
|
||||
"multiple-pages": {
|
||||
"description": "Edit redaction the range of pages",
|
||||
"description": "Edit annotation the range of pages",
|
||||
"extraOptionDescription": "Minus(-) for range and comma(,) for enumeration",
|
||||
"extraOptionLabel": "Range",
|
||||
"extraOptionPlaceholder": "e.g. 1-20,22,32",
|
||||
"label": "Apply on multiple pages"
|
||||
},
|
||||
"only-this-page": {
|
||||
"description": "Edit redaction only at this position in this document",
|
||||
"description": "Edit annotation only at this position in this document",
|
||||
"label": "Apply only on this page"
|
||||
}
|
||||
},
|
||||
@ -1919,20 +1919,20 @@
|
||||
"minutes": "minutes",
|
||||
"no-active-license": "Invalid or corrupt license – Please contact your administrator",
|
||||
"notification": {
|
||||
"assign-approver": "You have been assigned to <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
|
||||
"assign-reviewer": "You have been assigned to <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
|
||||
"document-approved": " <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> has been moved to Done!",
|
||||
"dossier-deleted": "Dossier: <b>{dossierName}</b> has been deleted!",
|
||||
"dossier-owner-deleted": "The owner of dossier: <b>{dossierName}</b> has been deleted!",
|
||||
"dossier-owner-removed": "You have been removed as dossier owner from <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
|
||||
"dossier-owner-set": "You are now the dossier owner of <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
|
||||
"assign-approver": "You have been assigned as approver for a document. <br>Document: <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> <br> Dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>",
|
||||
"assign-reviewer": "You have been assigned as reviewer for a document. <br>Document: <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> <br>\nDossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>",
|
||||
"document-approved": " <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> has been moved to Done.",
|
||||
"dossier-deleted": "Dossier: <b>{dossierName}</b> has been deleted.",
|
||||
"dossier-owner-deleted": "The dossier owner has been deleted: <b>{dossierName}</b>",
|
||||
"dossier-owner-removed": "You have been removed as dossier owner: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>",
|
||||
"dossier-owner-set": "You are now the dossier owner of <b>{dossierHref, select, null{{dossierName}} other\n{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>.",
|
||||
"download-ready": "Your <b><a href=\"{downloadHref}\", target=\"_self\">download</a></b> is ready!",
|
||||
"no-data": "You currently have no notifications",
|
||||
"unassigned-from-file": "You have been unassigned from <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> in dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}}}</b>!",
|
||||
"user-becomes-dossier-member": "You have been added to dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
|
||||
"user-demoted-to-reviewer": "You have been demoted to reviewer in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
|
||||
"user-promoted-to-approver": "You have been promoted to approver in dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!",
|
||||
"user-removed-as-dossier-member": "You have been removed as a member from dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>!"
|
||||
"unassigned-from-file": "You have been unassigned from a document. <br>Document: <b>{fileHref, select, null{{fileName}} other{<a href=\"{fileHref}\" target=\"_blank\">{fileName}</a>}}</b> <br>Dossier: <b>{dossierHref, select, null{{dossierName}} other{{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>\n}}}}</b>",
|
||||
"user-becomes-dossier-member": "You have been added to a dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>",
|
||||
"user-demoted-to-reviewer": "You have been demoted to reviewer in a dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>",
|
||||
"user-promoted-to-approver": "You have been promoted to approver in a dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>",
|
||||
"user-removed-as-dossier-member": "You have been removed as a member from dossier: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b>"
|
||||
},
|
||||
"notifications-screen": {
|
||||
"category": {
|
||||
@ -1940,7 +1940,7 @@
|
||||
"in-app-notifications": "In-app notifications"
|
||||
},
|
||||
"error": {
|
||||
"generic": "Something went wrong... Preferences update failed!"
|
||||
"generic": "Something went wrong... Preferences update failed."
|
||||
},
|
||||
"groups": {
|
||||
"document": "Document related notifications",
|
||||
@ -1982,30 +1982,30 @@
|
||||
"ocr": {
|
||||
"confirmation-dialog": {
|
||||
"cancel": "Cancel",
|
||||
"question": "Manual changes could get lost if OCR makes changes at those positions. Are you sure you want to proceed?",
|
||||
"question": "Manual changes may be overwritten if the OCR makes changes at the respective positions. Do you still want to proceed?",
|
||||
"title": "Warning: the file has manual adjustments!"
|
||||
}
|
||||
},
|
||||
"overwrite-files-dialog": {
|
||||
"archive-question": "Dossier is not empty, so files might overlap with the contents of the archive you are uploading. Choose how to proceed in case of duplicates:",
|
||||
"archive-question": "Dossier already contains files. Files might overlap with the contents of the folder you are uploading. Select how to handle duplicates:",
|
||||
"archive-title": "Uploading a ZIP archive",
|
||||
"file-question": "<b>{filename}</b> already exists. Choose how to proceed:",
|
||||
"file-title": "File already exists!",
|
||||
"file-title": "File already exists.",
|
||||
"options": {
|
||||
"all-files": "Apply to all files of current upload",
|
||||
"cancel": "Cancel upload",
|
||||
"current-files": "Apply to current file",
|
||||
"full-overwrite": {
|
||||
"description": "Manual changes done to the existing file will be removed and you are able to start over.",
|
||||
"description": "Remove all manual changes made to the file, and start reviewing a freshly processed file.",
|
||||
"label": "Overwrite and start over"
|
||||
},
|
||||
"partial-overwrite": {
|
||||
"description": "Manual changes are kept only if the affected annotations are still at the same position in the file. Some annotations could be misplaced if the content of the file changed.",
|
||||
"description": "Keep manual changes if the affected redactions remain in their original positions. Some redactions could be misplaced if the content has changed.",
|
||||
"label": "Overwrite and keep manual changes"
|
||||
},
|
||||
"proceed": "Proceed",
|
||||
"skip": {
|
||||
"description": "The upload will be skipped and the existing file will not be replaced.",
|
||||
"description": "Skip the file upload and do not replace the existing file.",
|
||||
"label": "Keep the existing file and do not overwrite"
|
||||
}
|
||||
},
|
||||
@ -2079,14 +2079,14 @@
|
||||
},
|
||||
"form": {
|
||||
"auto-expand-filters-on-action": "Auto expand filters on my actions",
|
||||
"help-mode-dialog": "Help Mode Dialog",
|
||||
"load-all-annotations-warning": "Warning regarding loading all annotations at once in file preview",
|
||||
"help-mode-dialog": "Help mode activation dialog",
|
||||
"load-all-annotations-warning": "Warning regarding simultaneous loading of all annotations in thumbnails",
|
||||
"overwrite-file-option": "Preferred action when re-uploading an already existing file",
|
||||
"table-extraction-type": "Table extraction type"
|
||||
},
|
||||
"label": "Preferences",
|
||||
"title": "Edit preferences",
|
||||
"warnings-description": "Selecting the 'Do not show this message again' checkbox will skip the warning dialog the next time you trigger it.",
|
||||
"warnings-description": "Selecting the 'Do not show this message again' checkbox will skip the dialog the next time you trigger it.",
|
||||
"warnings-label": "Prompts and dialogs",
|
||||
"warnings-subtitle": "Do not show again options"
|
||||
},
|
||||
@ -2110,7 +2110,7 @@
|
||||
},
|
||||
"content": {
|
||||
"comment": "Comment",
|
||||
"comment-placeholder": "Add remarks or mentions...",
|
||||
"comment-placeholder": "Add remarks or notes...",
|
||||
"edit-text": "",
|
||||
"legal-basis": "Legal basis",
|
||||
"options": {
|
||||
@ -2120,7 +2120,7 @@
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Add redaction in every document in {dossierName}.",
|
||||
"extraOptionLabel": "Apply to all dossiers",
|
||||
"extraOptionLabel": "Apply to all active and future dossiers",
|
||||
"label": "Redact in dossier"
|
||||
},
|
||||
"only-here": {
|
||||
@ -2149,27 +2149,27 @@
|
||||
},
|
||||
"content": {
|
||||
"comment": "Comment",
|
||||
"comment-placeholder": "Add remarks or mentions...",
|
||||
"comment-placeholder": "Add remarks or notes...",
|
||||
"list-item": "{text}",
|
||||
"list-item-false-positive": "''{text}'' in the context: ''{context}''",
|
||||
"options": {
|
||||
"false-positive": {
|
||||
"description": "''{value}'' is not a ''{type}'' in this context: ''{context}''.",
|
||||
"description-bulk": "The selected items should not be annotated in their respective contexts.",
|
||||
"label": "False positive"
|
||||
"description": "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 this redaction as a false-positive. The term will not be redacted in this dossier if it occurs in the same context.",
|
||||
"label": "Remove from dossier in this context"
|
||||
},
|
||||
"in-document": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
"label": "Aus Dokument entfernen"
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Do not annotate ''{value}'' as ''{type}'' in any dossier.",
|
||||
"description": "Do not annotate the term in any dossier.",
|
||||
"description-bulk": "Do not annotate the selected terms as their respective types in any dossier.",
|
||||
"label": "No longer annotate as ''{type}''",
|
||||
"label-bulk": "No longer annotate in any dossier"
|
||||
"label-bulk": "Do not annotate as <i>{type}</i>"
|
||||
},
|
||||
"only-here": {
|
||||
"description": "Do not annotate ''{value}'' at this position in the current document.",
|
||||
"description": "Do not annotate the term at this position in this document.",
|
||||
"description-bulk": "Do not annotate the selected terms at this position in the current document.",
|
||||
"label": "Remove here"
|
||||
}
|
||||
@ -2206,35 +2206,35 @@
|
||||
},
|
||||
"content": {
|
||||
"comment": "Comment",
|
||||
"comment-placeholder": "Add remarks or mentions...",
|
||||
"comment-placeholder": "Add remarks or notes...",
|
||||
"options": {
|
||||
"do-not-recommend": {
|
||||
"description": "Do not recommend ''{value}'' as {type} in any document of the current dossier.",
|
||||
"description": "Do not recommend the selected term in any document of this dossier.",
|
||||
"description-bulk": "Do not recommend the selected values as their respective types in any document of the current dossier.",
|
||||
"extraOptionLabel": "Apply to all dossiers",
|
||||
"extraOptionLabel": "Apply to all active and future dossiers",
|
||||
"label": "Remove from dossier"
|
||||
},
|
||||
"false-positive": {
|
||||
"description": "''{value}'' is not a {type} in this context: ''{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": "",
|
||||
"extraOptionDescription": "",
|
||||
"extraOptionLabel": "Apply to all dossiers",
|
||||
"label": "False positive"
|
||||
"extraOptionLabel": "Apply to all active and future dossiers",
|
||||
"label": "Remove from dossier in this context"
|
||||
},
|
||||
"in-document": {
|
||||
"description": "",
|
||||
"label": ""
|
||||
"label": "Aus Dokument entfernen"
|
||||
},
|
||||
"in-dossier": {
|
||||
"description": "Do not {type} \"{value}\" in any document of the current dossier.",
|
||||
"description": "Do not annotate the term in this dossier.",
|
||||
"description-bulk": "",
|
||||
"extraOptionLabel": "Apply to all dossiers",
|
||||
"extraOptionLabel": "Apply to all active and future dossiers",
|
||||
"label": "Remove from dossier",
|
||||
"label-bulk": ""
|
||||
},
|
||||
"only-here": {
|
||||
"description": "Do not {type} ''{value}'' at this position in the current document.",
|
||||
"description-bulk": "",
|
||||
"description": "Do not{type} '{value}'' at this position in the current document.",
|
||||
"description-bulk": "Do not{type} ''{value}'' at this position in the current document.",
|
||||
"label": "Remove here"
|
||||
}
|
||||
}
|
||||
@ -2268,7 +2268,7 @@
|
||||
"display-name": "This placeholder is replaced by the name of the entity the component is based on."
|
||||
},
|
||||
"excerpt": "This placeholder is replaced by a text snippet that contains the component.",
|
||||
"is-skipped": "The skipped redaction placeholder indicates whether a redaction is skipped or not. It can be included in a separate column of a template that also contains the '{{redaction.value'}} placeholder. The placeholder is replaced by “true” if the respective redaction is skipped, and by “false” if it is redacted (i. e., not skipped).",
|
||||
"is-skipped": "The skipped redaction placeholder indicates whether a redaction is skipped or not. It can be included in a separate column of a template that also contains the '\n{{'redaction.value'}}' placeholder. The placeholder is replaced by “true” if the respective redaction is skipped, and by “false” if it is redacted (i. e., not skipped).",
|
||||
"justification": "This placeholder is replaced by the justification of the component. It is a combination of the legal reference (justificationParagraph) and the justification text (justificationReason).",
|
||||
"justification-legal-basis": "This placeholder is replaced by the legal basis for the component.",
|
||||
"justification-paragraph": "This placeholder is replaced by the legal reference of the justification of the component.",
|
||||
@ -2284,7 +2284,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"invalid-upload": "Invalid format selected for Upload! Supported formats are XLSX and DOCX",
|
||||
"invalid-upload": "Invalid upload format selected. Supported formats: XLSX and DOCX",
|
||||
"multi-file-report": "(Multi-file)",
|
||||
"report-documents": "Report documents",
|
||||
"setup": "Click the upload button on the right to upload your component report templates.",
|
||||
@ -2331,7 +2331,7 @@
|
||||
"options": {
|
||||
"in-dossier": {
|
||||
"description": "Resize in every document in {dossierName}.",
|
||||
"extraOptionLabel": "Apply to all dossiers",
|
||||
"extraOptionLabel": "Apply to all active and future dossiers",
|
||||
"label": "Resize in dossier",
|
||||
"tooltip": "Only available for dictionary-based types"
|
||||
},
|
||||
@ -2359,12 +2359,12 @@
|
||||
},
|
||||
"roles": {
|
||||
"inactive": "Inactive",
|
||||
"manager-admin": "Manager & {length, plural, one{Admin} other{Admins}}",
|
||||
"manager-admin": "Manager & admin",
|
||||
"no-role": "No role defined",
|
||||
"red-admin": "Application {length, plural, one{admin} other{admins}}",
|
||||
"red-manager": "{length, plural, one{Manager} other{Managers}}",
|
||||
"red-user": "{length, plural, one{User} other{Users}}",
|
||||
"red-user-admin": "{length, plural, one{User} other{Users}} admin",
|
||||
"red-admin": "Application admin",
|
||||
"red-manager": "Manager",
|
||||
"red-user": "User",
|
||||
"red-user-admin": "Users admin",
|
||||
"regular": "Regular"
|
||||
},
|
||||
"search-screen": {
|
||||
@ -2386,7 +2386,7 @@
|
||||
},
|
||||
"missing": "Missing",
|
||||
"must-contain": "Must contain",
|
||||
"no-data": "Please enter a keyword into the search bar to look for documents or document content.",
|
||||
"no-data": "Enter a keyword into the search bar<br> to look for documents or document content.",
|
||||
"no-match": "The specified search term was not found in any of the documents.",
|
||||
"table-header": "{length} search {length, plural, one{result} other{results}}"
|
||||
},
|
||||
@ -2422,7 +2422,7 @@
|
||||
"sign-in-previous-domain": "Sign in to a previously used workspace",
|
||||
"youre-logged-out": "You have successfully been logged out."
|
||||
},
|
||||
"input-placeholder": "your workspace"
|
||||
"input-placeholder": "Your workspace"
|
||||
},
|
||||
"time": {
|
||||
"days": "{days} {days, plural, one{day} other{days}}",
|
||||
@ -2500,7 +2500,7 @@
|
||||
"overwrite": "Overwrite"
|
||||
},
|
||||
"question": "Choose how you want to proceed:",
|
||||
"title": "The dictionary already has entries!"
|
||||
"title": "The dictionary already has entries."
|
||||
},
|
||||
"upload-file": {
|
||||
"upload-area-text": "Click or drag & drop anywhere on this area..."
|
||||
@ -2515,7 +2515,7 @@
|
||||
},
|
||||
"error": {
|
||||
"file-size": "File too large. Limit is {size}MB.",
|
||||
"file-type": "This file type is not accepted.",
|
||||
"file-type": "This file type is not supported.",
|
||||
"generic": "Failed to upload file. {error}"
|
||||
}
|
||||
},
|
||||
@ -2570,7 +2570,7 @@
|
||||
},
|
||||
"title": "Edit profile",
|
||||
"update": {
|
||||
"success": "Successfully updated profile!"
|
||||
"success": "Successfully updated profile."
|
||||
}
|
||||
},
|
||||
"user-stats": {
|
||||
@ -2588,9 +2588,9 @@
|
||||
},
|
||||
"watermark-screen": {
|
||||
"action": {
|
||||
"change-success": "Watermark has been updated!",
|
||||
"created-success": "Watermark has been created!",
|
||||
"error": "Failed to update watermark",
|
||||
"change-success": "Watermark has been updated.",
|
||||
"created-success": "Watermark has been created.",
|
||||
"error": "Failed to update watermark.",
|
||||
"revert": "Revert",
|
||||
"save": "Save changes"
|
||||
},
|
||||
@ -2623,7 +2623,7 @@
|
||||
"watermarks-listing": {
|
||||
"action": {
|
||||
"delete": "Delete",
|
||||
"delete-success": "Watermark has been deleted!",
|
||||
"delete-success": "Watermark has been deleted.",
|
||||
"edit": "Edit"
|
||||
},
|
||||
"add-new": "New watermark",
|
||||
|
||||
File diff suppressed because one or more lines are too long
205
apps/red-ui/src/assets/pdftron/fonts/Apache License.txt
Normal file
205
apps/red-ui/src/assets/pdftron/fonts/Apache License.txt
Normal file
@ -0,0 +1,205 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.-------------------------------------------------------------------
|
||||
------------[ Log Start: 2019-Oct-10 19:32:29.143159]--------------
|
||||
System: (Windows, AMD64), PDFNetVersion: 7.1.0.71627
|
||||
-------------------------------------------------------------------
|
||||
[ INFO 19:32:29.143159, fontapp, WebFontCreator.cpp(679)]: logging enabled
|
||||
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-Bold.ttf
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-Bold.ttf
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-Bold.ttf.brotli
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-Bold.ttf.brotli
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-Bold.ttf.lzma
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-Bold.ttf.lzma
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-BoldItalic.ttf
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-BoldItalic.ttf.brotli
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-BoldItalic.ttf.brotli
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-BoldItalic.ttf.lzma
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-BoldItalic.ttf.lzma
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-Italic.ttf
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-Italic.ttf
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-Italic.ttf.brotli
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-Italic.ttf.brotli
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-Italic.ttf.lzma
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-Italic.ttf.lzma
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-Regular.ttf
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-Regular.ttf
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-Regular.ttf.brotli
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-Regular.ttf.brotli
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-Regular.ttf.lzma
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Arimo-Regular.ttf.lzma
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/ArivoBlack.otf
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/ArivoBlack.otf
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/ArivoBlack.otf.brotli
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/ArivoBlack.otf.brotli
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/ArivoBlack.otf.lzma
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/ArivoBlack.otf.lzma
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-Bold.ttf
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-Bold.ttf
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-Bold.ttf.brotli
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-Bold.ttf.brotli
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-Bold.ttf.lzma
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-Bold.ttf.lzma
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-BoldItalic.ttf
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-BoldItalic.ttf
Normal file
Binary file not shown.
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-BoldItalic.ttf.lzma
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-BoldItalic.ttf.lzma
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-Italic.ttf
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-Italic.ttf
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-Italic.ttf.brotli
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-Italic.ttf.brotli
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-Italic.ttf.lzma
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-Italic.ttf.lzma
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-Regular.ttf
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-Regular.ttf
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-Regular.ttf.brotli
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-Regular.ttf.brotli
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-Regular.ttf.lzma
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Caladea-Regular.ttf.lzma
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Carlito-Bold.ttf
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Carlito-Bold.ttf
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Carlito-Bold.ttf.brotli
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Carlito-Bold.ttf.brotli
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Carlito-Bold.ttf.lzma
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Carlito-Bold.ttf.lzma
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Carlito-BoldItalic.ttf
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Carlito-BoldItalic.ttf
Normal file
Binary file not shown.
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Carlito-BoldItalic.ttf.lzma
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Carlito-BoldItalic.ttf.lzma
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Carlito-Italic.ttf
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Carlito-Italic.ttf
Normal file
Binary file not shown.
BIN
apps/red-ui/src/assets/pdftron/fonts/Carlito-Italic.ttf.brotli
Normal file
BIN
apps/red-ui/src/assets/pdftron/fonts/Carlito-Italic.ttf.brotli
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user