RED-5546: fix escaped html
This commit is contained in:
parent
076382c32a
commit
df25dd7522
@ -1,12 +1,5 @@
|
||||
<section class="dialog">
|
||||
<div
|
||||
[translateParams]="{
|
||||
name: dossierAttribute?.label,
|
||||
type: dossierAttribute ? 'edit' : 'create'
|
||||
}"
|
||||
[translate]="'add-edit-dossier-attribute.title'"
|
||||
class="dialog-header heading-l"
|
||||
></div>
|
||||
<div [innerHTML]="'add-edit-dossier-attribute.title' | translate : titleTranslateParams" class="dialog-header heading-l"></div>
|
||||
|
||||
<form [formGroup]="form">
|
||||
<div class="dialog-content">
|
||||
|
||||
@ -8,19 +8,27 @@ import { DossierAttributesService } from '@services/entity-services/dossier-attr
|
||||
import { dossierAttributeTypesTranslations } from '@translations/dossier-attribute-types-translations';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
|
||||
export interface AddEditDossierAttributeDialogData {
|
||||
readonly dossierAttribute: IDossierAttributeConfig;
|
||||
dossierTemplateId: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
templateUrl: './add-edit-dossier-attribute-dialog.component.html',
|
||||
})
|
||||
export class AddEditDossierAttributeDialogComponent extends BaseDialogComponent implements OnDestroy {
|
||||
dossierAttribute: IDossierAttributeConfig = this.data.dossierAttribute;
|
||||
readonly dossierAttribute = this.data.dossierAttribute;
|
||||
readonly translations = dossierAttributeTypesTranslations;
|
||||
readonly typeOptions = Object.keys(DossierAttributeConfigTypes);
|
||||
readonly titleTranslateParams = {
|
||||
name: this.data.dossierAttribute?.label,
|
||||
type: this.data.dossierAttribute ? 'edit' : 'create',
|
||||
};
|
||||
|
||||
constructor(
|
||||
private readonly _dossierAttributesService: DossierAttributesService,
|
||||
protected readonly _dialogRef: MatDialogRef<AddEditDossierAttributeDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA)
|
||||
readonly data: { readonly dossierAttribute: IDossierAttributeConfig; dossierTemplateId: string },
|
||||
@Inject(MAT_DIALOG_DATA) readonly data: AddEditDossierAttributeDialogData,
|
||||
) {
|
||||
super(_dialogRef, !!data.dossierAttribute);
|
||||
this.form = this._getForm(this.dossierAttribute);
|
||||
@ -41,7 +49,7 @@ export class AddEditDossierAttributeDialogComponent extends BaseDialogComponent
|
||||
return false;
|
||||
}
|
||||
|
||||
save() {
|
||||
async save() {
|
||||
this._loadingService.start();
|
||||
|
||||
const attribute: IDossierAttributeConfig = {
|
||||
@ -50,22 +58,23 @@ export class AddEditDossierAttributeDialogComponent extends BaseDialogComponent
|
||||
...this.form.getRawValue(),
|
||||
};
|
||||
|
||||
this._dossierAttributesService.createOrUpdate(attribute, this.data.dossierTemplateId).subscribe(
|
||||
() => {
|
||||
this._dialogRef.close(true);
|
||||
},
|
||||
(error: HttpErrorResponse) => {
|
||||
this._loadingService.stop();
|
||||
this._toaster.error(_('add-edit-dossier-attribute.error.generic'), { error });
|
||||
},
|
||||
);
|
||||
const createOrUpdate = this._dossierAttributesService.createOrUpdate(attribute, this.data.dossierTemplateId);
|
||||
const result = await createOrUpdate.catch((error: HttpErrorResponse) => {
|
||||
this._loadingService.stop();
|
||||
this._toaster.error(_('add-edit-dossier-attribute.error.generic'), { error });
|
||||
return undefined;
|
||||
});
|
||||
|
||||
if (result) {
|
||||
this._dialogRef.close(true);
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('window:keydown.Enter', ['$event'])
|
||||
onEnter(event: KeyboardEvent): void {
|
||||
async onEnter(event: KeyboardEvent) {
|
||||
const node = (event.target as IqserEventTarget).localName;
|
||||
if (this.form.valid && this.changed && node !== 'textarea') {
|
||||
this.save();
|
||||
await this.save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,12 +1,5 @@
|
||||
<section class="dialog">
|
||||
<div
|
||||
[translateParams]="{
|
||||
type: type,
|
||||
name: data.dossierState?.name
|
||||
}"
|
||||
[translate]="'add-edit-dossier-state.title'"
|
||||
class="dialog-header heading-l"
|
||||
></div>
|
||||
<div [innerHTML]="'add-edit-dossier-state.title' | translate : titleTranslateParams" class="dialog-header heading-l"></div>
|
||||
|
||||
<form [formGroup]="form">
|
||||
<div class="dialog-content">
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { BaseDialogComponent } from '@iqser/common-ui';
|
||||
import { UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { Validators } from '@angular/forms';
|
||||
import { IDossierState } from '@red/domain';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { DossierStatesService } from '@services/entity-services/dossier-states.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
@ -13,12 +12,16 @@ interface DialogData {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-add-edit-dossier-state-dialog',
|
||||
templateUrl: './add-edit-dossier-state-dialog.component.html',
|
||||
styleUrls: ['./add-edit-dossier-state-dialog.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AddEditDossierStateDialogComponent extends BaseDialogComponent {
|
||||
readonly type = this.data.dossierState ? 'edit' : 'create';
|
||||
readonly titleTranslateParams = {
|
||||
type: this.type,
|
||||
name: this.data.dossierState?.name,
|
||||
};
|
||||
|
||||
constructor(
|
||||
private readonly _dossierStatesService: DossierStatesService,
|
||||
protected readonly _dialogRef: MatDialogRef<AddEditDossierStateDialogComponent>,
|
||||
@ -29,26 +32,25 @@ export class AddEditDossierStateDialogComponent extends BaseDialogComponent {
|
||||
this.initialFormValue = this.form.getRawValue();
|
||||
}
|
||||
|
||||
get type(): 'edit' | 'create' {
|
||||
return this.data.dossierState ? 'edit' : 'create';
|
||||
}
|
||||
|
||||
async save(): Promise<void> {
|
||||
async save() {
|
||||
const dossierState: IDossierState = {
|
||||
dossierStatusId: this.data.dossierState?.dossierStatusId,
|
||||
dossierTemplateId: this.data.dossierTemplateId,
|
||||
...this.form.getRawValue(),
|
||||
};
|
||||
|
||||
this._loadingService.start();
|
||||
|
||||
try {
|
||||
await firstValueFrom(this._dossierStatesService.createOrUpdate(dossierState));
|
||||
await this._dossierStatesService.createOrUpdate(dossierState);
|
||||
this._toaster.success(_('add-edit-dossier-state.success'), { params: { type: this.type } });
|
||||
this._dialogRef.close();
|
||||
} catch (e) {}
|
||||
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
#getForm(): UntypedFormGroup {
|
||||
#getForm() {
|
||||
return this._formBuilder.group({
|
||||
name: [this.data.dossierState?.name, Validators.required],
|
||||
color: [this.data.dossierState?.color, Validators.required],
|
||||
|
||||
@ -1,12 +1,5 @@
|
||||
<section class="dialog">
|
||||
<div
|
||||
[translateParams]="{
|
||||
type: fileAttribute ? 'edit' : 'create',
|
||||
name: fileAttribute?.label
|
||||
}"
|
||||
[translate]="'add-edit-file-attribute.title'"
|
||||
class="dialog-header heading-l"
|
||||
></div>
|
||||
<div [innerHTML]="'add-edit-file-attribute.title' | translate : titleTranslateParams" class="dialog-header heading-l"></div>
|
||||
|
||||
<form [formGroup]="form">
|
||||
<div class="dialog-content">
|
||||
|
||||
@ -1,34 +1,37 @@
|
||||
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
|
||||
import { UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { Validators } from '@angular/forms';
|
||||
import { FileAttributeConfigTypes, IFileAttributeConfig } from '@red/domain';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { fileAttributeTypesTranslations } from '@translations/file-attribute-types-translations';
|
||||
import { BaseDialogComponent } from '@iqser/common-ui';
|
||||
|
||||
export interface AddEditFileAttributeDialogData {
|
||||
readonly fileAttribute: IFileAttributeConfig;
|
||||
readonly dossierTemplateId: string;
|
||||
readonly numberOfDisplayedAttrs: number;
|
||||
readonly numberOfFilterableAttrs: number;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-add-edit-file-attribute-dialog',
|
||||
templateUrl: './add-edit-file-attribute-dialog.component.html',
|
||||
styleUrls: ['./add-edit-file-attribute-dialog.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AddEditFileAttributeDialogComponent extends BaseDialogComponent {
|
||||
readonly DISPLAYED_FILTERABLE_LIMIT = 3;
|
||||
readonly translations = fileAttributeTypesTranslations;
|
||||
fileAttribute: IFileAttributeConfig = this.data.fileAttribute;
|
||||
readonly fileAttribute = this.data.fileAttribute;
|
||||
readonly dossierTemplateId: string = this.data.dossierTemplateId;
|
||||
readonly typeOptions = Object.keys(FileAttributeConfigTypes);
|
||||
readonly canSetDisplayed!: boolean;
|
||||
readonly canSetFilterable!: boolean;
|
||||
readonly titleTranslateParams = {
|
||||
type: this.data.fileAttribute ? 'edit' : 'create',
|
||||
name: this.data.fileAttribute?.label,
|
||||
};
|
||||
|
||||
constructor(
|
||||
protected readonly _dialogRef: MatDialogRef<AddEditFileAttributeDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA)
|
||||
readonly data: {
|
||||
fileAttribute: IFileAttributeConfig;
|
||||
dossierTemplateId: string;
|
||||
numberOfDisplayedAttrs: number;
|
||||
numberOfFilterableAttrs: number;
|
||||
},
|
||||
@Inject(MAT_DIALOG_DATA) readonly data: AddEditFileAttributeDialogData,
|
||||
) {
|
||||
super(_dialogRef, !!data.fileAttribute);
|
||||
this.canSetDisplayed = data.numberOfDisplayedAttrs < this.DISPLAYED_FILTERABLE_LIMIT || data.fileAttribute?.displayedInFileList;
|
||||
@ -46,7 +49,7 @@ export class AddEditFileAttributeDialogComponent extends BaseDialogComponent {
|
||||
this._dialogRef.close(fileAttribute);
|
||||
}
|
||||
|
||||
private _getForm(fileAttribute: IFileAttributeConfig): UntypedFormGroup {
|
||||
private _getForm(fileAttribute: IFileAttributeConfig) {
|
||||
return this._formBuilder.group({
|
||||
label: [fileAttribute?.label, Validators.required],
|
||||
csvColumnHeader: [fileAttribute?.csvColumnHeader],
|
||||
|
||||
@ -1,48 +1,46 @@
|
||||
<div *ngIf="dossierTemplate$ | async as dossierTemplate" class="content-container" iqserHasScrollbar>
|
||||
<ng-container *ngIf="dossierTemplateStats$ | async as stats">
|
||||
<div class="heading-xl">{{ dossierTemplate.name }}</div>
|
||||
<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>
|
||||
<div [translate]="'dossier-template-info-screen.created-by'" class="all-caps-label mt-24 mb-8"></div>
|
||||
|
||||
<iqser-initials-avatar [user]="dossierTemplate.createdBy || 'system'" [withName]="true" size="large"></iqser-initials-avatar>
|
||||
<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[dossierTemplate.dossierTemplateStatus] | translate }}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<mat-icon svgIcon="red:dictionary"></mat-icon>
|
||||
{{ 'dossier-template-info-screen.entities' | translate : { count: stats.numberOfDictionaries } }}
|
||||
</div>
|
||||
|
||||
<div *ngIf="dossierTemplate.validTo && dossierTemplate.validFrom">
|
||||
<mat-icon svgIcon="red:calendar"></mat-icon>
|
||||
{{ 'dossier-template-info-screen.valid-from' | translate : { date: dossierTemplate.validFrom | date : 'd MMM yyyy' } }}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<mat-icon svgIcon="red:calendar"></mat-icon>
|
||||
{{ 'dossier-template-info-screen.created-on' | translate : { date: dossierTemplate.dateAdded | date : 'd MMM yyyy' } }}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<mat-icon svgIcon="red:entries"></mat-icon>
|
||||
{{ 'dossier-template-info-screen.entries' | translate : { count: stats.numberOfEntries } }}
|
||||
</div>
|
||||
|
||||
<div *ngIf="dossierTemplate.validTo && dossierTemplate.validFrom">
|
||||
<mat-icon svgIcon="red:calendar"></mat-icon>
|
||||
{{ 'dossier-template-info-screen.valid-to' | translate : { date: dossierTemplate.validTo | date : 'd MMM yyyy' } }}
|
||||
</div>
|
||||
|
||||
<div *ngIf="dossierTemplate.dateModified">
|
||||
<mat-icon svgIcon="red:calendar"></mat-icon>
|
||||
{{ 'dossier-template-info-screen.modified-on' | translate : { date: dossierTemplate.dateModified | date : 'd MMM yyyy' } }}
|
||||
</div>
|
||||
<div class="small-label stats-subtitle">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:status"></mat-icon>
|
||||
{{ translations[ctx.dossierTemplate.dossierTemplateStatus] | translate }}
|
||||
</div>
|
||||
|
||||
<div class="template-description">{{ dossierTemplate.description }}</div>
|
||||
</ng-container>
|
||||
<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="red: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="red: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="red: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="red: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,24 +1,28 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { Component } from '@angular/core';
|
||||
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { DOSSIER_TEMPLATE_ID, DossierTemplate, DossierTemplateStats } from '@red/domain';
|
||||
import { DOSSIER_TEMPLATE_ID, type DossierTemplate, type DossierTemplateStats } from '@red/domain';
|
||||
import { DossierTemplateStatsService } from '@services/entity-services/dossier-template-stats.service';
|
||||
import { dossierTemplateStatusTranslations } from '@translations/dossier-template-status-translations';
|
||||
import { getParam } from '@iqser/common-ui';
|
||||
import { ContextComponent, getParam } from '@iqser/common-ui';
|
||||
|
||||
interface Context {
|
||||
readonly dossierTemplate: DossierTemplate;
|
||||
readonly stats: DossierTemplateStats;
|
||||
}
|
||||
|
||||
@Component({
|
||||
templateUrl: './dossier-template-info-screen.component.html',
|
||||
styleUrls: ['./dossier-template-info-screen.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class DossierTemplateInfoScreenComponent {
|
||||
readonly dossierTemplate$: Observable<DossierTemplate>;
|
||||
readonly dossierTemplateStats$: Observable<DossierTemplateStats>;
|
||||
export class DossierTemplateInfoScreenComponent extends ContextComponent<Context> {
|
||||
readonly translations = dossierTemplateStatusTranslations;
|
||||
|
||||
constructor(dossierTemplatesService: DossierTemplatesService, dossierTemplateStatsService: DossierTemplateStatsService) {
|
||||
super();
|
||||
const dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
|
||||
this.dossierTemplate$ = dossierTemplatesService.getEntityChanged$(dossierTemplateId);
|
||||
this.dossierTemplateStats$ = dossierTemplateStatsService.watch$(dossierTemplateId);
|
||||
super._initContext({
|
||||
dossierTemplate: dossierTemplatesService.getEntityChanged$(dossierTemplateId),
|
||||
stats: dossierTemplateStatsService.watch$(dossierTemplateId),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,12 +74,10 @@
|
||||
<div class="section-title all-caps-label" translate="license-info-screen.usage-details"></div>
|
||||
|
||||
<div class="row">
|
||||
<div>
|
||||
{{
|
||||
'license-info-screen.total-analyzed'
|
||||
| translate : { date: licenseService.totalInfo.startDate | date : 'longDate' }
|
||||
}}
|
||||
</div>
|
||||
<div
|
||||
*ngIf="licenseService.totalInfo.startDate | date : 'longDate' as startDate"
|
||||
[innerHTML]="'license-info-screen.total-analyzed' | translate : { date: startDate }"
|
||||
></div>
|
||||
<div>{{ licenseService.totalInfo.numberOfAnalyzedPages }}</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
<ng-container *ngIf="stateService.file$ | async as file">
|
||||
<ng-container *ngIf="componentContext$ | async as ctx">
|
||||
<div class="right-title heading" translate="file-preview.tabs.document-info.label">
|
||||
<div *ngIf="stateService.dossier$ | async as dossier">
|
||||
<div>
|
||||
<iqser-circle-button
|
||||
(action)="edit(file)"
|
||||
*ngIf="permissionsService.canEditFileAttributes(file, dossier)"
|
||||
(action)="edit(ctx.file)"
|
||||
*ngIf="permissionsService.canEditFileAttributes(ctx.file, ctx.dossier)"
|
||||
[tooltip]="'file-preview.tabs.document-info.edit' | translate"
|
||||
icon="iqser:edit"
|
||||
tooltipPosition="before"
|
||||
@ -20,40 +20,38 @@
|
||||
|
||||
<div class="right-content" iqserHasScrollbar>
|
||||
<div class="section">
|
||||
<div *ngFor="let attr of fileAttributes$ | async" class="attribute">
|
||||
<div *ngFor="let attr of ctx.fileAttributes" class="attribute">
|
||||
<div class="small-label">{{ attr.label }}:</div>
|
||||
<div>{{ attr.value ? (isDate(attr) ? (attr.value | date : 'd MMM yyyy') : attr.value) : '-' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="stateService.dossier$ | async as dossier" class="section small-label stats-subtitle">
|
||||
<div class="section small-label stats-subtitle">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:folder"></mat-icon>
|
||||
<span>{{ 'file-preview.tabs.document-info.details.dossier' | translate : { dossierName: dossier.dossierName } }}</span>
|
||||
<span
|
||||
[innerHTML]="'file-preview.tabs.document-info.details.dossier' | translate : { dossierName: ctx.dossier.dossierName }"
|
||||
></span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<mat-icon svgIcon="iqser:document"></mat-icon>
|
||||
<span>{{ 'file-preview.tabs.document-info.details.pages' | translate : { pages: file.numberOfPages } }}</span>
|
||||
<span>{{ 'file-preview.tabs.document-info.details.pages' | translate : { pages: ctx.file.numberOfPages } }}</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div *ngIf="ctx.file.added | date : 'mediumDate' as added">
|
||||
<mat-icon svgIcon="red:calendar"></mat-icon>
|
||||
<span>{{
|
||||
'file-preview.tabs.document-info.details.created-on' | translate : { date: file.added | date : 'mediumDate' }
|
||||
}}</span>
|
||||
<span [innerHTML]="'file-preview.tabs.document-info.details.created-on' | translate : { date: added }"></span>
|
||||
</div>
|
||||
|
||||
<div *ngIf="dossier.dueDate">
|
||||
<div *ngIf="ctx.dossier.dueDate | date : 'mediumDate' as dueDate">
|
||||
<mat-icon svgIcon="red:lightning"></mat-icon>
|
||||
<span>{{
|
||||
'file-preview.tabs.document-info.details.due' | translate : { date: dossier.dueDate | date : 'mediumDate' }
|
||||
}}</span>
|
||||
<span [innerHTML]="'file-preview.tabs.document-info.details.due' | translate : { date: dueDate }"></span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<mat-icon svgIcon="red:template"></mat-icon>
|
||||
{{ dossierTemplateName$ | async }}
|
||||
{{ ctx.dossierTemplateName }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
|
||||
import { DocumentInfoService } from '../../services/document-info.service';
|
||||
import { combineLatest, Observable, switchMap } from 'rxjs';
|
||||
import { combineLatest, switchMap } from 'rxjs';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { FilePreviewStateService } from '../../services/file-preview-state.service';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { File, FileAttributeConfigType, FileAttributeConfigTypes } from '@red/domain';
|
||||
import { type Dossier, type File, type FileAttributeConfigType, FileAttributeConfigTypes } from '@red/domain';
|
||||
import { FilePreviewDialogService } from '../../services/file-preview-dialog.service';
|
||||
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
|
||||
import { ContextComponent } from '@iqser/common-ui';
|
||||
|
||||
interface FileAttribute {
|
||||
label: string;
|
||||
@ -15,34 +16,43 @@ interface FileAttribute {
|
||||
type: FileAttributeConfigType;
|
||||
}
|
||||
|
||||
interface Context {
|
||||
readonly file: File;
|
||||
readonly dossier: Dossier;
|
||||
readonly dossierTemplateName: string;
|
||||
readonly fileAttributes: FileAttribute[];
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-document-info',
|
||||
templateUrl: './document-info.component.html',
|
||||
styleUrls: ['./document-info.component.scss'],
|
||||
})
|
||||
export class DocumentInfoComponent {
|
||||
readonly fileAttributes$: Observable<FileAttribute[]>;
|
||||
readonly dossierTemplateName$: Observable<string>;
|
||||
|
||||
export class DocumentInfoComponent extends ContextComponent<Context> {
|
||||
constructor(
|
||||
private readonly _dossierTemplatesService: DossierTemplatesService,
|
||||
private readonly _dialogService: FilePreviewDialogService,
|
||||
private readonly _fileAttributesService: FileAttributesService,
|
||||
readonly stateService: FilePreviewStateService,
|
||||
state: FilePreviewStateService,
|
||||
fileAttributesService: FileAttributesService,
|
||||
readonly permissionsService: PermissionsService,
|
||||
readonly documentInfoService: DocumentInfoService,
|
||||
private readonly _dialogService: FilePreviewDialogService,
|
||||
private readonly _dossierTemplatesService: DossierTemplatesService,
|
||||
) {
|
||||
this.fileAttributes$ = combineLatest([
|
||||
this.stateService.file$,
|
||||
this.stateService.dossier$,
|
||||
this._fileAttributesService.fileAttributesConfig$,
|
||||
]).pipe(
|
||||
switchMap(([file, dossier]) => this.documentInfoService.fileAttributes$(file.fileId, dossier.id, dossier.dossierTemplateId)),
|
||||
super();
|
||||
const fileAttributes$ = combineLatest([state.file$, state.dossier$, fileAttributesService.fileAttributesConfig$]).pipe(
|
||||
switchMap(([file, dossier]) => this.documentInfoService.fileAttributes$(file.id, dossier.id, dossier.dossierTemplateId)),
|
||||
);
|
||||
this.dossierTemplateName$ = this.stateService.dossier$.pipe(
|
||||
|
||||
const dossierTemplateName$ = state.dossier$.pipe(
|
||||
switchMap(dossier => this._dossierTemplatesService.getEntityChanged$(dossier.dossierTemplateId)),
|
||||
map(dossierTemplate => dossierTemplate.name),
|
||||
);
|
||||
|
||||
super._initContext({
|
||||
file: state.file$,
|
||||
dossier: state.dossier$,
|
||||
dossierTemplateName: dossierTemplateName$,
|
||||
fileAttributes: fileAttributes$,
|
||||
});
|
||||
}
|
||||
|
||||
edit(file: File) {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject, merge, Observable } from 'rxjs';
|
||||
import { shareLast } from '@iqser/common-ui';
|
||||
import { filter, map, startWith, tap, withLatestFrom } from 'rxjs/operators';
|
||||
import { map, startWith, tap, withLatestFrom } from 'rxjs/operators';
|
||||
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
|
||||
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
|
||||
import { FilesMapService } from '@services/files/files-map.service';
|
||||
@ -39,9 +39,7 @@ export class DocumentInfoService {
|
||||
|
||||
fileAttributes$(fileId: string, dossierId: string, dossierTemplateId: string) {
|
||||
const getAttributes = () => this._fileAttributesService.getFileAttributeConfig(dossierTemplateId).fileAttributeConfigs;
|
||||
const dossierTemplateChange$ = this._dossierTemplatesService
|
||||
.getEntityChanged$(dossierTemplateId)
|
||||
.pipe(filter(template => template.dossierTemplateId === dossierTemplateId));
|
||||
const dossierTemplateChange$ = this._dossierTemplatesService.getEntityChanged$(dossierTemplateId);
|
||||
const fileChange$ = this._filesMapService.watch$(dossierId, fileId);
|
||||
return merge(dossierTemplateChange$, fileChange$).pipe(
|
||||
map(getAttributes),
|
||||
|
||||
@ -44,11 +44,9 @@ export class DossierAttributesService extends EntitiesService<IDossierAttributeC
|
||||
}
|
||||
|
||||
@Validate()
|
||||
createOrUpdate(
|
||||
@RequiredParam() attributeConfig: IDossierAttributeConfig,
|
||||
dossierTemplateId: string,
|
||||
): Observable<IDossierAttributeConfig> {
|
||||
return this._post(attributeConfig, `${this._defaultModelPath}/config/${dossierTemplateId}`);
|
||||
createOrUpdate(@RequiredParam() attributeConfig: IDossierAttributeConfig, dossierTemplateId: string) {
|
||||
const url = `${this._defaultModelPath}/config/${dossierTemplateId}`;
|
||||
return firstValueFrom(this._post(attributeConfig, url));
|
||||
}
|
||||
|
||||
@Validate()
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { EntitiesService, mapEach, RequiredParam, Toaster, Validate } from '@iqser/common-ui';
|
||||
import { DossierState, IDossierState } from '@red/domain';
|
||||
import { EMPTY, forkJoin, Observable, switchMap } from 'rxjs';
|
||||
import { EMPTY, firstValueFrom, forkJoin, Observable, switchMap } from 'rxjs';
|
||||
import { DossierTemplatesService } from '../dossier-templates/dossier-templates.service';
|
||||
import { catchError, defaultIfEmpty, tap } from 'rxjs/operators';
|
||||
import { DossierStatesMapService } from '../entity-services/dossier-states-map.service';
|
||||
@ -23,15 +23,18 @@ export class DossierStatesService extends EntitiesService<IDossierState, Dossier
|
||||
readonly #dossierStatesMapService = inject(DossierStatesMapService);
|
||||
|
||||
@Validate()
|
||||
createOrUpdate(@RequiredParam() state: IDossierState): Observable<DossierState[]> {
|
||||
async createOrUpdate(@RequiredParam() state: IDossierState) {
|
||||
const showToast = (error: HttpErrorResponse) => {
|
||||
this.#toaster.error(error.status === HttpStatusCode.Conflict ? CONFLICT_MSG : GENERIC_MSG);
|
||||
return EMPTY;
|
||||
};
|
||||
return this._post<unknown>(state, this._defaultModelPath).pipe(
|
||||
|
||||
const request = this._post(state, this._defaultModelPath).pipe(
|
||||
catchError(showToast),
|
||||
switchMap(() => this.loadAllForTemplate(state.dossierTemplateId)),
|
||||
);
|
||||
|
||||
return firstValueFrom(request);
|
||||
}
|
||||
|
||||
@Validate()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user