Merge branch 'master' into RED-3796
This commit is contained in:
commit
0ab20a608a
@ -25,16 +25,17 @@
|
||||
<iqser-help-button [dialogButton]="false"></iqser-help-button>
|
||||
<redaction-notifications iqserHelpMode="open_notifications"></redaction-notifications>
|
||||
</div>
|
||||
<redaction-user-button [matMenuTriggerFor]="userMenu" [userId]="currentUser.id"></redaction-user-button>
|
||||
|
||||
<redaction-user-button [matMenuTriggerFor]="userMenu" [userId]="currentUser.id" id="userMenu"></redaction-user-button>
|
||||
|
||||
<mat-menu #userMenu="matMenu" xPosition="before">
|
||||
<ng-container *ngFor="let item of userMenuItems; trackBy: trackByName">
|
||||
<a (click)="(item.action)" *ngIf="item.show" [routerLink]="item.routerLink" mat-menu-item>
|
||||
<a (click)="(item.action)" *ngIf="item.show" [id]="item.id" [routerLink]="item.routerLink" mat-menu-item>
|
||||
{{ item.name | translate }}
|
||||
</a>
|
||||
</ng-container>
|
||||
|
||||
<button (click)="userService.logout()" mat-menu-item>
|
||||
<button (click)="userService.logout()" id="logout" mat-menu-item>
|
||||
<mat-icon svgIcon="iqser:logout"></mat-icon>
|
||||
<span translate="top-bar.navigation-items.my-account.children.logout"> </span>
|
||||
</button>
|
||||
|
||||
@ -13,6 +13,7 @@ import { FeaturesService } from '@services/features.service';
|
||||
import { DOSSIERS_ARCHIVE } from '@utils/constants';
|
||||
|
||||
interface MenuItem {
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly routerLink?: string;
|
||||
readonly show: boolean;
|
||||
@ -31,21 +32,25 @@ export class BaseScreenComponent {
|
||||
readonly currentUser = this.userService.currentUser;
|
||||
readonly userMenuItems: readonly MenuItem[] = [
|
||||
{
|
||||
id: 'account',
|
||||
name: _('top-bar.navigation-items.my-account.children.account'),
|
||||
routerLink: '/main/account',
|
||||
show: true,
|
||||
},
|
||||
{
|
||||
id: 'admin',
|
||||
name: _('top-bar.navigation-items.my-account.children.admin'),
|
||||
routerLink: '/main/admin',
|
||||
show: this.currentUser.isManager || this.currentUser.isUserAdmin,
|
||||
},
|
||||
{
|
||||
id: 'downloads',
|
||||
name: _('top-bar.navigation-items.my-account.children.downloads'),
|
||||
routerLink: '/main/downloads',
|
||||
show: this.currentUser.isUser,
|
||||
},
|
||||
{
|
||||
id: 'trash',
|
||||
name: _('top-bar.navigation-items.my-account.children.trash'),
|
||||
routerLink: '/main/admin/trash',
|
||||
show: this.currentUser.isManager,
|
||||
|
||||
@ -37,7 +37,8 @@ export class AnnotationPermissions {
|
||||
const annotationEntity = entities.find(entity => entity.type === annotation.type);
|
||||
permissions.canMarkAsFalsePositive = annotation.canBeMarkedAsFalsePositive && annotationEntity.hasDictionary;
|
||||
|
||||
permissions.canRemoveOrSuggestToRemoveOnlyHere = (annotation.isRedacted || annotation.isHint) && !annotation.pending;
|
||||
permissions.canRemoveOrSuggestToRemoveOnlyHere =
|
||||
(annotation.isRedacted || annotation.isHint) && !annotation.pending && !annotation.isImage;
|
||||
permissions.canRemoveOrSuggestToRemoveFromDictionary =
|
||||
annotation.isModifyDictionary &&
|
||||
(annotation.isRedacted || annotation.isSkipped || annotation.isHint) &&
|
||||
|
||||
@ -303,20 +303,24 @@ export class AnnotationWrapper implements IListable, Record<string, unknown> {
|
||||
}
|
||||
}
|
||||
|
||||
private static _getLastRelevantManualChange(manualChanges: IManualChange[]) {
|
||||
return manualChanges[manualChanges.length - 1];
|
||||
}
|
||||
|
||||
private static _setSuperType(annotationWrapper: AnnotationWrapper, redactionLogEntryWrapper: RedactionLogEntry) {
|
||||
if (redactionLogEntryWrapper.manualChanges?.length) {
|
||||
const lastManualChange = redactionLogEntryWrapper.manualChanges[redactionLogEntryWrapper.manualChanges.length - 1];
|
||||
const lastRelevantManualChange = this._getLastRelevantManualChange(redactionLogEntryWrapper.manualChanges);
|
||||
|
||||
annotationWrapper.pending = !lastManualChange.processed;
|
||||
annotationWrapper.pending = !lastRelevantManualChange.processed;
|
||||
|
||||
annotationWrapper.superType = AnnotationWrapper._selectSuperType(
|
||||
redactionLogEntryWrapper,
|
||||
lastManualChange,
|
||||
lastRelevantManualChange,
|
||||
annotationWrapper.hintDictionary,
|
||||
);
|
||||
|
||||
if (lastManualChange.annotationStatus === LogEntryStatus.REQUESTED) {
|
||||
annotationWrapper.recategorizationType = lastManualChange.propertyChanges.type;
|
||||
if (lastRelevantManualChange.annotationStatus === LogEntryStatus.REQUESTED) {
|
||||
annotationWrapper.recategorizationType = lastRelevantManualChange.propertyChanges.type;
|
||||
}
|
||||
} else {
|
||||
if (redactionLogEntryWrapper.recommendation) {
|
||||
@ -418,7 +422,7 @@ export class AnnotationWrapper implements IListable, Record<string, unknown> {
|
||||
case LogEntryStatus.APPROVED:
|
||||
return SuperTypes.Redaction;
|
||||
case LogEntryStatus.DECLINED:
|
||||
return SuperTypes.Skipped;
|
||||
return isHintDictionary ? SuperTypes.IgnoredHint : SuperTypes.Skipped;
|
||||
case LogEntryStatus.REQUESTED:
|
||||
return SuperTypes.SuggestionForceRedaction;
|
||||
}
|
||||
@ -444,7 +448,7 @@ export class AnnotationWrapper implements IListable, Record<string, unknown> {
|
||||
} else if (redactionLogEntry.hint) {
|
||||
return SuperTypes.Hint;
|
||||
} else {
|
||||
return SuperTypes.Skipped;
|
||||
return isHintDictionary ? SuperTypes.IgnoredHint : SuperTypes.Skipped;
|
||||
}
|
||||
}
|
||||
case LogEntryStatus.REQUESTED:
|
||||
@ -471,7 +475,7 @@ export class AnnotationWrapper implements IListable, Record<string, unknown> {
|
||||
} else if (redactionLogEntry.hint) {
|
||||
return SuperTypes.Hint;
|
||||
} else {
|
||||
return SuperTypes.Skipped;
|
||||
return isHintDictionary ? SuperTypes.IgnoredHint : SuperTypes.Skipped;
|
||||
}
|
||||
case LogEntryStatus.REQUESTED:
|
||||
return SuperTypes.SuggestionResize;
|
||||
|
||||
@ -29,6 +29,7 @@ export class RedactionLogEntry implements IRedactionLogEntry {
|
||||
readonly textBefore?: string;
|
||||
readonly type?: string;
|
||||
readonly value?: string;
|
||||
readonly sourceId?: string;
|
||||
|
||||
reason?: string;
|
||||
|
||||
@ -69,5 +70,6 @@ export class RedactionLogEntry implements IRedactionLogEntry {
|
||||
this.type = redactionLogEntry.type;
|
||||
this.value = redactionLogEntry.value;
|
||||
this.imported = redactionLogEntry.imported;
|
||||
this.sourceId = redactionLogEntry.sourceId;
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ import { UserListingScreenComponent } from './screens/user-listing/user-listing-
|
||||
import { DossierTemplateBreadcrumbsComponent } from './components/dossier-template-breadcrumbs/dossier-template-breadcrumbs.component';
|
||||
import { ColorPickerModule } from 'ngx-color-picker';
|
||||
import { AddEditFileAttributeDialogComponent } from './dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component';
|
||||
import { AddEditCloneDossierTemplateDialogComponent } from './dialogs/add-edit-clone-dossier-template-dialog/add-edit-clone-dossier-template-dialog.component';
|
||||
import { AddEditDossierTemplateDialogComponent } from './dialogs/add-edit-dossier-template-dialog/add-edit-dossier-template-dialog.component';
|
||||
import { AddEntityDialogComponent } from './dialogs/add-entity-dialog/add-entity-dialog.component';
|
||||
import { EditColorDialogComponent } from './dialogs/edit-color-dialog/edit-color-dialog.component';
|
||||
import { ComboChartComponent, ComboSeriesVerticalComponent } from './components/combo-chart';
|
||||
@ -48,11 +48,13 @@ import { A11yModule } from '@angular/cdk/a11y';
|
||||
import { ConfirmDeleteDossierStateDialogComponent } from './dialogs/confirm-delete-dossier-state-dialog/confirm-delete-dossier-state-dialog.component';
|
||||
import { TrashTableItemComponent } from './screens/trash/trash-table-item/trash-table-item.component';
|
||||
import { BaseEntityScreenComponent } from './base-entity-screen/base-entity-screen.component';
|
||||
import { CloneDossierTemplateDialogComponent } from './dialogs/clone-dossier-template-dialog/clone-dossier-template-dialog.component';
|
||||
|
||||
const dialogs = [
|
||||
AddEditCloneDossierTemplateDialogComponent,
|
||||
AddEditDossierTemplateDialogComponent,
|
||||
AddEntityDialogComponent,
|
||||
AddEditFileAttributeDialogComponent,
|
||||
CloneDossierTemplateDialogComponent,
|
||||
EditColorDialogComponent,
|
||||
SmtpAuthDialogComponent,
|
||||
AddEditUserDialogComponent,
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
<section class="dialog">
|
||||
<div
|
||||
[translateParams]="{
|
||||
type: dossierTemplate ? (data.clone ? 'clone' : 'edit') : 'create',
|
||||
type: dossierTemplate ? 'edit' : 'create',
|
||||
name: dossierTemplate?.name
|
||||
}"
|
||||
[translate]="'add-edit-clone-dossier-template.title'"
|
||||
[translate]="'add-edit-dossier-template.title'"
|
||||
class="dialog-header heading-l"
|
||||
></div>
|
||||
|
||||
<form [formGroup]="form">
|
||||
<div class="dialog-content">
|
||||
<div class="iqser-input-group required w-300">
|
||||
<label translate="add-edit-clone-dossier-template.form.name"></label>
|
||||
<label translate="add-edit-dossier-template.form.name"></label>
|
||||
<input
|
||||
[placeholder]="'add-edit-clone-dossier-template.form.name-placeholder' | translate"
|
||||
[placeholder]="'add-edit-dossier-template.form.name-placeholder' | translate"
|
||||
formControlName="name"
|
||||
name="name"
|
||||
type="text"
|
||||
@ -21,9 +21,9 @@
|
||||
</div>
|
||||
|
||||
<div class="iqser-input-group w-400">
|
||||
<label translate="add-edit-clone-dossier-template.form.description"></label>
|
||||
<label translate="add-edit-dossier-template.form.description"></label>
|
||||
<textarea
|
||||
[placeholder]="'add-edit-clone-dossier-template.form.description-placeholder' | translate"
|
||||
[placeholder]="'add-edit-dossier-template.form.description-placeholder' | translate"
|
||||
formControlName="description"
|
||||
name="description"
|
||||
rows="4"
|
||||
@ -34,11 +34,11 @@
|
||||
<div class="validity">
|
||||
<div>
|
||||
<mat-checkbox (change)="toggleHasValid('from')" [checked]="hasValidFrom" class="filter-menu-checkbox" color="primary">
|
||||
{{ 'add-edit-clone-dossier-template.form.valid-from' | translate }}
|
||||
{{ 'add-edit-dossier-template.form.valid-from' | translate }}
|
||||
</mat-checkbox>
|
||||
|
||||
<mat-checkbox (change)="toggleHasValid('to')" [checked]="hasValidTo" class="filter-menu-checkbox" color="primary">
|
||||
{{ 'add-edit-clone-dossier-template.form.valid-to' | translate }}
|
||||
{{ 'add-edit-dossier-template.form.valid-to' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
@ -83,7 +83,7 @@
|
||||
|
||||
<div class="dialog-actions">
|
||||
<button (click)="save()" [disabled]="disabled" color="primary" mat-flat-button type="button">
|
||||
{{ 'add-edit-clone-dossier-template.save' | translate }}
|
||||
{{ 'add-edit-dossier-template.save' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
@ -12,16 +12,11 @@ import { DictionaryService } from '@services/entity-services/dictionary.service'
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import dayjs, { Dayjs } from 'dayjs';
|
||||
|
||||
interface EditCloneTemplateData {
|
||||
dossierTemplateId: string;
|
||||
clone?: boolean;
|
||||
}
|
||||
|
||||
@Component({
|
||||
templateUrl: './add-edit-clone-dossier-template-dialog.component.html',
|
||||
styleUrls: ['./add-edit-clone-dossier-template-dialog.component.scss'],
|
||||
templateUrl: './add-edit-dossier-template-dialog.component.html',
|
||||
styleUrls: ['./add-edit-dossier-template-dialog.component.scss'],
|
||||
})
|
||||
export class AddEditCloneDossierTemplateDialogComponent extends BaseDialogComponent {
|
||||
export class AddEditDossierTemplateDialogComponent extends BaseDialogComponent {
|
||||
hasValidFrom: boolean;
|
||||
hasValidTo: boolean;
|
||||
downloadTypesEnum: DownloadFileType[] = ['ORIGINAL', 'PREVIEW', 'DELTA_PREVIEW', 'REDACTED'];
|
||||
@ -41,12 +36,12 @@ export class AddEditCloneDossierTemplateDialogComponent extends BaseDialogCompon
|
||||
private readonly _dictionaryService: DictionaryService,
|
||||
private readonly _formBuilder: FormBuilder,
|
||||
protected readonly _injector: Injector,
|
||||
protected readonly _dialogRef: MatDialogRef<AddEditCloneDossierTemplateDialogComponent>,
|
||||
protected readonly _dialogRef: MatDialogRef<AddEditDossierTemplateDialogComponent>,
|
||||
private readonly _loadingService: LoadingService,
|
||||
@Inject(MAT_DIALOG_DATA) readonly data: EditCloneTemplateData,
|
||||
@Inject(MAT_DIALOG_DATA) readonly dossierTemplateId: string,
|
||||
) {
|
||||
super(_injector, _dialogRef, !!data && !data.clone);
|
||||
this.dossierTemplate = this._dossierTemplatesService.find(this.data?.dossierTemplateId);
|
||||
super(_injector, _dialogRef, !!dossierTemplateId);
|
||||
this.dossierTemplate = this._dossierTemplatesService.find(dossierTemplateId);
|
||||
this.form = this._getForm();
|
||||
this.initialFormValue = this.form.getRawValue();
|
||||
this.hasValidFrom = !!this.dossierTemplate?.validFrom;
|
||||
@ -81,24 +76,18 @@ export class AddEditCloneDossierTemplateDialogComponent extends BaseDialogCompon
|
||||
this._loadingService.start();
|
||||
try {
|
||||
const dossierTemplate = {
|
||||
dossierTemplateId: !this.data?.clone ? this.dossierTemplate?.dossierTemplateId : null,
|
||||
dossierTemplateId: this.dossierTemplate?.dossierTemplateId,
|
||||
...this.form.getRawValue(),
|
||||
validFrom: this.hasValidFrom ? this.form.get('validFrom').value : null,
|
||||
validTo: this.hasValidTo ? this.form.get('validTo').value : null,
|
||||
} as IDossierTemplate;
|
||||
if (this.data?.clone) {
|
||||
const dossierTemplateId = this.dossierTemplate?.dossierTemplateId;
|
||||
const nameOfClonedTemplate = this._getNameOfClonedTemplate(this.dossierTemplate.name);
|
||||
await firstValueFrom(this._dossierTemplatesService.clone(dossierTemplate, dossierTemplateId, nameOfClonedTemplate));
|
||||
} else {
|
||||
await firstValueFrom(this._dossierTemplatesService.createOrUpdate(dossierTemplate));
|
||||
}
|
||||
await firstValueFrom(this._dossierTemplatesService.createOrUpdate(dossierTemplate));
|
||||
this._dialogRef.close(true);
|
||||
} catch (error: any) {
|
||||
const message =
|
||||
error.status === HttpStatusCode.Conflict
|
||||
? _('add-edit-clone-dossier-template.error.conflict')
|
||||
: _('add-edit-clone-dossier-template.error.generic');
|
||||
? _('add-edit-dossier-template.error.conflict')
|
||||
: _('add-edit-dossier-template.error.generic');
|
||||
this._toaster.error(message, { error });
|
||||
}
|
||||
this._loadingService.stop();
|
||||
@ -106,7 +95,7 @@ export class AddEditCloneDossierTemplateDialogComponent extends BaseDialogCompon
|
||||
|
||||
private _getForm(): FormGroup {
|
||||
return this._formBuilder.group({
|
||||
name: [this._getTemplateName(), Validators.required],
|
||||
name: [this.dossierTemplate?.name, Validators.required],
|
||||
description: [this.dossierTemplate?.description],
|
||||
validFrom: [
|
||||
this.dossierTemplate?.validFrom ? dayjs(this.dossierTemplate?.validFrom) : null,
|
||||
@ -120,37 +109,6 @@ export class AddEditCloneDossierTemplateDialogComponent extends BaseDialogCompon
|
||||
});
|
||||
}
|
||||
|
||||
private _getTemplateName(): string | null {
|
||||
if (this.dossierTemplate) {
|
||||
const templateName = this.dossierTemplate.name.trim();
|
||||
if (this.data.clone) {
|
||||
const nameOfClonedTemplate = this._getNameOfClonedTemplate(templateName);
|
||||
const allTemplatesNames = this._dossierTemplatesService.all.map(t => t.name);
|
||||
|
||||
let clonesCount = 0;
|
||||
for (const name of allTemplatesNames) {
|
||||
const splitName = name.split(nameOfClonedTemplate);
|
||||
const suffixRegExp = new RegExp(/^\(\s*\d+\s*\)$/);
|
||||
if (splitName[0] === 'Clone of ' && (splitName[1].trim().match(suffixRegExp) || splitName[1] === '')) {
|
||||
clonesCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (clonesCount >= 1) {
|
||||
return `Clone of ${nameOfClonedTemplate} ${clonesCount === 1 ? '(1)' : `(${clonesCount})`}`;
|
||||
}
|
||||
return `Clone of ${nameOfClonedTemplate}`;
|
||||
}
|
||||
return templateName;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private _getNameOfClonedTemplate(templateName: string): string {
|
||||
const nameOfClonedTemplate = templateName.split('Clone of ').filter(n => n)[0];
|
||||
return nameOfClonedTemplate.split(/\(\s*\d+\s*\)$/)[0].trim();
|
||||
}
|
||||
|
||||
private _applyValidityIntervalConstraints(value): boolean {
|
||||
if (applyIntervalConstraints(value, this._previousValidFrom, this._previousValidTo, this.form, 'validFrom', 'validTo')) {
|
||||
return true;
|
||||
@ -172,11 +130,4 @@ export class AddEditCloneDossierTemplateDialogComponent extends BaseDialogCompon
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
get disabled(): boolean {
|
||||
if (!this.data?.clone) {
|
||||
return super.disabled;
|
||||
}
|
||||
return !this.valid;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
<section class="dialog">
|
||||
<div translate="clone-dossier-template.title" class="dialog-header heading-l"></div>
|
||||
|
||||
<div class="dialog-content">
|
||||
<div class="iqser-input-group required w-full">
|
||||
<label translate="clone-dossier-template.content.name"></label>
|
||||
<input
|
||||
[placeholder]="'clone-dossier-template.content.name-placeholder' | translate"
|
||||
[(ngModel)]="nameOfClonedDossierTemplate"
|
||||
name="name"
|
||||
type="text"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<button color="primary" mat-flat-button type="submit" (click)="save()" [disabled]="!nameOfClonedDossierTemplate">
|
||||
{{ 'clone-dossier-template.actions.save' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
|
||||
</section>
|
||||
@ -0,0 +1,61 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { DossierTemplatesService } from '../../../../services/entity-services/dossier-templates.service';
|
||||
import { DossierTemplate, IDossierTemplate } from '../../../../../../../../libs/red-domain/src';
|
||||
import { LoadingService, Toaster } from '../../../../../../../../libs/common-ui/src';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
|
||||
@Component({
|
||||
templateUrl: './clone-dossier-template-dialog.component.html',
|
||||
styleUrls: ['./clone-dossier-template-dialog.component.scss'],
|
||||
})
|
||||
export class CloneDossierTemplateDialogComponent {
|
||||
private readonly _dossierTemplate: DossierTemplate;
|
||||
nameOfClonedDossierTemplate: string;
|
||||
|
||||
constructor(
|
||||
private readonly _toaster: Toaster,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _dossierTemplatesService: DossierTemplatesService,
|
||||
protected readonly _dialogRef: MatDialogRef<CloneDossierTemplateDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) readonly dossierTemplateId: string,
|
||||
) {
|
||||
this._dossierTemplate = this._dossierTemplatesService.find(dossierTemplateId);
|
||||
this.nameOfClonedDossierTemplate = this._getCloneName();
|
||||
}
|
||||
|
||||
private _getCloneName(): string | null {
|
||||
const templateName = this._dossierTemplate.name.trim();
|
||||
|
||||
let nameOfClonedTemplate: string = templateName.split('Clone of ').filter(n => n)[0];
|
||||
nameOfClonedTemplate = nameOfClonedTemplate.split(/\(\s*\d+\s*\)$/)[0].trim();
|
||||
|
||||
const allTemplatesNames = this._dossierTemplatesService.all.map(t => t.name);
|
||||
|
||||
let clonesCount = 0;
|
||||
for (const name of allTemplatesNames) {
|
||||
const splitName = name.split(nameOfClonedTemplate);
|
||||
const suffixRegExp = new RegExp(/^\(\s*\d+\s*\)$/);
|
||||
if (splitName[0] === 'Clone of ' && (splitName[1].trim().match(suffixRegExp) || splitName[1] === '')) {
|
||||
clonesCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (clonesCount >= 1) {
|
||||
return `Clone of ${nameOfClonedTemplate} ${clonesCount === 1 ? '(1)' : `(${clonesCount})`}`;
|
||||
}
|
||||
return `Clone of ${nameOfClonedTemplate}`;
|
||||
}
|
||||
|
||||
async save() {
|
||||
this._loadingService.start();
|
||||
try {
|
||||
await firstValueFrom(this._dossierTemplatesService.clone(this.dossierTemplateId, this.nameOfClonedDossierTemplate));
|
||||
this._dialogRef.close(true);
|
||||
} catch (error: any) {
|
||||
this._toaster.error(_('clone-dossier-template.error.generic'), { error });
|
||||
}
|
||||
this._loadingService.stop();
|
||||
}
|
||||
}
|
||||
@ -63,7 +63,7 @@ export class DossierTemplatesListingScreenComponent extends ListingComponent<Dos
|
||||
}
|
||||
|
||||
openAddDossierTemplateDialog() {
|
||||
this._dialogService.openDialog('addEditCloneDossierTemplate', null, null);
|
||||
this._dialogService.openDialog('addEditDossierTemplate', null, null);
|
||||
}
|
||||
|
||||
private async _deleteTemplates(templateIds = this.listingService.selected.map(d => d.dossierTemplateId)) {
|
||||
|
||||
@ -32,6 +32,6 @@ export class DossierTemplateInfoScreenComponent {
|
||||
}
|
||||
|
||||
openEditDossierTemplateDialog($event: MouseEvent, dossierTemplate: DossierTemplate) {
|
||||
this._dialogService.openDialog('addEditCloneDossierTemplate', $event, { dossierTemplateId: dossierTemplate.id });
|
||||
this._dialogService.openDialog('addEditDossierTemplate', $event, { dossierTemplateId: dossierTemplate.id });
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ import { Injectable, TemplateRef } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { AddEditFileAttributeDialogComponent } from '../dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component';
|
||||
import { AddEntityDialogComponent } from '../dialogs/add-entity-dialog/add-entity-dialog.component';
|
||||
import { AddEditCloneDossierTemplateDialogComponent } from '../dialogs/add-edit-clone-dossier-template-dialog/add-edit-clone-dossier-template-dialog.component';
|
||||
import { AddEditDossierTemplateDialogComponent } from '../dialogs/add-edit-dossier-template-dialog/add-edit-dossier-template-dialog.component';
|
||||
import { EditColorDialogComponent } from '../dialogs/edit-color-dialog/edit-color-dialog.component';
|
||||
import { SmtpAuthDialogComponent } from '../dialogs/smtp-auth-dialog/smtp-auth-dialog.component';
|
||||
import { AddEditUserDialogComponent } from '../dialogs/add-edit-user-dialog/add-edit-user-dialog.component';
|
||||
@ -28,6 +28,7 @@ import { ActiveDossiersService } from '@services/dossiers/active-dossiers.servic
|
||||
import { UserService } from '@services/user.service';
|
||||
import { IDossierAttributeConfig, IFileAttributeConfig, IReportTemplate } from '@red/domain';
|
||||
import { ReportTemplateService } from '@services/report-template.service';
|
||||
import { CloneDossierTemplateDialogComponent } from '../dialogs/clone-dossier-template-dialog/clone-dossier-template-dialog.component';
|
||||
|
||||
type DialogType =
|
||||
| 'confirm'
|
||||
@ -38,7 +39,8 @@ type DialogType =
|
||||
| 'fileAttributesConfigurations'
|
||||
| 'addEditUser'
|
||||
| 'smtpAuthConfig'
|
||||
| 'addEditCloneDossierTemplate'
|
||||
| 'addEditDossierTemplate'
|
||||
| 'cloneDossierTemplate'
|
||||
| 'addEditDossierAttribute'
|
||||
| 'uploadDictionary'
|
||||
| 'addEditDossierState'
|
||||
@ -78,10 +80,14 @@ export class AdminDialogService extends DialogService<DialogType> {
|
||||
component: SmtpAuthDialogComponent,
|
||||
dialogConfig: { autoFocus: true },
|
||||
},
|
||||
addEditCloneDossierTemplate: {
|
||||
component: AddEditCloneDossierTemplateDialogComponent,
|
||||
addEditDossierTemplate: {
|
||||
component: AddEditDossierTemplateDialogComponent,
|
||||
dialogConfig: { width: '900px', autoFocus: true },
|
||||
},
|
||||
cloneDossierTemplate: {
|
||||
component: CloneDossierTemplateDialogComponent,
|
||||
dialogConfig: { disableClose: false },
|
||||
},
|
||||
addEditDossierAttribute: {
|
||||
component: AddEditDossierAttributeDialogComponent,
|
||||
dialogConfig: { autoFocus: true },
|
||||
|
||||
@ -7,14 +7,14 @@
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="openEditCloneDossierTemplateDialog($event, true)"
|
||||
(action)="openCloneDossierTemplateDialog($event)"
|
||||
[tooltip]="'dossier-templates-listing.action.clone' | translate"
|
||||
icon="iqser:copy"
|
||||
[type]="circleButtonTypes.dark"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="openEditCloneDossierTemplateDialog($event)"
|
||||
(action)="openEditDossierTemplateDialog($event)"
|
||||
[tooltip]="'dossier-templates-listing.action.edit' | translate"
|
||||
icon="iqser:edit"
|
||||
[type]="circleButtonTypes.dark"
|
||||
|
||||
@ -34,8 +34,11 @@ export class DossierTemplateActionsComponent implements OnInit {
|
||||
this.dossierTemplateId ??= this._route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID);
|
||||
}
|
||||
|
||||
openEditCloneDossierTemplateDialog($event: MouseEvent, clone: boolean = false) {
|
||||
this._dialogService.openDialog('addEditCloneDossierTemplate', $event, { dossierTemplateId: this.dossierTemplateId, clone });
|
||||
openEditDossierTemplateDialog($event: MouseEvent) {
|
||||
this._dialogService.openDialog('addEditDossierTemplate', $event, this.dossierTemplateId);
|
||||
}
|
||||
openCloneDossierTemplateDialog($event: MouseEvent) {
|
||||
this._dialogService.openDialog('cloneDossierTemplate', $event, this.dossierTemplateId);
|
||||
}
|
||||
|
||||
openDeleteDossierTemplateDialog($event?: MouseEvent) {
|
||||
|
||||
@ -215,7 +215,11 @@ export class ConfigService {
|
||||
filters = dynamicFilters.get(filterKey);
|
||||
}
|
||||
const filterValue = file.fileAttributes?.attributeIdToValue[config.id];
|
||||
filters.add(filterValue);
|
||||
if (filterValue === undefined || filterValue === null) {
|
||||
filters.add(undefined);
|
||||
} else {
|
||||
filters.add(filterValue);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -83,7 +83,15 @@ export class AnnotationActionsComponent implements OnChanges {
|
||||
}
|
||||
|
||||
get helpModeKey() {
|
||||
return this.annotations[0]?.typeLabel?.split('.')[1];
|
||||
const type = this.annotations[0]?.typeLabel?.split('.')[1];
|
||||
const typeValue = this.annotations[0]?.typeValue;
|
||||
if (type === 'hint' && (typeValue === 'formula' || typeValue === 'image')) {
|
||||
return 'image';
|
||||
}
|
||||
if (type === 'redaction' || type === 'manual-redaction') {
|
||||
return 'redaction';
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
ngOnChanges(): void {
|
||||
|
||||
@ -26,7 +26,7 @@ import { AnnotationActionsService } from '../../services/annotation-actions.serv
|
||||
import { UserPreferenceService } from '@services/user-preference.service';
|
||||
import { BASE_HREF } from '../../../../tokens';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
import { AutoUnsubscribe, ConfirmationDialogInput, LoadingService } from '@iqser/common-ui';
|
||||
import { AutoUnsubscribe, ConfirmationDialogInput, CustomError, ErrorService, LoadingService } from '@iqser/common-ui';
|
||||
import { PdfViewer } from '../../services/pdf-viewer.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { toPosition } from '../../../dossier/utils/pdf-calculation.utils';
|
||||
@ -47,6 +47,8 @@ import Tools = Core.Tools;
|
||||
import TextTool = Tools.TextTool;
|
||||
import Annotation = Core.Annotations.Annotation;
|
||||
|
||||
const DocLoadingError = new CustomError(_('error.file-preview.label'), _('error.file-preview.action'), 'iqser:refresh');
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-pdf-viewer',
|
||||
templateUrl: './pdf-viewer.component.html',
|
||||
@ -81,6 +83,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
|
||||
private readonly _fileDataService: FileDataService,
|
||||
private readonly _headerConfigService: ViewerHeaderConfigService,
|
||||
private readonly _tooltipsService: TooltipsService,
|
||||
private readonly _errorService: ErrorService,
|
||||
readonly stateService: FilePreviewStateService,
|
||||
readonly viewModeService: ViewModeService,
|
||||
readonly multiSelectService: MultiSelectService,
|
||||
@ -97,6 +100,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
|
||||
.pipe(
|
||||
switchMap(blob => from(this.pdfViewer.lockDocument()).pipe(map(() => blob))),
|
||||
withLatestFrom(this.stateService.file$),
|
||||
tap(() => this._errorService.clear()),
|
||||
tap(([blob, file]) => this._loadDocument(blob, file)),
|
||||
)
|
||||
.subscribe();
|
||||
@ -484,7 +488,6 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
|
||||
}
|
||||
|
||||
private _handleCustomActions() {
|
||||
this.instance.UI.setToolMode('AnnotationEdit');
|
||||
const textPopupsToToggle = [TextPopups.ADD_REDACTION, TextPopups.ADD_RECTANGLE, TextPopups.ADD_FALSE_POSITIVE];
|
||||
const headerItemsToToggle = [
|
||||
HeaderElements.SHAPE_TOOL_GROUP_BUTTON,
|
||||
@ -550,7 +553,12 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
|
||||
}
|
||||
|
||||
private _loadDocument(blob: Blob, file: File) {
|
||||
this.instance.UI.loadDocument(blob, { filename: file?.filename + '.pdf' ?? 'document.pdf' });
|
||||
const onError = () => {
|
||||
this._loadingService.stop();
|
||||
this._errorService.set(DocLoadingError);
|
||||
this.stateService.reloadBlob();
|
||||
};
|
||||
this.instance.UI.loadDocument(blob, { filename: file?.filename + '.pdf' ?? 'document.pdf', onError });
|
||||
this._pageRotationService.clearRotationsHideActions();
|
||||
}
|
||||
|
||||
|
||||
@ -396,7 +396,7 @@ export class AnnotationActionsService {
|
||||
annotationWrapper.resizing = true;
|
||||
|
||||
const viewerAnnotation = this._pdf.annotationManager.getAnnotationById(annotationWrapper.id);
|
||||
if (annotationWrapper.rectangle || annotationWrapper.imported) {
|
||||
if (annotationWrapper.rectangle || annotationWrapper.imported || annotationWrapper.isImage) {
|
||||
this._pdf.deleteAnnotations([annotationWrapper.id]);
|
||||
const rectangleAnnotation = this.#generateRectangle(annotationWrapper);
|
||||
this._pdf.annotationManager.addAnnotation(rectangleAnnotation, { imported: true });
|
||||
@ -446,12 +446,12 @@ export class AnnotationActionsService {
|
||||
$event?.stopPropagation();
|
||||
|
||||
const requests: List<IAddRedactionRequest> = annotations.map(annotation => ({
|
||||
reason: annotation.id,
|
||||
sourceId: annotation.id,
|
||||
value: this._getFalsePositiveText(annotation),
|
||||
type: annotation.type,
|
||||
positions: annotation.positions,
|
||||
addToDictionary: true,
|
||||
comment: { text: 'False Positive' },
|
||||
reason: 'False Positive',
|
||||
dictionaryEntryType: annotation.isRecommendation
|
||||
? DictionaryEntryTypes.FALSE_RECOMMENDATION
|
||||
: DictionaryEntryTypes.FALSE_POSITIVE,
|
||||
|
||||
@ -1,14 +1,4 @@
|
||||
import {
|
||||
ChangeType,
|
||||
File,
|
||||
IRedactionLog,
|
||||
IRedactionLogEntry,
|
||||
IViewedPage,
|
||||
LogEntryStatus,
|
||||
ManualRedactionType,
|
||||
ViewMode,
|
||||
ViewModes,
|
||||
} from '@red/domain';
|
||||
import { ChangeType, File, IRedactionLog, IRedactionLogEntry, IViewedPage, ViewMode, ViewModes } from '@red/domain';
|
||||
import { AnnotationWrapper } from '../../../models/file/annotation.wrapper';
|
||||
import { BehaviorSubject, firstValueFrom, iif, Observable, Subject } from 'rxjs';
|
||||
import { RedactionLogEntry } from '../../../models/file/redaction-log.entry';
|
||||
@ -179,7 +169,7 @@ export class FileDataService extends EntitiesService<AnnotationWrapper> {
|
||||
|
||||
#convertData(redactionLog: IRedactionLog, file: File): RedactionLogEntry[] {
|
||||
let result: RedactionLogEntry[] = [];
|
||||
const reasonAnnotationIds: { [key: string]: RedactionLogEntry[] } = {};
|
||||
const sourceIdAnnotationIds: { [key: string]: RedactionLogEntry[] } = {};
|
||||
const dictionaries = this._dictionariesMapService.get(this._state.dossierTemplateId);
|
||||
|
||||
redactionLog.redactionLogEntry?.forEach(redactionLogEntry => {
|
||||
@ -199,36 +189,18 @@ export class FileDataService extends EntitiesService<AnnotationWrapper> {
|
||||
!!dictionary?.hint,
|
||||
);
|
||||
|
||||
if (
|
||||
redactionLogEntry.manualChanges?.find(
|
||||
mc =>
|
||||
mc.manualRedactionType === ManualRedactionType.ADD_TO_DICTIONARY &&
|
||||
(mc.annotationStatus === LogEntryStatus.APPROVED || mc.annotationStatus === LogEntryStatus.REQUESTED),
|
||||
)
|
||||
) {
|
||||
// for dictionary entries -> I.E accepted recommendations or false positives,
|
||||
// check reason
|
||||
if (!reasonAnnotationIds[redactionLogEntry.reason]) {
|
||||
reasonAnnotationIds[redactionLogEntry.reason] = [redactionLogEntryWrapper];
|
||||
} else {
|
||||
reasonAnnotationIds[redactionLogEntry.reason].push(redactionLogEntryWrapper);
|
||||
if (redactionLogEntry.sourceId) {
|
||||
if (!sourceIdAnnotationIds[redactionLogEntry.sourceId]) {
|
||||
sourceIdAnnotationIds[redactionLogEntry.sourceId] = [];
|
||||
}
|
||||
sourceIdAnnotationIds[redactionLogEntry.sourceId].push(redactionLogEntryWrapper);
|
||||
}
|
||||
|
||||
result.push(redactionLogEntryWrapper);
|
||||
});
|
||||
|
||||
const reasonKeys = Object.keys(reasonAnnotationIds);
|
||||
result = result.filter(r => {
|
||||
const matched = reasonKeys.indexOf(r.id) >= 0;
|
||||
if (matched) {
|
||||
reasonAnnotationIds[r.id].forEach(value => {
|
||||
value.reason = null;
|
||||
});
|
||||
}
|
||||
return !matched;
|
||||
});
|
||||
|
||||
const sourceKeys = Object.keys(sourceIdAnnotationIds);
|
||||
result = result.filter(r => !sourceKeys.includes(r.id));
|
||||
result = result.filter(r => !r.hidden);
|
||||
|
||||
return result;
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { combineLatest, firstValueFrom, from, Observable, of, pairwise, switchMap } from 'rxjs';
|
||||
import { combineLatest, firstValueFrom, from, merge, Observable, of, pairwise, Subject, switchMap } from 'rxjs';
|
||||
import { Dossier, File } from '@red/domain';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { FilesMapService } from '@services/entity-services/files-map.service';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { boolFactory } from '@iqser/common-ui';
|
||||
import { filter, startWith, tap } from 'rxjs/operators';
|
||||
import { filter, map, startWith, tap, withLatestFrom } from 'rxjs/operators';
|
||||
import { FileManagementService } from '@services/entity-services/file-management.service';
|
||||
import { DOSSIER_ID, FILE_ID } from '@utils/constants';
|
||||
import { dossiersServiceResolver } from '@services/entity-services/dossiers.service.provider';
|
||||
@ -29,26 +29,28 @@ export class FilePreviewStateService {
|
||||
dossier: Dossier;
|
||||
file: File;
|
||||
|
||||
constructor(
|
||||
private readonly _fileManagementService: FileManagementService,
|
||||
private readonly _injector: Injector,
|
||||
private readonly _route: ActivatedRoute,
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
private readonly _dossiersService: DossiersService,
|
||||
private readonly _filesService: FilesService,
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
) {
|
||||
const dossiersService = dossiersServiceResolver(this._injector);
|
||||
readonly #reloadBlob$ = new Subject();
|
||||
|
||||
this.fileId = _route.snapshot.paramMap.get(FILE_ID);
|
||||
this.dossierId = _route.snapshot.paramMap.get(DOSSIER_ID);
|
||||
constructor(
|
||||
route: ActivatedRoute,
|
||||
filesMapService: FilesMapService,
|
||||
private readonly _injector: Injector,
|
||||
permissionsService: PermissionsService,
|
||||
private readonly _filesService: FilesService,
|
||||
private readonly _dossiersService: DossiersService,
|
||||
private readonly _fileManagementService: FileManagementService,
|
||||
) {
|
||||
const dossiersService = dossiersServiceResolver(_injector);
|
||||
|
||||
this.fileId = route.snapshot.paramMap.get(FILE_ID);
|
||||
this.dossierId = route.snapshot.paramMap.get(DOSSIER_ID);
|
||||
this.dossierTemplateId = dossiersService.find(this.dossierId).dossierTemplateId;
|
||||
|
||||
this.dossier$ = dossiersService.getEntityChanged$(this.dossierId).pipe(tap(dossier => (this.dossier = dossier)));
|
||||
this.file$ = _filesMapService.watch$(this.dossierId, this.fileId).pipe(tap(file => (this.file = file)));
|
||||
this.file$ = filesMapService.watch$(this.dossierId, this.fileId).pipe(tap(file => (this.file = file)));
|
||||
[this.isReadonly$, this.isWritable$] = boolFactory(
|
||||
combineLatest([this.file$, this.dossier$]),
|
||||
([file, dossier]) => !_permissionsService.canPerformAnnotationActions(file, dossier),
|
||||
([file, dossier]) => !permissionsService.canPerformAnnotationActions(file, dossier),
|
||||
);
|
||||
|
||||
this.blob$ = this.#blob$;
|
||||
@ -60,7 +62,11 @@ export class FilePreviewStateService {
|
||||
}
|
||||
|
||||
get #blob$() {
|
||||
return this.file$.pipe(
|
||||
const reloadBlob$ = this.#reloadBlob$.pipe(
|
||||
withLatestFrom(this.file$),
|
||||
map(([, file]) => file),
|
||||
);
|
||||
return merge(this.file$, reloadBlob$).pipe(
|
||||
startWith(undefined),
|
||||
pairwise(),
|
||||
filter(([oldFile, newFile]) => oldFile?.cacheIdentifier !== newFile.cacheIdentifier),
|
||||
@ -68,6 +74,10 @@ export class FilePreviewStateService {
|
||||
);
|
||||
}
|
||||
|
||||
reloadBlob(): void {
|
||||
this.#reloadBlob$.next(true);
|
||||
}
|
||||
|
||||
#dossierFilesChange$() {
|
||||
return this._dossiersService.dossierFileChanges$.pipe(
|
||||
filter(dossierId => dossierId === this.dossierId),
|
||||
|
||||
@ -66,8 +66,8 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
|
||||
addRecommendation(annotations: AnnotationWrapper[], dossierId: string, fileId: string, comment = { text: 'Accepted Recommendation' }) {
|
||||
const recommendations: List<IAddRedactionRequest> = annotations.map(annotation => ({
|
||||
addToDictionary: true,
|
||||
// set the ID as reason, so we can hide the suggestion
|
||||
reason: annotation.annotationId,
|
||||
sourceId: annotation.annotationId,
|
||||
reason: 'False Positive',
|
||||
value: annotation.value,
|
||||
positions: annotation.positions,
|
||||
type: annotation.recommendationType,
|
||||
|
||||
@ -70,8 +70,8 @@ export class DossierTemplatesService extends EntitiesService<DossierTemplate, ID
|
||||
return this._post(body).pipe(switchMap(() => this.loadAll()));
|
||||
}
|
||||
|
||||
clone(@RequiredParam() body: any, dossierTemplateId: string, name: string) {
|
||||
return this._post(body, `${this._defaultModelPath}/${dossierTemplateId}/clone?nameOfClonedDossierTemplate=${name}`).pipe(
|
||||
clone(dossierTemplateId: string, name: string) {
|
||||
return this._post(null, `${this._defaultModelPath}/${dossierTemplateId}/clone?nameOfClonedDossierTemplate=${name}`).pipe(
|
||||
switchMap(() => this.loadAll()),
|
||||
);
|
||||
}
|
||||
|
||||
@ -6,10 +6,12 @@ import { ILoggerConfig } from '@red/domain';
|
||||
export class LoggerRulesService extends NGXLoggerRulesService {
|
||||
shouldCallWriter(level: NgxLoggerLevel, config: ILoggerConfig, message?: unknown, additional?: unknown[]): boolean {
|
||||
if (message && typeof message === 'string') {
|
||||
const matches = message.match('(?<=\\[)(.*?)(?=\\])');
|
||||
const matches = message.match('\\[(.*?)\\]');
|
||||
|
||||
if (matches && matches.length > 0 && config.features[matches[0]]) {
|
||||
const featureConfig = config.features[matches[0]];
|
||||
const firstMatch = matches[1]?.toUpperCase();
|
||||
|
||||
if (matches && matches.length > 0 && config.features[firstMatch]) {
|
||||
const featureConfig = config.features[firstMatch];
|
||||
|
||||
if (!featureConfig.enabled || (featureConfig.level && featureConfig?.level < config.level)) {
|
||||
return false;
|
||||
|
||||
@ -150,7 +150,7 @@
|
||||
"fr": ""
|
||||
},
|
||||
"hint_remove_from_dictionary": {
|
||||
"en": "/en/index-en.html?contextId=hints_remove_from_dictionary",
|
||||
"en": "/en/index-en.html?contextId=hint_remove_from_dictionary",
|
||||
"de": "",
|
||||
"it": "",
|
||||
"fr": ""
|
||||
@ -252,7 +252,7 @@
|
||||
"fr": ""
|
||||
},
|
||||
"redaction_resize": {
|
||||
"en": "/en/index-en.html?contextId=redaction_resize_redaction",
|
||||
"en": "/en/index-en.html?contextId=redaction_resize",
|
||||
"de": "",
|
||||
"it": "",
|
||||
"fr": ""
|
||||
@ -263,6 +263,12 @@
|
||||
"it": "",
|
||||
"fr": ""
|
||||
},
|
||||
"hint_resize": {
|
||||
"en": "/en/index-en.html?contextId=hint_resize",
|
||||
"de": "",
|
||||
"it": "",
|
||||
"fr": ""
|
||||
},
|
||||
"skipped_force_redaction": {
|
||||
"en": "/en/index-en.html?contextId=skipped_force_redaction",
|
||||
"de": "",
|
||||
@ -358,5 +364,53 @@
|
||||
"de": "",
|
||||
"it": "",
|
||||
"fr": ""
|
||||
},
|
||||
"image_resize": {
|
||||
"en": "/en/index-en.html?contextId=image_resize",
|
||||
"de": "",
|
||||
"it": "",
|
||||
"fr": ""
|
||||
},
|
||||
"image_recategorize": {
|
||||
"en": "/en/index-en.html?contextId=image_recategorize",
|
||||
"de": "",
|
||||
"it": "",
|
||||
"fr": ""
|
||||
},
|
||||
"image_hide": {
|
||||
"en": "/en/index-en.html?contextId=image_hide",
|
||||
"de": "",
|
||||
"it": "",
|
||||
"fr": ""
|
||||
},
|
||||
"image_remove_only_here": {
|
||||
"en": "/en/index-en.html?contextId=image_remove_only_here",
|
||||
"de": "",
|
||||
"it": "",
|
||||
"fr": ""
|
||||
},
|
||||
"redaction_remove_from_dictionary": {
|
||||
"en": "/en/index-en.html?contextId=redaction_remove_from_dictionary",
|
||||
"de": "",
|
||||
"it": "",
|
||||
"fr": ""
|
||||
},
|
||||
"skipped_resize": {
|
||||
"en": "/en/index-en.html?contextId=skipped_resize_redaction",
|
||||
"de": "",
|
||||
"it": "",
|
||||
"fr": ""
|
||||
},
|
||||
"skipped_recategorize": {
|
||||
"en": "/en/index-en.html?contextId=skipped_recategorize_redaction",
|
||||
"de": "",
|
||||
"it": "",
|
||||
"fr": ""
|
||||
},
|
||||
"skipped_hide": {
|
||||
"en": "/en/index-en.html?contextId=skipped_hide",
|
||||
"de": "",
|
||||
"it": "",
|
||||
"fr": ""
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,22 +36,6 @@
|
||||
},
|
||||
"header-new": "Dossier erstellen"
|
||||
},
|
||||
"add-edit-clone-dossier-template": {
|
||||
"error": {
|
||||
"conflict": "Dossiervorlage konnte nicht erstellt werden: Es existiert bereits eine Dossiervorlage mit demselben Namen.",
|
||||
"generic": "Fehler beim Erstellen der Dossiervorlage."
|
||||
},
|
||||
"form": {
|
||||
"description": "Beschreibung",
|
||||
"description-placeholder": "Beschreibung eingeben",
|
||||
"name": "Name der Dossier-Vorlage",
|
||||
"name-placeholder": "Namen eingeben",
|
||||
"valid-from": "Gültig ab",
|
||||
"valid-to": "Gültig bis"
|
||||
},
|
||||
"save": "Dossier-Vorlage speichern",
|
||||
"title": "{type, select, edit{Dossier-Vorlage {name} bearbeiten} create{Dossier-Vorlage erstellen} clone{} other{}}"
|
||||
},
|
||||
"add-edit-dossier-attribute": {
|
||||
"error": {
|
||||
"generic": "Attribut konnte nicht gespeichert werden!"
|
||||
@ -77,6 +61,22 @@
|
||||
"success": "",
|
||||
"title": ""
|
||||
},
|
||||
"add-edit-dossier-template": {
|
||||
"error": {
|
||||
"conflict": "Dossiervorlage konnte nicht erstellt werden: Es existiert bereits eine Dossiervorlage mit demselben Namen.",
|
||||
"generic": "Fehler beim Erstellen der Dossiervorlage."
|
||||
},
|
||||
"form": {
|
||||
"description": "Beschreibung",
|
||||
"description-placeholder": "Beschreibung eingeben",
|
||||
"name": "Name der Dossier-Vorlage",
|
||||
"name-placeholder": "Namen eingeben",
|
||||
"valid-from": "Gültig ab",
|
||||
"valid-to": "Gültig bis"
|
||||
},
|
||||
"save": "Dossier-Vorlage speichern",
|
||||
"title": "{type, select, edit{Dossier-Vorlage {name} bearbeiten} create{Dossier-Vorlage erstellen} other{}}"
|
||||
},
|
||||
"add-edit-entity": {
|
||||
"error": {
|
||||
"entity-already-exists": "",
|
||||
@ -454,6 +454,19 @@
|
||||
},
|
||||
"header": "Begründung für die Schwärzung bearbeiten"
|
||||
},
|
||||
"clone-dossier-template": {
|
||||
"actions": {
|
||||
"save": ""
|
||||
},
|
||||
"content": {
|
||||
"name": "",
|
||||
"name-placeholder": ""
|
||||
},
|
||||
"error": {
|
||||
"generic": ""
|
||||
},
|
||||
"title": ""
|
||||
},
|
||||
"color": "",
|
||||
"comments": {
|
||||
"add-comment": "Kommentar eingeben",
|
||||
@ -1124,6 +1137,10 @@
|
||||
"label": "Diese Datei wurde gelöscht!"
|
||||
}
|
||||
},
|
||||
"file-preview": {
|
||||
"action": "",
|
||||
"label": ""
|
||||
},
|
||||
"http": {
|
||||
"generic": "Aktion mit Code {status} fehlgeschlagen"
|
||||
},
|
||||
|
||||
@ -36,22 +36,6 @@
|
||||
},
|
||||
"header-new": "Create Dossier"
|
||||
},
|
||||
"add-edit-clone-dossier-template": {
|
||||
"error": {
|
||||
"conflict": "Failed to create dossier template: a dossier template with the same name already exists.",
|
||||
"generic": "Failed to create dossier template."
|
||||
},
|
||||
"form": {
|
||||
"description": "Description",
|
||||
"description-placeholder": "Enter Description",
|
||||
"name": "Dossier Template Name",
|
||||
"name-placeholder": "Enter Name",
|
||||
"valid-from": "Valid from",
|
||||
"valid-to": "Valid to"
|
||||
},
|
||||
"save": "Save Dossier Template",
|
||||
"title": "{type, select, edit{Edit {name}} create{Create} clone{Clone} other{}} Dossier Template"
|
||||
},
|
||||
"add-edit-dossier-attribute": {
|
||||
"error": {
|
||||
"generic": "Failed to save attribute!"
|
||||
@ -77,6 +61,22 @@
|
||||
"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-dossier-template": {
|
||||
"error": {
|
||||
"conflict": "Failed to create dossier template: a dossier template with the same name already exists.",
|
||||
"generic": "Failed to create dossier template."
|
||||
},
|
||||
"form": {
|
||||
"description": "Description",
|
||||
"description-placeholder": "Enter Description",
|
||||
"name": "Dossier Template Name",
|
||||
"name-placeholder": "Enter Name",
|
||||
"valid-from": "Valid from",
|
||||
"valid-to": "Valid to"
|
||||
},
|
||||
"save": "Save Dossier Template",
|
||||
"title": "{type, select, edit{Edit {name}} create{Create} other{}} Dossier Template"
|
||||
},
|
||||
"add-edit-entity": {
|
||||
"error": {
|
||||
"entity-already-exists": "Entity with this name already exists!",
|
||||
@ -454,6 +454,19 @@
|
||||
},
|
||||
"header": "Edit Redaction Reason"
|
||||
},
|
||||
"clone-dossier-template": {
|
||||
"actions": {
|
||||
"save": "Save Dossier Template"
|
||||
},
|
||||
"content": {
|
||||
"name": "Dossier Template Name",
|
||||
"name-placeholder": "Enter Name"
|
||||
},
|
||||
"error": {
|
||||
"generic": "Failed to clone dossier template."
|
||||
},
|
||||
"title": "Clone Dossier Template"
|
||||
},
|
||||
"color": "Color",
|
||||
"comments": {
|
||||
"add-comment": "Enter comment",
|
||||
@ -1026,7 +1039,7 @@
|
||||
"change-successful": "Dossier {dossierName} was updated.",
|
||||
"delete-successful": "Dossier {dossierName} was deleted.",
|
||||
"dictionary": {
|
||||
"add-to-dictionary-action": "Available for add to dictionary",
|
||||
"add-to-dictionary-action": "Enable 'Add to dictionary'",
|
||||
"display-name": {
|
||||
"cancel": "Cancel",
|
||||
"edit": "Edit Display Name",
|
||||
@ -1124,6 +1137,10 @@
|
||||
"label": "This file has been deleted!"
|
||||
}
|
||||
},
|
||||
"file-preview": {
|
||||
"action": "Refresh",
|
||||
"label": "An unknown error occurred. Please refresh the page"
|
||||
},
|
||||
"http": {
|
||||
"generic": "Action failed with code {status}"
|
||||
},
|
||||
|
||||
@ -34,4 +34,5 @@ export interface IRedactionLogEntry {
|
||||
textBefore?: string;
|
||||
type?: string;
|
||||
value?: string;
|
||||
sourceId?: string;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "redaction",
|
||||
"version": "3.440.0",
|
||||
"version": "3.451.0",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
@ -1,14 +1,6 @@
|
||||
@use '../apps/red-ui/src/assets/styles/variables';
|
||||
@use 'mixin';
|
||||
|
||||
.featured-content-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.featured-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.portal-single-publication {
|
||||
background-color: transparent;
|
||||
|
||||
@ -22,7 +14,7 @@
|
||||
}
|
||||
|
||||
.portal-contents {
|
||||
margin-top: 100px;
|
||||
margin-top: 24px;
|
||||
margin-bottom: 0;
|
||||
|
||||
.inner {
|
||||
@ -45,10 +37,6 @@
|
||||
.portal-contents .inner {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.publication-contents:first-child {
|
||||
grid-column: auto;
|
||||
}
|
||||
}
|
||||
|
||||
// Icon Overwrites for sections - change these if sections change!!!
|
||||
|
||||
@ -86,13 +86,8 @@
|
||||
background-color: variables.$white;
|
||||
border-radius: 4px;
|
||||
|
||||
&:first-child {
|
||||
grid-column: 1 / span 2;
|
||||
}
|
||||
|
||||
h4.featured-title,
|
||||
.section-toc-title {
|
||||
@include heading-4;
|
||||
margin: 0;
|
||||
|
||||
a {
|
||||
@ -105,6 +100,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.section-toc-title {
|
||||
@include heading-4;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user