Merge branch 'master' into VM/RED-8748
This commit is contained in:
commit
18ca33e9d2
@ -8,7 +8,6 @@ import { EntitiesListingScreenComponent } from './screens/entities-listing/entit
|
||||
import { DigitalSignatureScreenComponent } from './screens/digital-signature/digital-signature-screen.component';
|
||||
import { UserListingScreenComponent } from './screens/user-listing/user-listing-screen.component';
|
||||
import { DossierTemplateBreadcrumbsComponent } from './shared/components/dossier-template-breadcrumbs/dossier-template-breadcrumbs.component';
|
||||
import { AddEditCloneDossierTemplateDialogComponent } from './dialogs/add-edit-dossier-template-dialog/add-edit-clone-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 { AdminDialogService } from './services/admin-dialog.service';
|
||||
@ -57,9 +56,10 @@ import { DossierTemplateActionsComponent } from './shared/components/dossier-tem
|
||||
import { IqserUsersModule } from '@iqser/common-ui/lib/users';
|
||||
import { SelectComponent } from '@shared/components/select/select.component';
|
||||
import { PaginationComponent } from '@common-ui/pagination/pagination.component';
|
||||
import { AddCloneDossierTemplateDialogComponent } from './dialogs/add-clone-dossier-template-dialog/add-clone-dossier-template-dialog.component';
|
||||
|
||||
const dialogs = [
|
||||
AddEditCloneDossierTemplateDialogComponent,
|
||||
AddCloneDossierTemplateDialogComponent,
|
||||
AddEntityDialogComponent,
|
||||
EditColorDialogComponent,
|
||||
SmtpAuthDialogComponent,
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
<section class="dialog">
|
||||
<div [innerHTML]="'add-clone-dossier-template.title' | translate: translateParams" 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>
|
||||
<input
|
||||
[placeholder]="'add-edit-clone-dossier-template.form.name-placeholder' | translate"
|
||||
formControlName="name"
|
||||
name="name"
|
||||
type="text"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="iqser-input-group w-400">
|
||||
<label [translate]="'add-edit-clone-dossier-template.form.description'"></label>
|
||||
<textarea
|
||||
[placeholder]="'add-edit-clone-dossier-template.form.description-placeholder' | translate"
|
||||
formControlName="description"
|
||||
name="description"
|
||||
rows="4"
|
||||
type="text"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<iqser-icon-button
|
||||
(action)="save()"
|
||||
[buttonId]="'saveButton'"
|
||||
[disabled]="disabled"
|
||||
[label]="'add-clone-dossier-template.save' | translate: translateParams"
|
||||
[type]="iconButtonTypes.primary"
|
||||
></iqser-icon-button>
|
||||
|
||||
<iqser-icon-button
|
||||
(action)="save({ nextAction: true })"
|
||||
[buttonId]="'saveButton'"
|
||||
[disabled]="disabled"
|
||||
[label]="'add-clone-dossier-template.save-and-edit' | translate"
|
||||
[type]="iconButtonTypes.dark"
|
||||
></iqser-icon-button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<iqser-circle-button (action)="close()" class="dialog-close" icon="iqser:close"></iqser-circle-button>
|
||||
</section>
|
||||
@ -0,0 +1,101 @@
|
||||
import { HttpStatusCode } from '@angular/common/http';
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { Validators } from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { BaseDialogComponent, getConfig, SaveOptions } from '@iqser/common-ui';
|
||||
import { DossierTemplate } from '@red/domain';
|
||||
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
export interface CloneTemplateData {
|
||||
dossierTemplateId?: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
templateUrl: './add-clone-dossier-template-dialog.component.html',
|
||||
styleUrls: ['./add-clone-dossier-template-dialog.component.scss'],
|
||||
})
|
||||
export class AddCloneDossierTemplateDialogComponent extends BaseDialogComponent {
|
||||
readonly dossierTemplate?: DossierTemplate;
|
||||
readonly isDocumine = getConfig().IS_DOCUMINE;
|
||||
readonly translateParams: { type: string; dossierTemplateName?: string };
|
||||
|
||||
constructor(
|
||||
private readonly _dossierTemplatesService: DossierTemplatesService,
|
||||
private readonly _router: Router,
|
||||
protected readonly _dialogRef: MatDialogRef<AddCloneDossierTemplateDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) readonly data: CloneTemplateData,
|
||||
) {
|
||||
super(_dialogRef);
|
||||
this.dossierTemplate = this._dossierTemplatesService.find(this.data.dossierTemplateId);
|
||||
|
||||
this.translateParams = {
|
||||
type: this.dossierTemplate ? 'clone' : 'create',
|
||||
dossierTemplateName: this.dossierTemplate?.name,
|
||||
};
|
||||
|
||||
this.form = this.#getForm();
|
||||
this.initialFormValue = this.form.getRawValue();
|
||||
}
|
||||
|
||||
override get disabled(): boolean {
|
||||
// Ignore 'changed' value, doesn't make sense in this context
|
||||
return !this.valid || this._hasErrors();
|
||||
}
|
||||
|
||||
async save(options?: SaveOptions): Promise<void> {
|
||||
let dossierTemplate: DossierTemplate;
|
||||
this._loadingService.start();
|
||||
const body = {
|
||||
...this.dossierTemplate,
|
||||
...this.form.getRawValue(),
|
||||
};
|
||||
try {
|
||||
if (this.dossierTemplate) {
|
||||
dossierTemplate = await this._dossierTemplatesService.clone(this.dossierTemplate.id, body);
|
||||
} else {
|
||||
dossierTemplate = await this._dossierTemplatesService.createOrUpdate(body);
|
||||
}
|
||||
if (options?.nextAction) {
|
||||
await this._router.navigate([dossierTemplate.routerLink]);
|
||||
}
|
||||
this._dialogRef.close(true);
|
||||
} catch (error) {
|
||||
if (error.status === HttpStatusCode.Conflict) {
|
||||
this._toaster.error(_('add-edit-clone-dossier-template.error.conflict'), { error });
|
||||
} else {
|
||||
this._toaster.rawError(error.error.message);
|
||||
}
|
||||
}
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
#getForm() {
|
||||
return this._formBuilder.group({
|
||||
name: [this.dossierTemplate ? this.#getCloneName(this.dossierTemplate) : undefined, Validators.required],
|
||||
description: [this.dossierTemplate?.description],
|
||||
});
|
||||
}
|
||||
|
||||
#getCloneName(initialTemplate: DossierTemplate): string {
|
||||
const templateName = initialTemplate.name.trim();
|
||||
let nameOfClonedTemplate: string = templateName.split('Copy 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] === 'Copy of ' && (splitName[1].trim().match(suffixRegExp) || splitName[1] === '')) {
|
||||
clonesCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (clonesCount >= 1) {
|
||||
return `Copy of ${nameOfClonedTemplate} (${clonesCount})`;
|
||||
}
|
||||
return `Copy of ${nameOfClonedTemplate}`;
|
||||
}
|
||||
}
|
||||
@ -1,159 +0,0 @@
|
||||
<section class="dialog">
|
||||
<div [innerHTML]="'add-edit-clone-dossier-template.title' | translate: translateParams" 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>
|
||||
<input
|
||||
[placeholder]="'add-edit-clone-dossier-template.form.name-placeholder' | translate"
|
||||
formControlName="name"
|
||||
name="name"
|
||||
type="text"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="iqser-input-group w-400">
|
||||
<label [translate]="'add-edit-clone-dossier-template.form.description'"></label>
|
||||
<textarea
|
||||
[placeholder]="'add-edit-clone-dossier-template.form.description-placeholder' | translate"
|
||||
formControlName="description"
|
||||
name="description"
|
||||
rows="4"
|
||||
type="text"
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<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 }}
|
||||
</mat-checkbox>
|
||||
|
||||
<mat-checkbox (change)="toggleHasValid('to')" [checked]="hasValidTo" class="filter-menu-checkbox" color="primary">
|
||||
{{ 'add-edit-clone-dossier-template.form.valid-to' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="iqser-input-group datepicker-wrapper">
|
||||
<ng-container *ngIf="hasValidFrom">
|
||||
<input
|
||||
(dateChange)="applyValidityIntervalConstraints()"
|
||||
[matDatepicker]="fromPicker"
|
||||
formControlName="validFrom"
|
||||
placeholder="dd/mm/yy"
|
||||
/>
|
||||
<mat-datepicker-toggle [for]="fromPicker" matSuffix>
|
||||
<mat-icon matDatepickerToggleIcon svgIcon="iqser:calendar"></mat-icon>
|
||||
</mat-datepicker-toggle>
|
||||
<mat-datepicker #fromPicker></mat-datepicker>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<div class="iqser-input-group datepicker-wrapper">
|
||||
<ng-container *ngIf="hasValidTo">
|
||||
<input
|
||||
(dateChange)="applyValidityIntervalConstraints()"
|
||||
[matDatepicker]="toPicker"
|
||||
formControlName="validTo"
|
||||
placeholder="dd/mm/yy"
|
||||
/>
|
||||
<mat-datepicker-toggle [for]="toPicker" matSuffix>
|
||||
<mat-icon matDatepickerToggleIcon svgIcon="iqser:calendar"></mat-icon>
|
||||
</mat-datepicker-toggle>
|
||||
<mat-datepicker #toPicker></mat-datepicker>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!isDocumine">
|
||||
<p class="heading download-includes">
|
||||
{{ 'add-edit-clone-dossier-template.form.apply-updates-default.heading' | translate }}
|
||||
</p>
|
||||
<div class="iqser-input-group">
|
||||
<mat-checkbox color="primary" formControlName="applyDictionaryUpdatesToAllDossiersByDefault">
|
||||
{{ 'add-edit-clone-dossier-template.form.apply-updates-default.description' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!isDocumine" class="flex">
|
||||
<div class="half-flex-basis">
|
||||
<p class="heading download-includes">{{ 'download-includes' | translate }}</p>
|
||||
|
||||
<div class="flex">
|
||||
<redaction-select
|
||||
[label]="
|
||||
'download-type.label'
|
||||
| translate
|
||||
: {
|
||||
length: form.controls['downloadFileTypes'].value.length
|
||||
}
|
||||
"
|
||||
[options]="downloadTypes"
|
||||
formControlName="downloadFileTypes"
|
||||
></redaction-select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="half-flex-basis w-full pl-75">
|
||||
<p class="heading download-includes">
|
||||
{{ 'add-edit-clone-dossier-template.form.upload-settings.heading' | translate }}
|
||||
</p>
|
||||
<div class="iqser-input-group">
|
||||
<mat-checkbox color="primary" formControlName="ocrByDefault">
|
||||
{{ 'add-edit-clone-dossier-template.form.upload-settings.ocr-by-default' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="iqser-input-group">
|
||||
<mat-checkbox color="primary" formControlName="removeWatermark">
|
||||
{{ 'add-edit-clone-dossier-template.form.upload-settings.remove-watermark' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!isDocumine">
|
||||
<p class="heading download-includes">{{ 'add-edit-clone-dossier-template.form.hidden-text.heading' | translate }}</p>
|
||||
<div class="hidden-elements">
|
||||
<div class="iqser-input-group">
|
||||
<mat-checkbox color="primary" formControlName="keepHiddenText">
|
||||
{{ 'add-edit-clone-dossier-template.form.hidden-text.title' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="info mt-4">{{ 'add-edit-clone-dossier-template.form.hidden-text.description' | translate }}</div>
|
||||
</div>
|
||||
<div class="iqser-input-group">
|
||||
<mat-checkbox color="primary" formControlName="keepImageMetadata">
|
||||
{{ 'add-edit-clone-dossier-template.form.image-metadata.title' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="info mt-4">{{ 'add-edit-clone-dossier-template.form.image-metadata.description' | translate }}</div>
|
||||
</div>
|
||||
<div class="iqser-input-group">
|
||||
<mat-checkbox color="primary" formControlName="keepOverlappingObjects">
|
||||
{{ 'add-edit-clone-dossier-template.form.overlapping-elements.title' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="info mt-4">
|
||||
{{ 'add-edit-clone-dossier-template.form.overlapping-elements.description' | translate }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<iqser-icon-button
|
||||
(action)="save()"
|
||||
[disabled]="disabled"
|
||||
[label]="'add-edit-clone-dossier-template.save' | translate"
|
||||
[type]="iconButtonTypes.primary"
|
||||
[buttonId]="'saveButton'"
|
||||
></iqser-icon-button>
|
||||
|
||||
<iqser-help-button *ngIf="!isDocumine && !!dossierTemplate"></iqser-help-button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<iqser-circle-button (action)="close()" class="dialog-close" icon="iqser:close"></iqser-circle-button>
|
||||
</section>
|
||||
@ -1,58 +0,0 @@
|
||||
.validity {
|
||||
width: 230px;
|
||||
display: flex;
|
||||
|
||||
> div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: 16px;
|
||||
|
||||
mat-checkbox {
|
||||
margin-right: 16px;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
min-height: 42px;
|
||||
}
|
||||
|
||||
.iqser-input-group {
|
||||
min-height: 42px;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
redaction-select {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.download-includes {
|
||||
margin: 16px 0 10px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.hidden-elements {
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
|
||||
.iqser-input-group {
|
||||
margin-top: 0;
|
||||
flex: 1;
|
||||
|
||||
mat-checkbox {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.info {
|
||||
margin-left: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.half-flex-basis {
|
||||
flex-basis: 50%;
|
||||
}
|
||||
|
||||
.pl-75 {
|
||||
padding: 0 0 0 75px;
|
||||
}
|
||||
@ -1,173 +0,0 @@
|
||||
import { HttpStatusCode } from '@angular/common/http';
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { AbstractControl, Validators } from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { BaseDialogComponent, getConfig } from '@iqser/common-ui';
|
||||
import { DossierTemplate, IDossierTemplate } from '@red/domain';
|
||||
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
|
||||
import { downloadTypesTranslations } from '@translations/download-types-translations';
|
||||
import { applyIntervalConstraints } from '@utils/date-inputs-utils';
|
||||
import dayjs, { Dayjs } from 'dayjs';
|
||||
|
||||
interface EditCloneTemplateData {
|
||||
dossierTemplateId: string;
|
||||
clone?: boolean;
|
||||
}
|
||||
|
||||
const downloadTypes = ['ORIGINAL', 'PREVIEW', 'DELTA_PREVIEW', 'REDACTED'].map(type => ({
|
||||
key: type,
|
||||
label: downloadTypesTranslations[type],
|
||||
}));
|
||||
|
||||
@Component({
|
||||
templateUrl: './add-edit-clone-dossier-template-dialog.component.html',
|
||||
styleUrls: ['./add-edit-clone-dossier-template-dialog.component.scss'],
|
||||
})
|
||||
export class AddEditCloneDossierTemplateDialogComponent extends BaseDialogComponent {
|
||||
readonly isDocumine = getConfig().IS_DOCUMINE;
|
||||
hasValidFrom: boolean;
|
||||
hasValidTo: boolean;
|
||||
readonly downloadTypes = downloadTypes;
|
||||
readonly dossierTemplate: DossierTemplate;
|
||||
private _previousValidFrom: Dayjs;
|
||||
private _previousValidTo: Dayjs;
|
||||
private _lastValidFrom: Dayjs;
|
||||
private _lastValidTo: Dayjs;
|
||||
|
||||
get disabled(): boolean {
|
||||
if (!this.data?.clone) {
|
||||
return super.disabled;
|
||||
}
|
||||
return !this.valid;
|
||||
}
|
||||
|
||||
get translateParams() {
|
||||
return {
|
||||
type: this.dossierTemplate ? (this.data.clone ? 'clone' : 'edit') : 'create',
|
||||
name: this.dossierTemplate?.name,
|
||||
};
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly _dossierTemplatesService: DossierTemplatesService,
|
||||
protected readonly _dialogRef: MatDialogRef<AddEditCloneDossierTemplateDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) readonly data: EditCloneTemplateData,
|
||||
) {
|
||||
super(_dialogRef, !!data && !data.clone);
|
||||
this.dossierTemplate = this._dossierTemplatesService.find(this.data?.dossierTemplateId);
|
||||
this.form = this.#getForm();
|
||||
this.initialFormValue = this.form.getRawValue();
|
||||
this.hasValidFrom = !!this.dossierTemplate?.validFrom;
|
||||
this.hasValidTo = !!this.dossierTemplate?.validTo;
|
||||
|
||||
this._previousValidFrom = this._lastValidFrom = this.form.get('validFrom').value;
|
||||
this._previousValidTo = this._lastValidTo = this.form.get('validTo').value;
|
||||
}
|
||||
|
||||
toggleHasValid(extremity: string) {
|
||||
if (extremity === 'from') {
|
||||
this.hasValidFrom = !this.hasValidFrom;
|
||||
this.form.controls['validFrom'].setValue(this.hasValidFrom ? this._lastValidFrom : null);
|
||||
} else {
|
||||
this.hasValidTo = !this.hasValidTo;
|
||||
this.form.controls['validTo'].setValue(this.hasValidTo ? this._lastValidTo : null);
|
||||
}
|
||||
this.applyValidityIntervalConstraints();
|
||||
}
|
||||
|
||||
async save() {
|
||||
this._loadingService.start();
|
||||
const dossierTemplate = {
|
||||
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;
|
||||
|
||||
try {
|
||||
if (this.data?.clone) {
|
||||
await this._dossierTemplatesService.clone(this.dossierTemplate.id, dossierTemplate);
|
||||
} else {
|
||||
await this._dossierTemplatesService.createOrUpdate(dossierTemplate);
|
||||
}
|
||||
this._dialogRef.close(true);
|
||||
} catch (error) {
|
||||
if (error.status === HttpStatusCode.Conflict) {
|
||||
this._toaster.error(_('add-edit-clone-dossier-template.error.conflict'), { error });
|
||||
} else {
|
||||
this._toaster.rawError(error.error.message);
|
||||
}
|
||||
}
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
applyValidityIntervalConstraints(): void {
|
||||
const formValue = this.form.value;
|
||||
applyIntervalConstraints(formValue, this._previousValidFrom, this._previousValidTo, this.form, 'validFrom', 'validTo');
|
||||
|
||||
this._previousValidFrom = this.form.get('validFrom').value;
|
||||
this._previousValidTo = this.form.get('validTo').value;
|
||||
this._lastValidFrom = this._previousValidFrom || this._lastValidFrom;
|
||||
this._lastValidTo = this._previousValidTo || this._lastValidTo;
|
||||
}
|
||||
|
||||
#getForm() {
|
||||
return this._formBuilder.group({
|
||||
name: [this.#getCloneName(), Validators.required],
|
||||
description: [this.dossierTemplate?.description],
|
||||
validFrom: [
|
||||
this.dossierTemplate?.validFrom ? dayjs(this.dossierTemplate?.validFrom) : null,
|
||||
this.#requiredIfValidator(() => this.hasValidFrom),
|
||||
],
|
||||
validTo: [
|
||||
this.dossierTemplate?.validTo ? dayjs(this.dossierTemplate?.validTo) : null,
|
||||
this.#requiredIfValidator(() => this.hasValidTo),
|
||||
],
|
||||
applyDictionaryUpdatesToAllDossiersByDefault: [this.dossierTemplate?.applyDictionaryUpdatesToAllDossiersByDefault],
|
||||
ocrByDefault: [this.dossierTemplate?.ocrByDefault],
|
||||
removeWatermark: [this.dossierTemplate?.removeWatermark],
|
||||
downloadFileTypes: [this.dossierTemplate?.downloadFileTypes || ['PREVIEW', 'REDACTED']],
|
||||
keepHiddenText: [this.dossierTemplate?.keepHiddenText],
|
||||
keepImageMetadata: [this.dossierTemplate?.keepImageMetadata],
|
||||
keepOverlappingObjects: [this.dossierTemplate?.keepOverlappingObjects],
|
||||
});
|
||||
}
|
||||
|
||||
#getCloneName(): string {
|
||||
if (!this.data?.clone) {
|
||||
return this.dossierTemplate?.name;
|
||||
}
|
||||
|
||||
const templateName = this.dossierTemplate.name.trim();
|
||||
let nameOfClonedTemplate: string = templateName.split('Copy 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] === 'Copy of ' && (splitName[1].trim().match(suffixRegExp) || splitName[1] === '')) {
|
||||
clonesCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (clonesCount >= 1) {
|
||||
return `Copy of ${nameOfClonedTemplate} (${clonesCount})`;
|
||||
}
|
||||
return `Copy of ${nameOfClonedTemplate}`;
|
||||
}
|
||||
|
||||
#requiredIfValidator(predicate) {
|
||||
return (formControl: AbstractControl) => {
|
||||
if (!formControl.parent) {
|
||||
return null;
|
||||
}
|
||||
if (predicate()) {
|
||||
return Validators.required(formControl);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -63,7 +63,7 @@ export class DossierTemplatesListingScreenComponent extends ListingComponent<Dos
|
||||
}
|
||||
|
||||
openAddDossierTemplateDialog() {
|
||||
this._dialogService.openDialog('addEditCloneDossierTemplate');
|
||||
this._dialogService.openDialog('addCloneDossierTemplate', {});
|
||||
}
|
||||
|
||||
private async _deleteTemplates(templateIds = this.listingService.selected.map(d => d.dossierTemplateId)) {
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
<div *ngIf="componentContext$ | async as ctx">
|
||||
<ng-container *ngIf="ctx.dossierTemplate && ctx.stats">
|
||||
<div class="heading-xl mb-24">{{ ctx.dossierTemplate.name }}</div>
|
||||
|
||||
<div class="info-wrapper">
|
||||
<div class="created-by-wrapper">
|
||||
<div [translate]="'dossier-template-info-screen.created-by'" class="all-caps-label mb-8"></div>
|
||||
|
||||
<iqser-initials-avatar
|
||||
[user]="ctx.dossierTemplate.createdBy || 'system'"
|
||||
[withName]="true"
|
||||
size="large"
|
||||
></iqser-initials-avatar>
|
||||
</div>
|
||||
|
||||
<div class="small-label stats-subtitle mt-0">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:status"></mat-icon>
|
||||
{{ translations[ctx.dossierTemplate.dossierTemplateStatus] | translate }}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<mat-icon svgIcon="red:dictionary"></mat-icon>
|
||||
{{ 'dossier-template-info-screen.entities' | translate: { count: ctx.stats.numberOfDictionaries } }}
|
||||
</div>
|
||||
|
||||
<div *ngIf="ctx.dossierTemplate.validFrom && ctx.dossierTemplate.validFrom | date: 'd MMM yyyy' as validFrom">
|
||||
<mat-icon svgIcon="iqser:calendar"></mat-icon>
|
||||
<span [innerHTML]="'dossier-template-info-screen.valid-from' | translate: { date: validFrom }"></span>
|
||||
</div>
|
||||
|
||||
<div *ngIf="ctx.dossierTemplate.dateAdded | date: 'd MMM yyyy' as createdOn">
|
||||
<mat-icon svgIcon="iqser:calendar"></mat-icon>
|
||||
<span [innerHTML]="'dossier-template-info-screen.created-on' | translate: { date: createdOn }"></span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<mat-icon svgIcon="red:entries"></mat-icon>
|
||||
{{ 'dossier-template-info-screen.entries' | translate: { count: ctx.stats.numberOfEntries } }}
|
||||
</div>
|
||||
|
||||
<div *ngIf="ctx.dossierTemplate.validTo && ctx.dossierTemplate.validTo | date: 'd MMM yyyy' as validTo">
|
||||
<mat-icon svgIcon="iqser:calendar"></mat-icon>
|
||||
<span [innerHTML]="'dossier-template-info-screen.valid-to' | translate: { date: validTo }"></span>
|
||||
</div>
|
||||
|
||||
<div *ngIf="ctx.dossierTemplate.dateModified | date: 'd MMM yyyy' as dateModified">
|
||||
<mat-icon svgIcon="iqser:calendar"></mat-icon>
|
||||
<span [innerHTML]="'dossier-template-info-screen.modified-on' | translate: { date: dateModified }"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
@ -0,0 +1,20 @@
|
||||
@use 'common-mixins';
|
||||
|
||||
.stats-subtitle {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, max-content);
|
||||
grid-row-gap: 8px;
|
||||
grid-column-gap: 8px;
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
.info-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.created-by-wrapper {
|
||||
border-right: 1px solid var(--iqser-separator);
|
||||
padding-right: 24px;
|
||||
margin-right: 24px;
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { ContextComponent } from '@iqser/common-ui/lib/utils';
|
||||
import { type DossierTemplate, type DossierTemplateStats } from '@red/domain';
|
||||
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
|
||||
import { DossierTemplateStatsService } from '@services/entity-services/dossier-template-stats.service';
|
||||
import { dossierTemplateStatusTranslations } from '@translations/dossier-template-status-translations';
|
||||
|
||||
interface Context {
|
||||
readonly dossierTemplate: DossierTemplate;
|
||||
readonly stats: DossierTemplateStats;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-dossier-template-details',
|
||||
templateUrl: './dossier-template-details.component.html',
|
||||
styleUrls: ['./dossier-template-details.component.scss'],
|
||||
})
|
||||
export class DossierTemplateDetailsComponent extends ContextComponent<Context> implements OnInit {
|
||||
readonly translations = dossierTemplateStatusTranslations;
|
||||
|
||||
@Input({ required: true }) dossierTemplateId: string;
|
||||
|
||||
constructor(
|
||||
private readonly _dossierTemplatesService: DossierTemplatesService,
|
||||
private readonly _dossierTemplateStatsService: DossierTemplateStatsService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
super._initContext({
|
||||
dossierTemplate: this._dossierTemplatesService.getEntityChanged$(this.dossierTemplateId),
|
||||
stats: this._dossierTemplateStatsService.watch$(this.dossierTemplateId),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,150 @@
|
||||
<div class="content-container" iqserHasScrollbar>
|
||||
<form [formGroup]="form" class="dialog">
|
||||
<div class="dialog-content">
|
||||
<redaction-dossier-template-details [dossierTemplateId]="dossierTemplateId"></redaction-dossier-template-details>
|
||||
|
||||
<div class="heading-md mt-24 mb-8" translate="dossier-template-info-screen.title"></div>
|
||||
|
||||
<div class="iqser-input-group required w-300">
|
||||
<label [translate]="'add-edit-clone-dossier-template.form.name'"></label>
|
||||
<input
|
||||
[placeholder]="'add-edit-clone-dossier-template.form.name-placeholder' | translate"
|
||||
formControlName="name"
|
||||
name="name"
|
||||
type="text"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="iqser-input-group w-full">
|
||||
<label [translate]="'add-edit-clone-dossier-template.form.description'"></label>
|
||||
<textarea
|
||||
[placeholder]="'add-edit-clone-dossier-template.form.description-placeholder' | translate"
|
||||
formControlName="description"
|
||||
name="description"
|
||||
rows="4"
|
||||
type="text"
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<div class="validity mt-12">
|
||||
<div>
|
||||
<mat-checkbox (change)="toggleHasValid('from')" [checked]="hasValidFrom()" color="primary">
|
||||
{{ 'add-edit-clone-dossier-template.form.valid-from' | translate }}
|
||||
</mat-checkbox>
|
||||
|
||||
<div class="iqser-input-group datepicker-wrapper">
|
||||
<ng-container *ngIf="hasValidFrom()">
|
||||
<input
|
||||
(dateChange)="applyValidityIntervalConstraints()"
|
||||
[matDatepicker]="fromPicker"
|
||||
formControlName="validFrom"
|
||||
placeholder="dd/mm/yy"
|
||||
/>
|
||||
<mat-datepicker-toggle [for]="fromPicker" matSuffix>
|
||||
<mat-icon matDatepickerToggleIcon svgIcon="iqser:calendar"></mat-icon>
|
||||
</mat-datepicker-toggle>
|
||||
<mat-datepicker #fromPicker></mat-datepicker>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<mat-checkbox (change)="toggleHasValid('to')" [checked]="hasValidTo()" color="primary">
|
||||
{{ 'add-edit-clone-dossier-template.form.valid-to' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="iqser-input-group datepicker-wrapper">
|
||||
<ng-container *ngIf="hasValidTo()">
|
||||
<input
|
||||
(dateChange)="applyValidityIntervalConstraints()"
|
||||
[matDatepicker]="toPicker"
|
||||
formControlName="validTo"
|
||||
placeholder="dd/mm/yy"
|
||||
/>
|
||||
<mat-datepicker-toggle [for]="toPicker" matSuffix>
|
||||
<mat-icon matDatepickerToggleIcon svgIcon="iqser:calendar"></mat-icon>
|
||||
</mat-datepicker-toggle>
|
||||
<mat-datepicker #toPicker></mat-datepicker>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!isDocumine" class="mt-24">
|
||||
<div class="heading">
|
||||
{{ 'add-edit-clone-dossier-template.form.apply-updates-default.heading' | translate }}
|
||||
</div>
|
||||
<div class="iqser-input-group">
|
||||
<mat-checkbox color="primary" formControlName="applyDictionaryUpdatesToAllDossiersByDefault">
|
||||
{{ 'add-edit-clone-dossier-template.form.apply-updates-default.description' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-24">
|
||||
<div class="heading mb-14">{{ 'download-includes' | translate }}</div>
|
||||
|
||||
<redaction-select
|
||||
[label]="
|
||||
'download-type.label'
|
||||
| translate
|
||||
: {
|
||||
length: form.controls['downloadFileTypes'].value.length
|
||||
}
|
||||
"
|
||||
[options]="downloadTypes"
|
||||
formControlName="downloadFileTypes"
|
||||
></redaction-select>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!isDocumine" class="mt-24">
|
||||
<div class="heading">
|
||||
{{ 'add-edit-clone-dossier-template.form.upload-settings.heading' | translate }}
|
||||
</div>
|
||||
<div class="iqser-input-group">
|
||||
<mat-checkbox color="primary" formControlName="ocrByDefault">
|
||||
{{ 'add-edit-clone-dossier-template.form.upload-settings.ocr-by-default' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div class="iqser-input-group">
|
||||
<mat-checkbox color="primary" formControlName="removeWatermark">
|
||||
{{ 'add-edit-clone-dossier-template.form.upload-settings.remove-watermark' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!isDocumine" class="mt-24 hidden-elements">
|
||||
<div class="heading">{{ 'add-edit-clone-dossier-template.form.hidden-text.heading' | translate }}</div>
|
||||
<div class="iqser-input-group">
|
||||
<mat-checkbox color="primary" formControlName="keepHiddenText">
|
||||
{{ 'add-edit-clone-dossier-template.form.hidden-text.title' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="info">{{ 'add-edit-clone-dossier-template.form.hidden-text.description' | translate }}</div>
|
||||
</div>
|
||||
<div class="iqser-input-group">
|
||||
<mat-checkbox color="primary" formControlName="keepImageMetadata">
|
||||
{{ 'add-edit-clone-dossier-template.form.image-metadata.title' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="info">{{ 'add-edit-clone-dossier-template.form.image-metadata.description' | translate }}</div>
|
||||
</div>
|
||||
<div class="iqser-input-group">
|
||||
<mat-checkbox color="primary" formControlName="keepOverlappingObjects">
|
||||
{{ 'add-edit-clone-dossier-template.form.overlapping-elements.title' | translate }}
|
||||
</mat-checkbox>
|
||||
<div class="info">
|
||||
{{ 'add-edit-clone-dossier-template.form.overlapping-elements.description' | translate }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<iqser-icon-button
|
||||
(action)="save()"
|
||||
[buttonId]="'saveButton'"
|
||||
[disabled]="disabled"
|
||||
[label]="'add-edit-clone-dossier-template.save' | translate"
|
||||
[type]="iconButtonTypes.primary"
|
||||
></iqser-icon-button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@ -1,25 +1,13 @@
|
||||
@use 'common-mixins';
|
||||
|
||||
:host {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.content-container {
|
||||
flex: 1;
|
||||
padding: 30px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background-color: var(--iqser-alt-background);
|
||||
overflow: auto;
|
||||
@include common-mixins.scroll-bar;
|
||||
}
|
||||
|
||||
.heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 40px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.stats-subtitle {
|
||||
margin-top: 16px;
|
||||
display: grid;
|
||||
@ -28,6 +16,23 @@
|
||||
grid-column-gap: 40px;
|
||||
}
|
||||
|
||||
.template-description {
|
||||
margin-top: 10px;
|
||||
.validity {
|
||||
display: flex;
|
||||
min-height: 42px;
|
||||
gap: 40px;
|
||||
|
||||
> div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
redaction-select {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.hidden-elements .info {
|
||||
margin-left: 24px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
@ -0,0 +1,139 @@
|
||||
import { Component, OnInit, signal, untracked, WritableSignal } from '@angular/core';
|
||||
import { BaseFormComponent, getConfig, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
|
||||
import { getParam } from '@iqser/common-ui/lib/utils';
|
||||
import { DOSSIER_TEMPLATE_ID, type DossierTemplate, IDossierTemplate } from '@red/domain';
|
||||
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
|
||||
import { dossierTemplateStatusTranslations } from '@translations/dossier-template-status-translations';
|
||||
import dayjs, { Dayjs } from 'dayjs';
|
||||
import { HttpStatusCode } from '@angular/common/http';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { applyIntervalConstraints } from '@utils/date-inputs-utils';
|
||||
import { AbstractControl, UntypedFormBuilder, Validators } from '@angular/forms';
|
||||
import { downloadTypesTranslations } from '@translations/download-types-translations';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
const downloadTypes = ['ORIGINAL', 'PREVIEW', 'DELTA_PREVIEW', 'REDACTED'].map(type => ({
|
||||
key: type,
|
||||
label: downloadTypesTranslations[type],
|
||||
}));
|
||||
|
||||
@Component({
|
||||
templateUrl: './dossier-template-info-screen.component.html',
|
||||
styleUrls: ['./dossier-template-info-screen.component.scss'],
|
||||
})
|
||||
export class DossierTemplateInfoScreenComponent extends BaseFormComponent implements OnInit {
|
||||
readonly translations = dossierTemplateStatusTranslations;
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly isDocumine = getConfig().IS_DOCUMINE;
|
||||
readonly downloadTypes = downloadTypes;
|
||||
|
||||
readonly dossierTemplate$: Observable<DossierTemplate>;
|
||||
readonly dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
|
||||
readonly hasValidFrom: WritableSignal<boolean>;
|
||||
readonly hasValidTo: WritableSignal<boolean>;
|
||||
private _previousValidFrom: Dayjs;
|
||||
private _previousValidTo: Dayjs;
|
||||
private _lastValidFrom: Dayjs;
|
||||
private _lastValidTo: Dayjs;
|
||||
|
||||
constructor(
|
||||
private readonly _dossierTemplatesService: DossierTemplatesService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _toaster: Toaster,
|
||||
private readonly _formBuilder: UntypedFormBuilder,
|
||||
) {
|
||||
super();
|
||||
this.dossierTemplate$ = this._dossierTemplatesService.get(this.dossierTemplateId);
|
||||
this.form = this.#getForm(this._dossierTemplatesService.find(this.dossierTemplateId));
|
||||
this.initialFormValue = this.form.getRawValue();
|
||||
|
||||
this.hasValidFrom = signal(!!this.form.get('validFrom').value);
|
||||
this.hasValidTo = signal(!!this.form.get('validTo').value);
|
||||
|
||||
this._previousValidFrom = this._lastValidFrom = this.form.get('validFrom').value;
|
||||
this._previousValidTo = this._lastValidTo = this.form.get('validTo').value;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
toggleHasValid(extremity: 'from' | 'to') {
|
||||
if (extremity === 'from') {
|
||||
const prevValue = untracked(this.hasValidFrom);
|
||||
this.hasValidFrom.set(!prevValue);
|
||||
this.form.controls['validFrom'].setValue(!prevValue ? this._lastValidFrom : null);
|
||||
} else {
|
||||
const prevValue = untracked(this.hasValidTo);
|
||||
this.hasValidTo.set(!prevValue);
|
||||
this.form.controls['validTo'].setValue(!prevValue ? this._lastValidTo : null);
|
||||
}
|
||||
this.applyValidityIntervalConstraints();
|
||||
}
|
||||
|
||||
async save() {
|
||||
this._loadingService.start();
|
||||
const dossierTemplate = {
|
||||
dossierTemplateId: this.dossierTemplateId,
|
||||
...this.form.getRawValue(),
|
||||
validFrom: this.hasValidFrom() ? this.form.get('validFrom').value : null,
|
||||
validTo: this.hasValidTo() ? this.form.get('validTo').value : null,
|
||||
} as IDossierTemplate;
|
||||
|
||||
try {
|
||||
await this._dossierTemplatesService.createOrUpdate(dossierTemplate);
|
||||
this.initialFormValue = this.form.getRawValue();
|
||||
} catch (error) {
|
||||
if (error.status === HttpStatusCode.Conflict) {
|
||||
this._toaster.error(_('add-edit-clone-dossier-template.error.conflict'), { error });
|
||||
} else {
|
||||
this._toaster.rawError(error.error.message);
|
||||
}
|
||||
}
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
applyValidityIntervalConstraints(): void {
|
||||
const formValue = this.form.value;
|
||||
applyIntervalConstraints(formValue, this._previousValidFrom, this._previousValidTo, this.form, 'validFrom', 'validTo');
|
||||
|
||||
this._previousValidFrom = this.form.get('validFrom').value;
|
||||
this._previousValidTo = this.form.get('validTo').value;
|
||||
this._lastValidFrom = this._previousValidFrom || this._lastValidFrom;
|
||||
this._lastValidTo = this._previousValidTo || this._lastValidTo;
|
||||
}
|
||||
|
||||
#getForm(dossierTemplate: DossierTemplate) {
|
||||
return this._formBuilder.group({
|
||||
name: [dossierTemplate.name, Validators.required],
|
||||
description: [dossierTemplate?.description],
|
||||
validFrom: [
|
||||
dossierTemplate?.validFrom ? dayjs(dossierTemplate?.validFrom) : null,
|
||||
this.#requiredIfValidator(() => this.hasValidFrom()),
|
||||
],
|
||||
validTo: [
|
||||
dossierTemplate?.validTo ? dayjs(dossierTemplate?.validTo) : null,
|
||||
this.#requiredIfValidator(() => this.hasValidTo()),
|
||||
],
|
||||
applyDictionaryUpdatesToAllDossiersByDefault: [dossierTemplate?.applyDictionaryUpdatesToAllDossiersByDefault],
|
||||
ocrByDefault: [dossierTemplate?.ocrByDefault],
|
||||
removeWatermark: [dossierTemplate?.removeWatermark],
|
||||
downloadFileTypes: [dossierTemplate?.downloadFileTypes || ['PREVIEW', 'REDACTED']],
|
||||
keepHiddenText: [dossierTemplate?.keepHiddenText],
|
||||
keepImageMetadata: [dossierTemplate?.keepImageMetadata],
|
||||
keepOverlappingObjects: [dossierTemplate?.keepOverlappingObjects],
|
||||
});
|
||||
}
|
||||
|
||||
#requiredIfValidator(predicate: () => boolean) {
|
||||
return (formControl: AbstractControl) => {
|
||||
if (!formControl.parent) {
|
||||
return null;
|
||||
}
|
||||
if (predicate()) {
|
||||
return Validators.required(formControl);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,16 +1,18 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { DossierTemplateInfoScreenComponent } from './info-screen/dossier-template-info-screen.component';
|
||||
import { DossierTemplateInfoScreenComponent } from './dossier-template-info-screen/dossier-template-info-screen.component';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { SharedModule } from '@shared/shared.module';
|
||||
import { HasScrollbarDirective, IqserHelpModeModule } from '@iqser/common-ui';
|
||||
import { CircleButtonComponent, HasScrollbarDirective, IconButtonComponent, IqserHelpModeModule } from '@iqser/common-ui';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { IqserUsersModule } from '@iqser/common-ui/lib/users';
|
||||
import { SelectComponent } from '@shared/components/select/select.component';
|
||||
import { DossierTemplateDetailsComponent } from './dossier-template-details/dossier-template-details.component';
|
||||
|
||||
const routes = [{ path: '', component: DossierTemplateInfoScreenComponent }];
|
||||
|
||||
@NgModule({
|
||||
declarations: [DossierTemplateInfoScreenComponent],
|
||||
declarations: [DossierTemplateInfoScreenComponent, DossierTemplateDetailsComponent],
|
||||
imports: [
|
||||
RouterModule.forChild(routes),
|
||||
CommonModule,
|
||||
@ -19,6 +21,9 @@ const routes = [{ path: '', component: DossierTemplateInfoScreenComponent }];
|
||||
TranslateModule,
|
||||
IqserHelpModeModule,
|
||||
HasScrollbarDirective,
|
||||
CircleButtonComponent,
|
||||
IconButtonComponent,
|
||||
SelectComponent,
|
||||
],
|
||||
})
|
||||
export class DossierTemplateInfoModule {}
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
<div *ngIf="componentContext$ | async as ctx" class="content-container" iqserHasScrollbar>
|
||||
<div class="heading-xl">{{ ctx.dossierTemplate.name }}</div>
|
||||
|
||||
<div [translate]="'dossier-template-info-screen.created-by'" class="all-caps-label mt-24 mb-8"></div>
|
||||
|
||||
<iqser-initials-avatar [user]="ctx.dossierTemplate.createdBy || 'system'" [withName]="true" size="large"></iqser-initials-avatar>
|
||||
|
||||
<div class="small-label stats-subtitle">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:status"></mat-icon>
|
||||
{{ translations[ctx.dossierTemplate.dossierTemplateStatus] | translate }}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<mat-icon svgIcon="red:dictionary"></mat-icon>
|
||||
{{ 'dossier-template-info-screen.entities' | translate : { count: ctx.stats.numberOfDictionaries } }}
|
||||
</div>
|
||||
|
||||
<div *ngIf="ctx.dossierTemplate.validTo && ctx.dossierTemplate.validFrom | date : 'd MMM yyyy' as validFrom">
|
||||
<mat-icon svgIcon="iqser:calendar"></mat-icon>
|
||||
<span [innerHTML]="'dossier-template-info-screen.valid-from' | translate : { date: validFrom }"></span>
|
||||
</div>
|
||||
|
||||
<div *ngIf="ctx.dossierTemplate.dateAdded | date : 'd MMM yyyy' as createdOn">
|
||||
<mat-icon svgIcon="iqser:calendar"></mat-icon>
|
||||
<span [innerHTML]="'dossier-template-info-screen.created-on' | translate : { date: createdOn }"></span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<mat-icon svgIcon="red:entries"></mat-icon>
|
||||
{{ 'dossier-template-info-screen.entries' | translate : { count: ctx.stats.numberOfEntries } }}
|
||||
</div>
|
||||
|
||||
<div *ngIf="ctx.dossierTemplate.validFrom && ctx.dossierTemplate.validTo | date : 'd MMM yyyy' as validTo">
|
||||
<mat-icon svgIcon="iqser:calendar"></mat-icon>
|
||||
<span [innerHTML]="'dossier-template-info-screen.valid-to' | translate : { date: validTo }"></span>
|
||||
</div>
|
||||
|
||||
<div *ngIf="ctx.dossierTemplate.dateModified | date : 'd MMM yyyy' as dateModified">
|
||||
<mat-icon svgIcon="iqser:calendar"></mat-icon>
|
||||
<span [innerHTML]="'dossier-template-info-screen.modified-on' | translate : { date: dateModified }"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="template-description">{{ ctx.dossierTemplate.description }}</div>
|
||||
</div>
|
||||
@ -1,34 +0,0 @@
|
||||
import { Component, inject, OnInit } from '@angular/core';
|
||||
import { LoadingService } from '@iqser/common-ui';
|
||||
import { ContextComponent, getParam } from '@iqser/common-ui/lib/utils';
|
||||
import { DOSSIER_TEMPLATE_ID, type DossierTemplate, type DossierTemplateStats } from '@red/domain';
|
||||
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
|
||||
import { DossierTemplateStatsService } from '@services/entity-services/dossier-template-stats.service';
|
||||
import { dossierTemplateStatusTranslations } from '@translations/dossier-template-status-translations';
|
||||
|
||||
interface Context {
|
||||
readonly dossierTemplate: DossierTemplate;
|
||||
readonly stats: DossierTemplateStats;
|
||||
}
|
||||
|
||||
@Component({
|
||||
templateUrl: './dossier-template-info-screen.component.html',
|
||||
styleUrls: ['./dossier-template-info-screen.component.scss'],
|
||||
})
|
||||
export class DossierTemplateInfoScreenComponent extends ContextComponent<Context> implements OnInit {
|
||||
readonly #loadingService = inject(LoadingService);
|
||||
readonly translations = dossierTemplateStatusTranslations;
|
||||
|
||||
constructor(dossierTemplatesService: DossierTemplatesService, dossierTemplateStatsService: DossierTemplateStatsService) {
|
||||
super();
|
||||
const dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
|
||||
super._initContext({
|
||||
dossierTemplate: dossierTemplatesService.getEntityChanged$(dossierTemplateId),
|
||||
stats: dossierTemplateStatsService.watch$(dossierTemplateId),
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.#loadingService.stop();
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
import { Injectable, TemplateRef } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { AddEntityDialogComponent } from '../dialogs/add-entity-dialog/add-entity-dialog.component';
|
||||
import { AddEditCloneDossierTemplateDialogComponent } from '../dialogs/add-edit-dossier-template-dialog/add-edit-clone-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';
|
||||
@ -23,6 +22,7 @@ import { IDossierAttributeConfig, IFileAttributeConfig, IReportTemplate } from '
|
||||
import { ReportTemplateService } from '@services/report-template.service';
|
||||
import { ConfigureCertificateDialogComponent } from '../dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component';
|
||||
import { AuditInfoDialogComponent } from '../dialogs/audit-info-dialog/audit-info-dialog.component';
|
||||
import { AddCloneDossierTemplateDialogComponent } from '../dialogs/add-clone-dossier-template-dialog/add-clone-dossier-template-dialog.component';
|
||||
|
||||
type DialogType =
|
||||
| 'confirm'
|
||||
@ -30,7 +30,7 @@ type DialogType =
|
||||
| 'editColor'
|
||||
| 'addEditUser'
|
||||
| 'smtpAuthConfig'
|
||||
| 'addEditCloneDossierTemplate'
|
||||
| 'addCloneDossierTemplate'
|
||||
| 'auditInfo'
|
||||
| 'uploadDictionary'
|
||||
| 'configureCertificate';
|
||||
@ -58,9 +58,9 @@ export class AdminDialogService extends DialogService<DialogType> {
|
||||
component: SmtpAuthDialogComponent,
|
||||
dialogConfig: { autoFocus: true },
|
||||
},
|
||||
addEditCloneDossierTemplate: {
|
||||
component: AddEditCloneDossierTemplateDialogComponent,
|
||||
dialogConfig: { width: '950px', autoFocus: true },
|
||||
addCloneDossierTemplate: {
|
||||
component: AddCloneDossierTemplateDialogComponent,
|
||||
dialogConfig: { autoFocus: true },
|
||||
},
|
||||
uploadDictionary: {
|
||||
component: UploadDictionaryDialogComponent,
|
||||
|
||||
@ -8,15 +8,15 @@
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="openEditCloneDossierTemplateDialog(true)"
|
||||
(action)="openCloneDossierTemplateDialog()"
|
||||
[buttonId]="'copy-dossier-template-btn'"
|
||||
[tooltip]="'dossier-templates-listing.action.clone' | translate"
|
||||
icon="iqser:copy"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="openEditCloneDossierTemplateDialog()"
|
||||
[buttonId]="'edit-dossier-template-btn'"
|
||||
[routerLink]="dossierTemplate.routerLink"
|
||||
[tooltip]="'dossier-templates-listing.action.edit' | translate"
|
||||
icon="iqser:edit"
|
||||
></iqser-circle-button>
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { NgIf } from '@angular/common';
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
|
||||
import { CircleButtonComponent, IqserHelpModeModule, LoadingService } from '@iqser/common-ui';
|
||||
import { getCurrentUser } from '@iqser/common-ui/lib/users';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { DOSSIER_TEMPLATE_ID, type User } from '@red/domain';
|
||||
import { DOSSIER_TEMPLATE_ID, DossierTemplate, type User } from '@red/domain';
|
||||
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { AdminDialogService } from '../../../services/admin-dialog.service';
|
||||
@ -14,12 +14,13 @@ import { AdminDialogService } from '../../../services/admin-dialog.service';
|
||||
templateUrl: './dossier-template-actions.component.html',
|
||||
styleUrls: ['./dossier-template-actions.component.scss'],
|
||||
standalone: true,
|
||||
imports: [NgIf, IqserHelpModeModule, CircleButtonComponent, TranslateModule],
|
||||
imports: [NgIf, IqserHelpModeModule, CircleButtonComponent, TranslateModule, RouterLink],
|
||||
})
|
||||
export class DossierTemplateActionsComponent implements OnInit {
|
||||
@Input() dossierTemplateId: string;
|
||||
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
dossierTemplate: DossierTemplate;
|
||||
|
||||
constructor(
|
||||
private readonly _router: Router,
|
||||
@ -31,10 +32,11 @@ export class DossierTemplateActionsComponent implements OnInit {
|
||||
|
||||
ngOnInit() {
|
||||
this.dossierTemplateId ??= this._route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID);
|
||||
this.dossierTemplate = this._dossierTemplatesService.find(this.dossierTemplateId);
|
||||
}
|
||||
|
||||
openEditCloneDossierTemplateDialog(clone: boolean = false) {
|
||||
this._dialogService.openDialog('addEditCloneDossierTemplate', { dossierTemplateId: this.dossierTemplateId, clone });
|
||||
openCloneDossierTemplateDialog() {
|
||||
this._dialogService.openDialog('addCloneDossierTemplate', { dossierTemplateId: this.dossierTemplateId });
|
||||
}
|
||||
|
||||
openDeleteDossierTemplateDialog() {
|
||||
|
||||
@ -105,9 +105,9 @@ export class REDDocumentViewer {
|
||||
this.#pdf.instance.UI.setAnnotationContentOverlayHandler(() => (current ? undefined : false));
|
||||
}
|
||||
|
||||
init(document: DocumentViewer) {
|
||||
init(document: DocumentViewer, zOrderFlag: number) {
|
||||
this.#document = document;
|
||||
this.#listenForDocEvents();
|
||||
this.#listenForDocEvents(zOrderFlag);
|
||||
this.keyUp$ = this.#keyUp$;
|
||||
}
|
||||
|
||||
@ -160,7 +160,7 @@ export class REDDocumentViewer {
|
||||
}
|
||||
}
|
||||
|
||||
#listenForDocEvents() {
|
||||
#listenForDocEvents(zOrderFlag: number) {
|
||||
this.#document.addEventListener('textSelected', (quads: Quad, selectedText: string, pageNumber: number) => {
|
||||
this.selectedText$.next(selectedText);
|
||||
this.#disableTextPopupIfCompareMode(pageNumber);
|
||||
@ -180,6 +180,8 @@ export class REDDocumentViewer {
|
||||
this.#document.addEventListener('documentLoaded', () => {
|
||||
this.#logger.info('[PDF] Document loaded');
|
||||
|
||||
this.document.setTextExtractorProcessingFlags([zOrderFlag]);
|
||||
|
||||
this.#pdf.runWithCleanup(() => {
|
||||
this.#flattenAnnotations().then();
|
||||
this.#setCurrentPage();
|
||||
|
||||
@ -35,7 +35,7 @@ export function webViewerLoadedGuard(): CanActivateFn | ResolveFn<boolean> {
|
||||
}
|
||||
|
||||
annotationManager.init(instance.Core.annotationManager);
|
||||
documentViewer.init(instance.Core.documentViewer);
|
||||
documentViewer.init(instance.Core.documentViewer, instance.Core.TextExtractorProcessingFlags.EXTRACT_USING_ZORDER);
|
||||
viewerHeaderService.init();
|
||||
|
||||
return !!pdf.instance;
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
<section *ngIf="dossier$ | async as dossier" class="dialog">
|
||||
<section class="dialog">
|
||||
<div
|
||||
[innerHTML]="'edit-dossier-dialog.header' | translate: { dossierName: dossier.dossierName }"
|
||||
[innerHTML]="'edit-dossier-dialog.header' | translate: { dossierName: dossier().dossierName }"
|
||||
class="dialog-header heading-l"
|
||||
id="editDossierHeader"
|
||||
></div>
|
||||
|
||||
<div class="dialog-content">
|
||||
<iqser-side-nav [title]="'edit-dossier-dialog.side-nav-title' | translate">
|
||||
<div *ngFor="let item of navItems">
|
||||
<div *ngFor="let item of navItems()">
|
||||
<div
|
||||
*ngIf="!item.hide"
|
||||
(click)="changeTab(item.key)"
|
||||
[class.active]="item.key === activeNav"
|
||||
*ngIf="!item.hide"
|
||||
[attr.help-mode-key]="item.helpModeKey"
|
||||
[class.active]="item.key === activeNav()"
|
||||
class="item"
|
||||
>
|
||||
{{ item.sideNavTitle || item.title | translate }}
|
||||
@ -22,46 +22,46 @@
|
||||
</iqser-side-nav>
|
||||
|
||||
<div>
|
||||
<div [class.no-actions]="!showActionButtons" [class.no-padding]="noPaddingTab" class="content">
|
||||
<div *ngIf="showHeading" class="heading">
|
||||
{{ activeNavItem.title | translate }}
|
||||
<div [class.no-actions]="!showActionButtons()" [class.no-padding]="noPaddingTab()" class="content">
|
||||
<div *ngIf="showHeading()" class="heading">
|
||||
{{ activeNavItem().title | translate }}
|
||||
</div>
|
||||
|
||||
<div *ngIf="activeNavItem.readonly" class="read-only-indicator all-caps-label primary">
|
||||
<div *ngIf="activeNavItem().readonly" class="read-only-indicator all-caps-label primary">
|
||||
<mat-icon class="mr-8" svgIcon="red:read-only"></mat-icon>
|
||||
{{ 'readonly' | translate }}
|
||||
</div>
|
||||
|
||||
<redaction-edit-dossier-general-info
|
||||
*ngIf="activeNav === 'dossierInfo'"
|
||||
[dossier]="dossier"
|
||||
*ngIf="activeNav() === 'dossierInfo'"
|
||||
[dossier]="dossier()"
|
||||
></redaction-edit-dossier-general-info>
|
||||
|
||||
<redaction-edit-dossier-download-package
|
||||
*ngIf="activeNav === 'downloadPackage'"
|
||||
[dossier]="dossier"
|
||||
*ngIf="activeNav() === 'downloadPackage'"
|
||||
[dossier]="dossier()"
|
||||
></redaction-edit-dossier-download-package>
|
||||
|
||||
<redaction-edit-dossier-dictionary
|
||||
*ngIf="activeNav === 'dossierDictionary'"
|
||||
[dossier]="dossier"
|
||||
*ngIf="activeNav() === 'dossierDictionary'"
|
||||
[dossier]="dossier()"
|
||||
></redaction-edit-dossier-dictionary>
|
||||
|
||||
<redaction-edit-dossier-team *ngIf="activeNav === 'members'" [dossier]="dossier"></redaction-edit-dossier-team>
|
||||
<redaction-edit-dossier-team *ngIf="activeNav() === 'members'" [dossier]="dossier()"></redaction-edit-dossier-team>
|
||||
|
||||
<redaction-edit-dossier-attributes
|
||||
*ngIf="activeNav === 'dossierAttributes'"
|
||||
[dossier]="dossier"
|
||||
*ngIf="activeNav() === 'dossierAttributes'"
|
||||
[dossier]="dossier()"
|
||||
></redaction-edit-dossier-attributes>
|
||||
</div>
|
||||
|
||||
<div *ngIf="showActionButtons" class="dialog-actions">
|
||||
<iqser-icon-button
|
||||
(action)="save()"
|
||||
[buttonId]="'saveButton'"
|
||||
[disabled]="disabled || !valid || !changed"
|
||||
[label]="'edit-dossier-dialog.actions.save' | translate"
|
||||
[type]="iconButtonTypes.primary"
|
||||
[buttonId]="'saveButton'"
|
||||
></iqser-icon-button>
|
||||
|
||||
<iqser-icon-button
|
||||
|
||||
@ -1,22 +1,20 @@
|
||||
import { AfterViewInit, Component, Inject, ViewChild } from '@angular/core';
|
||||
import { AfterViewInit, Component, computed, Inject, Signal, signal, untracked, ViewChild, WritableSignal } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { Dossier, User } from '@red/domain';
|
||||
import { Dossier } from '@red/domain';
|
||||
import { EditDossierGeneralInfoComponent } from './general-info/edit-dossier-general-info.component';
|
||||
import { EditDossierDownloadPackageComponent } from './download-package/edit-dossier-download-package.component';
|
||||
import { EditDossierSectionInterface } from './edit-dossier-section.interface';
|
||||
import { BaseDialogComponent, ConfirmOptions, IconButtonTypes, IqserPermissionsService, SaveOptions } from '@iqser/common-ui';
|
||||
import { BaseDialogComponent, ConfirmOptions, IconButtonTypes, SaveOptions } from '@iqser/common-ui';
|
||||
import { EditDossierDictionaryComponent } from './dictionary/edit-dossier-dictionary.component';
|
||||
import { EditDossierAttributesComponent } from './attributes/edit-dossier-attributes.component';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { Observable } from 'rxjs';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { EditDossierTeamComponent } from './edit-dossier-team/edit-dossier-team.component';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { DossiersService } from '@services/dossiers/dossiers.service';
|
||||
import { dossiersServiceProvider } from '@services/entity-services/dossiers.service.provider';
|
||||
import { Roles } from '@users/roles';
|
||||
import { getCurrentUser } from '@iqser/common-ui/lib/users';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
|
||||
type Section = 'dossierInfo' | 'downloadPackage' | 'dossierDictionary' | 'members' | 'dossierAttributes';
|
||||
|
||||
@ -36,20 +34,24 @@ interface NavItem {
|
||||
})
|
||||
export class EditDossierDialogComponent extends BaseDialogComponent implements AfterViewInit {
|
||||
readonly roles = Roles;
|
||||
navItems: NavItem[] = [];
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
activeNav: Section;
|
||||
readonly dossier$: Observable<Dossier>;
|
||||
|
||||
readonly activeNav: WritableSignal<Section>;
|
||||
readonly dossier: Signal<Dossier>;
|
||||
readonly navItems: Signal<NavItem[]>;
|
||||
readonly activeNavItem: Signal<NavItem>;
|
||||
readonly activeComponent: Signal<EditDossierSectionInterface>;
|
||||
readonly noPaddingTab: Signal<boolean>;
|
||||
readonly showHeading: Signal<boolean>;
|
||||
readonly showActionButtons: Signal<boolean>;
|
||||
|
||||
@ViewChild(EditDossierGeneralInfoComponent) generalInfoComponent: EditDossierGeneralInfoComponent;
|
||||
@ViewChild(EditDossierDownloadPackageComponent) downloadPackageComponent: EditDossierDownloadPackageComponent;
|
||||
@ViewChild(EditDossierDictionaryComponent) dictionaryComponent: EditDossierDictionaryComponent;
|
||||
@ViewChild(EditDossierTeamComponent) membersComponent: EditDossierTeamComponent;
|
||||
@ViewChild(EditDossierAttributesComponent) attributesComponent: EditDossierAttributesComponent;
|
||||
readonly #currentUser = getCurrentUser<User>();
|
||||
#dossier: Dossier;
|
||||
|
||||
constructor(
|
||||
readonly iqserPermissionsService: IqserPermissionsService,
|
||||
private readonly _dossiersService: DossiersService,
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
protected readonly _dialogRef: MatDialogRef<EditDossierDialogComponent>,
|
||||
@ -61,72 +63,43 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A
|
||||
readonly configService: ConfigService,
|
||||
) {
|
||||
super(_dialogRef, true);
|
||||
this.dossier$ = this._dossiersService.getEntityChanged$(this._data.dossierId).pipe(
|
||||
tap(dossier => {
|
||||
this.#dossier = dossier;
|
||||
this._initializeNavItems();
|
||||
}),
|
||||
);
|
||||
this.activeNav = this._data.section || 'dossierInfo';
|
||||
}
|
||||
|
||||
get activeNavItem(): NavItem {
|
||||
return this.navItems.find(item => item.key === this.activeNav);
|
||||
}
|
||||
|
||||
get activeComponent(): EditDossierSectionInterface {
|
||||
return {
|
||||
dossierInfo: this.generalInfoComponent,
|
||||
downloadPackage: this.downloadPackageComponent,
|
||||
dossierDictionary: this.dictionaryComponent,
|
||||
members: this.membersComponent,
|
||||
dossierAttributes: this.attributesComponent,
|
||||
}[this.activeNav];
|
||||
}
|
||||
|
||||
get noPaddingTab(): boolean {
|
||||
return ['dossierAttributes', 'dossierDictionary'].includes(this.activeNav);
|
||||
}
|
||||
|
||||
get showHeading(): boolean {
|
||||
return !['dossierAttributes', 'dossierDictionary'].includes(this.activeNav);
|
||||
}
|
||||
|
||||
get showActionButtons(): boolean {
|
||||
return (
|
||||
(['dossierDictionary'].includes(this.activeNav) && this._permissionsService.canEditDossierDictionary(this.#dossier)) ||
|
||||
(['members'].includes(this.activeNav) &&
|
||||
this.#currentUser.isManager &&
|
||||
this.iqserPermissionsService.has(Roles.dossiers.edit)) ||
|
||||
this._permissionsService.canEditDossier(this.#dossier)
|
||||
);
|
||||
this.dossier = toSignal(this._dossiersService.getEntityChanged$(this._data.dossierId));
|
||||
this.navItems = computed(() => this._getNavItems(this.dossier()));
|
||||
this.activeNav = signal(this._data.section || 'dossierInfo');
|
||||
this.activeNavItem = computed(() => this.navItems().find(item => item.key === this.activeNav()));
|
||||
this.activeComponent = computed(() => this._getActiveComponent(this.activeNav()));
|
||||
this.noPaddingTab = computed(() => ['dossierAttributes', 'dossierDictionary'].includes(this.activeNav()));
|
||||
this.showHeading = computed(() => !['dossierAttributes', 'dossierDictionary'].includes(this.activeNav()));
|
||||
this.showActionButtons = computed(() => !this.activeNavItem().readonly);
|
||||
}
|
||||
|
||||
get changed(): boolean {
|
||||
return this.activeComponent?.changed;
|
||||
return this.activeComponent()?.changed;
|
||||
}
|
||||
|
||||
get valid(): boolean {
|
||||
return this.activeComponent?.valid;
|
||||
return this.activeComponent()?.valid;
|
||||
}
|
||||
|
||||
get disabled(): boolean {
|
||||
return this.activeComponent?.disabled;
|
||||
return this.activeComponent()?.disabled;
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
if (!this.#dossier.ownerId) {
|
||||
if (!untracked(this.dossier).ownerId) {
|
||||
this._toaster.error(_('edit-dossier-dialog.missing-owner'));
|
||||
}
|
||||
}
|
||||
|
||||
async save(options?: SaveOptions) {
|
||||
this._loadingService.start();
|
||||
const result = await this.activeComponent.save();
|
||||
const result = await untracked(this.activeComponent).save();
|
||||
this._loadingService.stop();
|
||||
|
||||
if (result.success) {
|
||||
this._toaster.success(_('edit-dossier-dialog.change-successful'), { params: { dossierName: this.#dossier.dossierName } });
|
||||
this._toaster.success(_('edit-dossier-dialog.change-successful'), {
|
||||
params: { dossierName: untracked(this.dossier).dossierName },
|
||||
});
|
||||
}
|
||||
|
||||
if (result.success && options?.closeAfterSave) {
|
||||
@ -135,7 +108,7 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A
|
||||
}
|
||||
|
||||
revert() {
|
||||
this.activeComponent.revert();
|
||||
untracked(this.activeComponent).revert();
|
||||
}
|
||||
|
||||
changeTab(key: Section) {
|
||||
@ -146,34 +119,44 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A
|
||||
} else {
|
||||
this.revert();
|
||||
}
|
||||
this.activeNav = key;
|
||||
this.activeNav.set(key);
|
||||
});
|
||||
} else {
|
||||
this.activeNav = key;
|
||||
this.activeNav.set(key);
|
||||
}
|
||||
}
|
||||
|
||||
private _initializeNavItems(): void {
|
||||
this.navItems = [
|
||||
private _getActiveComponent(section: Section): EditDossierSectionInterface {
|
||||
return {
|
||||
dossierInfo: this.generalInfoComponent,
|
||||
downloadPackage: this.downloadPackageComponent,
|
||||
dossierDictionary: this.dictionaryComponent,
|
||||
members: this.membersComponent,
|
||||
dossierAttributes: this.attributesComponent,
|
||||
}[section];
|
||||
}
|
||||
|
||||
private _getNavItems(dossier: Dossier): NavItem[] {
|
||||
return [
|
||||
{
|
||||
key: 'dossierInfo',
|
||||
title: _('edit-dossier-dialog.nav-items.general-info'),
|
||||
sideNavTitle: _('edit-dossier-dialog.nav-items.dossier-info'),
|
||||
readonly: !this.#dossier.isActive || !this._permissionsService.canEditDossier(this.#dossier),
|
||||
readonly: !this._permissionsService.canEditDossier(dossier),
|
||||
helpModeKey: 'edit_dossier_dossier_info_DIALOG',
|
||||
},
|
||||
{
|
||||
key: 'downloadPackage',
|
||||
title: _('edit-dossier-dialog.nav-items.choose-download'),
|
||||
sideNavTitle: _('edit-dossier-dialog.nav-items.download-package'),
|
||||
readonly: !this._permissionsService.canEditDossier(this.#dossier),
|
||||
readonly: !this._permissionsService.canEditDossier(dossier),
|
||||
helpModeKey: 'edit_dossier_download_package_DIALOG',
|
||||
},
|
||||
{
|
||||
key: 'dossierDictionary',
|
||||
sideNavTitle: _('edit-dossier-dialog.nav-items.dictionary'),
|
||||
title: _('edit-dossier-dialog.nav-items.dossier-dictionary'),
|
||||
readonly: !this._permissionsService.canEditDossierDictionary(this.#dossier),
|
||||
readonly: !this._permissionsService.canEditDossierDictionary(dossier),
|
||||
helpModeKey: 'edit_dossier_dossier_dictionary_DIALOG',
|
||||
hide: this.configService.values.IS_DOCUMINE,
|
||||
},
|
||||
@ -181,13 +164,13 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A
|
||||
key: 'members',
|
||||
title: _('edit-dossier-dialog.nav-items.team-members'),
|
||||
sideNavTitle: _('edit-dossier-dialog.nav-items.members'),
|
||||
readonly: !this._permissionsService.canEditTeamMembers(this.#dossier),
|
||||
readonly: !this._permissionsService.canEditTeamMembers(dossier),
|
||||
helpModeKey: 'edit_dossier_members_DIALOG',
|
||||
},
|
||||
{
|
||||
key: 'dossierAttributes',
|
||||
title: _('edit-dossier-dialog.nav-items.dossier-attributes'),
|
||||
readonly: !this._permissionsService.canEditDossierAttributes(this.#dossier),
|
||||
readonly: !this._permissionsService.canEditDossierAttributes(dossier),
|
||||
helpModeKey: 'edit_dossier_dossier_attributes_DIALOG',
|
||||
},
|
||||
];
|
||||
|
||||
@ -106,14 +106,14 @@
|
||||
<div class="dialog-actions">
|
||||
<iqser-icon-button
|
||||
(action)="save()"
|
||||
[buttonId]="'saveButton'"
|
||||
[disabled]="disabled"
|
||||
[label]="'add-dossier-dialog.actions.save' | translate"
|
||||
[type]="iconButtonTypes.primary"
|
||||
[buttonId]="'saveButton'"
|
||||
></iqser-icon-button>
|
||||
|
||||
<iqser-icon-button
|
||||
(action)="save({ addMembers: true })"
|
||||
(action)="save({ nextAction: true })"
|
||||
[buttonId]="'createDossierEditTeamButton'"
|
||||
[disabled]="disabled"
|
||||
[label]="'add-dossier-dialog.actions.save-and-add-members' | translate"
|
||||
|
||||
@ -79,7 +79,7 @@ export class AddDossierDialogComponent extends BaseDialogComponent implements On
|
||||
const savedDossier = await firstValueFrom(this._activeDossiersService.createOrUpdate(this.#formToObject()));
|
||||
if (savedDossier) {
|
||||
await this._router.navigate([savedDossier.routerLink]);
|
||||
if (options?.addMembers) {
|
||||
if (options?.nextAction) {
|
||||
this._dialogService.openDialog('editDossier', {
|
||||
dossierId: savedDossier.id,
|
||||
section: 'members',
|
||||
|
||||
@ -70,13 +70,15 @@ export class DossierTemplatesService extends EntitiesService<IDossierTemplate, D
|
||||
}
|
||||
|
||||
async createOrUpdate(body: IDossierTemplate) {
|
||||
await firstValueFrom(this._post(body));
|
||||
return await firstValueFrom(this.loadAll());
|
||||
const dossierTemplate = await firstValueFrom(this._post(body));
|
||||
await firstValueFrom(this.loadAll());
|
||||
return this.find(dossierTemplate.dossierTemplateId);
|
||||
}
|
||||
|
||||
async clone(dossierTemplateId: string, body: IDossierTemplate) {
|
||||
await firstValueFrom(this._post(body, `${this._defaultModelPath}/${dossierTemplateId}/clone`));
|
||||
return await firstValueFrom(this.loadAll());
|
||||
const dossierTemplate = await firstValueFrom(this._post(body, `${this._defaultModelPath}/${dossierTemplateId}/clone`));
|
||||
await firstValueFrom(this.loadAll());
|
||||
return this.find(dossierTemplate.dossierTemplateId);
|
||||
}
|
||||
|
||||
refreshDossierTemplate(dossierTemplateId: string): Observable<any> {
|
||||
|
||||
@ -302,7 +302,14 @@ export class PermissionsService {
|
||||
}
|
||||
|
||||
canEditDossier(dossier: Dossier): boolean {
|
||||
return this._iqserPermissionsService.has(Roles.dossiers.edit) && this.isManager() && !!dossier?.ownerId;
|
||||
const dossierTemplate = this._dossierTemplatesService.find(dossier.dossierTemplateId);
|
||||
return (
|
||||
this._iqserPermissionsService.has(Roles.dossiers.edit) &&
|
||||
this.isManager() &&
|
||||
!!dossier?.ownerId &&
|
||||
dossier.isActive &&
|
||||
dossierTemplate.isActive
|
||||
);
|
||||
}
|
||||
|
||||
canEditDossierDictionary(dossier: Dossier): boolean {
|
||||
|
||||
@ -26,6 +26,11 @@
|
||||
"title": "Add annotation"
|
||||
}
|
||||
},
|
||||
"add-clone-dossier-template": {
|
||||
"save": "",
|
||||
"save-and-edit": "",
|
||||
"title": ""
|
||||
},
|
||||
"add-dossier-dialog": {
|
||||
"actions": {
|
||||
"save": "Speichern",
|
||||
@ -87,8 +92,7 @@
|
||||
"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{}}"
|
||||
"save": "Dossier-Vorlage speichern"
|
||||
},
|
||||
"add-edit-dossier-attribute": {
|
||||
"error": {
|
||||
@ -1020,6 +1024,7 @@
|
||||
"entities": "{count} {count, plural, one{entity} other{entities}}",
|
||||
"entries": "{count} {count, plural, one{entry} other{entries}}",
|
||||
"modified-on": "Modified on: {date}",
|
||||
"title": "",
|
||||
"valid-from": "Valid from: {date}",
|
||||
"valid-to": "Valid to: {date}"
|
||||
},
|
||||
@ -1645,7 +1650,7 @@
|
||||
"clicking-anywhere-on": "<b>Klicken Sie auf eine beliebige Stelle des Bildschirms </b> um zu sehen, welche Bereiche interaktiv sind. Wenn Sie mit der Maus über einen interaktiven Bereich fahren, <b>verändert sich der Mauszeiger</b>, um Ihnen zu zeigen, ob ein Element interaktiv ist.",
|
||||
"instructions": "Hilfe-Modus-Anleitungen öffnen",
|
||||
"options": {
|
||||
"do-not-show-again": ""
|
||||
"do-not-show-again": "Do not show again"
|
||||
},
|
||||
"welcome-to-help-mode": "<b> Willkommen im Hilfe-Modus! <br> Klicken Sie auf interaktive Elemente, um in einem neuen Tab Infos dazu zu erhalten. </b>"
|
||||
},
|
||||
@ -1970,7 +1975,7 @@
|
||||
},
|
||||
"form": {
|
||||
"auto-expand-filters-on-action": "Auto-expand filters on my actions",
|
||||
"help-mode-dialog": "",
|
||||
"help-mode-dialog": "Help Mode Dialog",
|
||||
"load-all-annotations-warning": "Warning regarding loading all annotations at once in file preview",
|
||||
"open-structured-view-by-default": "Display structured component management modal by default",
|
||||
"table-extraction-type": "Table extraction type"
|
||||
@ -1979,8 +1984,7 @@
|
||||
"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-label": "Prompts and dialogs",
|
||||
"warnings-subtitle": "Do not show again options",
|
||||
"warnings-title": "Prompts and dialogs settings"
|
||||
"warnings-subtitle": "Do not show again options"
|
||||
},
|
||||
"processing-status": {
|
||||
"ocr": "OCR",
|
||||
@ -2267,6 +2271,9 @@
|
||||
},
|
||||
"title": "Authentifizierung aktivieren"
|
||||
},
|
||||
"table-header": {
|
||||
"selected-count": ""
|
||||
},
|
||||
"tenant-resolve": {
|
||||
"contact-administrator": "Cannot remember the workspace? <b>Please contact your administrator.</b>",
|
||||
"header": {
|
||||
|
||||
@ -26,6 +26,11 @@
|
||||
"title": "Add annotation"
|
||||
}
|
||||
},
|
||||
"add-clone-dossier-template": {
|
||||
"save": "{type, select, clone{Clone} other{Save}}",
|
||||
"save-and-edit": "{type, select, clone{Clone} other{Save}} and edit",
|
||||
"title": "{type, select, clone{Clone {dossierTemplateName}} other{Create dossier template}}"
|
||||
},
|
||||
"add-dossier-dialog": {
|
||||
"actions": {
|
||||
"save": "Save",
|
||||
@ -87,8 +92,7 @@
|
||||
"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"
|
||||
"save": "Save dossier template"
|
||||
},
|
||||
"add-edit-dossier-attribute": {
|
||||
"error": {
|
||||
@ -1021,6 +1025,7 @@
|
||||
"entities": "{count} {count, plural, one{entity} other{entities}}",
|
||||
"entries": "{count} {count, plural, one{entry} other{entries}}",
|
||||
"modified-on": "Modified on: {date}",
|
||||
"title": "Edit dossier template",
|
||||
"valid-from": "Valid from: {date}",
|
||||
"valid-to": "Valid to: {date}"
|
||||
},
|
||||
@ -1980,8 +1985,7 @@
|
||||
"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-label": "Prompts and dialogs",
|
||||
"warnings-subtitle": "Do not show again options",
|
||||
"warnings-title": "Prompts and dialogs settings"
|
||||
"warnings-subtitle": "Do not show again options"
|
||||
},
|
||||
"processing-status": {
|
||||
"ocr": "OCR",
|
||||
@ -2268,6 +2272,9 @@
|
||||
},
|
||||
"title": "Enable authentication"
|
||||
},
|
||||
"table-header": {
|
||||
"selected-count": "{count} selected"
|
||||
},
|
||||
"tenant-resolve": {
|
||||
"contact-administrator": "Cannot remember the workspace? <b>Please contact your administrator.</b>",
|
||||
"header": {
|
||||
|
||||
@ -26,6 +26,11 @@
|
||||
"title": "Add annotation"
|
||||
}
|
||||
},
|
||||
"add-clone-dossier-template": {
|
||||
"save": "",
|
||||
"save-and-edit": "",
|
||||
"title": ""
|
||||
},
|
||||
"add-dossier-dialog": {
|
||||
"actions": {
|
||||
"save": "Speichern",
|
||||
@ -87,8 +92,7 @@
|
||||
"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{}}"
|
||||
"save": "Dossier-Vorlage speichern"
|
||||
},
|
||||
"add-edit-dossier-attribute": {
|
||||
"error": {
|
||||
@ -1020,6 +1024,7 @@
|
||||
"entities": "{count} {count, plural, one{entity} other{entities}}",
|
||||
"entries": "{count} {count, plural, one{entry} other{entries}}",
|
||||
"modified-on": "Modified on: {date}",
|
||||
"title": "",
|
||||
"valid-from": "Valid from: {date}",
|
||||
"valid-to": "Valid to: {date}"
|
||||
},
|
||||
@ -1645,7 +1650,7 @@
|
||||
"clicking-anywhere-on": "<b>Klicken Sie auf eine beliebige Stelle des Bildschirms </b> um zu sehen, welche Bereiche interaktiv sind. Wenn Sie mit der Maus über einen interaktiven Bereich fahren, <b>verändert sich der Mauszeiger</b>, um Ihnen zu zeigen, ob ein Element interaktiv ist.",
|
||||
"instructions": "Hilfe-Modus-Anleitungen öffnen",
|
||||
"options": {
|
||||
"do-not-show-again": ""
|
||||
"do-not-show-again": "Do not show again"
|
||||
},
|
||||
"welcome-to-help-mode": "<b> Willkommen im Hilfe-Modus! <br> Klicken Sie auf interaktive Elemente, um in einem neuen Tab Infos dazu zu erhalten. </b>"
|
||||
},
|
||||
@ -1970,7 +1975,7 @@
|
||||
},
|
||||
"form": {
|
||||
"auto-expand-filters-on-action": "Auto expand filters on my actions",
|
||||
"help-mode-dialog": "",
|
||||
"help-mode-dialog": "Help Mode Dialog",
|
||||
"load-all-annotations-warning": "Warning regarding loading all annotations at once in file preview",
|
||||
"open-structured-view-by-default": "Display Component View by default when opening a document",
|
||||
"table-extraction-type": "Table extraction type"
|
||||
@ -1979,8 +1984,7 @@
|
||||
"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-label": "Prompts and dialogs",
|
||||
"warnings-subtitle": "Do not show again options",
|
||||
"warnings-title": "Prompts and dialogs settings"
|
||||
"warnings-subtitle": "Do not show again options"
|
||||
},
|
||||
"processing-status": {
|
||||
"ocr": "OCR",
|
||||
@ -2267,6 +2271,9 @@
|
||||
},
|
||||
"title": "Authentifizierung aktivieren"
|
||||
},
|
||||
"table-header": {
|
||||
"selected-count": ""
|
||||
},
|
||||
"tenant-resolve": {
|
||||
"contact-administrator": "Cannot remember the workspace? <b>Please contact your administrator.</b>",
|
||||
"header": {
|
||||
|
||||
@ -26,6 +26,11 @@
|
||||
"title": "Add annotation"
|
||||
}
|
||||
},
|
||||
"add-clone-dossier-template": {
|
||||
"save": "{type, select, clone{Clone} other{Save}}",
|
||||
"save-and-edit": "{type, select, clone{Clone} other{Save}} and edit",
|
||||
"title": "{type, select, clone{Clone {dossierTemplateName}} other{Create dossier template}}"
|
||||
},
|
||||
"add-dossier-dialog": {
|
||||
"actions": {
|
||||
"save": "Save",
|
||||
@ -87,8 +92,7 @@
|
||||
"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"
|
||||
"save": "Save dossier template"
|
||||
},
|
||||
"add-edit-dossier-attribute": {
|
||||
"error": {
|
||||
@ -1021,6 +1025,7 @@
|
||||
"entities": "{count} {count, plural, one{entity} other{entities}}",
|
||||
"entries": "{count} {count, plural, one{entry} other{entries}}",
|
||||
"modified-on": "Modified on: {date}",
|
||||
"title": "Edit dossier template",
|
||||
"valid-from": "Valid from: {date}",
|
||||
"valid-to": "Valid to: {date}"
|
||||
},
|
||||
@ -1980,8 +1985,7 @@
|
||||
"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-label": "Prompts and dialogs",
|
||||
"warnings-subtitle": "Do not show again options",
|
||||
"warnings-title": "Prompts and dialogs settings"
|
||||
"warnings-subtitle": "Do not show again options"
|
||||
},
|
||||
"processing-status": {
|
||||
"ocr": "OCR",
|
||||
@ -2268,6 +2272,9 @@
|
||||
},
|
||||
"title": "Enable authentication"
|
||||
},
|
||||
"table-header": {
|
||||
"selected-count": "{count} selected"
|
||||
},
|
||||
"tenant-resolve": {
|
||||
"contact-administrator": "Cannot remember the workspace? <b>Please contact your administrator.</b>",
|
||||
"header": {
|
||||
|
||||
@ -60,8 +60,4 @@ export class DossierTemplate implements IDossierTemplate, IListable {
|
||||
get routerLink(): string {
|
||||
return `/main/admin/dossier-templates/${this.dossierTemplateId}`;
|
||||
}
|
||||
|
||||
get dossiersRouterLink(): string {
|
||||
return `/main/${this.dossierTemplateId}/dossiers`;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user