RED-10220: added support for justification technical name.
This commit is contained in:
parent
d396b782a7
commit
a7b652c137
@ -17,6 +17,15 @@
|
||||
type="text"
|
||||
/>
|
||||
</div>
|
||||
<div class="iqser-input-group">
|
||||
<label translate="add-edit-entity.form.technical-name"></label>
|
||||
<div class="technical-name">{{ this.technicalName() || '-' }}</div>
|
||||
<span
|
||||
[translateParams]="{ type: data.justification ? 'edit' : 'create' }"
|
||||
[translate]="'add-edit-entity.form.technical-name-hint'"
|
||||
class="hint"
|
||||
></span>
|
||||
</div>
|
||||
|
||||
<div class="iqser-input-group required w-400">
|
||||
<label translate="add-edit-justification.form.reason"></label>
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, computed, Inject, untracked } from '@angular/core';
|
||||
import { ReactiveFormsModule, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { Justification } from '@red/domain';
|
||||
import { JustificationsService } from '@services/entity-services/justifications.service';
|
||||
import { BaseDialogComponent, CircleButtonComponent, IconButtonComponent } from '@iqser/common-ui';
|
||||
import { BaseDialogComponent, CircleButtonComponent, HasScrollbarDirective, IconButtonComponent } from '@iqser/common-ui';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { formControlToSignal } from '@utils/functions';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
|
||||
interface DialogData {
|
||||
justification?: Justification;
|
||||
@ -16,9 +18,29 @@ interface DialogData {
|
||||
templateUrl: './add-edit-justification-dialog.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [TranslateModule, ReactiveFormsModule, IconButtonComponent, CircleButtonComponent],
|
||||
imports: [TranslateModule, ReactiveFormsModule, IconButtonComponent, CircleButtonComponent, HasScrollbarDirective],
|
||||
})
|
||||
export class AddEditJustificationDialogComponent extends BaseDialogComponent {
|
||||
readonly form = this.#getForm();
|
||||
readonly name = formControlToSignal(this.form.controls['name']);
|
||||
readonly allJustifications = toSignal(this._justificationService.all$);
|
||||
readonly technicalName = computed(() => {
|
||||
if (this.data.justification) {
|
||||
return this.data.justification.technicalName;
|
||||
}
|
||||
if (!this.name()) {
|
||||
return null;
|
||||
}
|
||||
let currentTechnicalName = Justification.toTechnicalName(this.name());
|
||||
const existingTechnicalNames = untracked(this.allJustifications).map(justification => justification.technicalName);
|
||||
let suffix = 1;
|
||||
while (existingTechnicalNames.includes(currentTechnicalName)) {
|
||||
currentTechnicalName =
|
||||
currentTechnicalName === '_' ? `${currentTechnicalName}${suffix++}` : [currentTechnicalName, suffix++].join('_');
|
||||
}
|
||||
return currentTechnicalName;
|
||||
});
|
||||
|
||||
constructor(
|
||||
private readonly _justificationService: JustificationsService,
|
||||
protected readonly _dialogRef: MatDialogRef<AddEditJustificationDialogComponent>,
|
||||
@ -26,7 +48,6 @@ export class AddEditJustificationDialogComponent extends BaseDialogComponent {
|
||||
) {
|
||||
super(_dialogRef, !!data.justification);
|
||||
|
||||
this.form = this._getForm();
|
||||
this.initialFormValue = this.form.getRawValue();
|
||||
}
|
||||
|
||||
@ -34,7 +55,8 @@ export class AddEditJustificationDialogComponent extends BaseDialogComponent {
|
||||
const dossierTemplateId = this.data.dossierTemplateId;
|
||||
this._loadingService.start();
|
||||
try {
|
||||
await firstValueFrom(this._justificationService.createOrUpdate(this.form.getRawValue() as Justification, dossierTemplateId));
|
||||
const formValue = { ...this.form.getRawValue(), technicalName: this.technicalName() };
|
||||
await firstValueFrom(this._justificationService.createOrUpdate(formValue as Justification, dossierTemplateId));
|
||||
await firstValueFrom(this._justificationService.loadAll(dossierTemplateId));
|
||||
this._dialogRef.close(true);
|
||||
} catch (error) {
|
||||
@ -43,11 +65,12 @@ export class AddEditJustificationDialogComponent extends BaseDialogComponent {
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
private _getForm(): UntypedFormGroup {
|
||||
#getForm(): UntypedFormGroup {
|
||||
return this._formBuilder.group({
|
||||
name: [{ value: this.data.justification?.name, disabled: !!this.data.justification }, Validators.required],
|
||||
reason: [this.data.justification?.reason, Validators.required],
|
||||
description: [this.data.justification?.description, Validators.required],
|
||||
technicalName: [this.data.justification?.technicalName ?? null],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ import { ITrackable } from '@iqser/common-ui';
|
||||
import type { List } from '@iqser/common-ui/lib/utils';
|
||||
import type { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { Dayjs } from 'dayjs';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { AbstractControl } from '@angular/forms';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
|
||||
export function hexToRgb(hex: string) {
|
||||
@ -146,6 +146,6 @@ export function urlFileId() {
|
||||
return fileId.split('?')[0];
|
||||
}
|
||||
|
||||
export function formControlToSignal<T>(control: FormControl<T>) {
|
||||
export function formControlToSignal<T>(control: AbstractControl<T>) {
|
||||
return toSignal(control.valueChanges, { initialValue: control.value });
|
||||
}
|
||||
|
||||
@ -1,15 +1,18 @@
|
||||
import { IListable } from '@iqser/common-ui';
|
||||
import { ILegalBasis } from './legal-basis';
|
||||
import { toSnakeCase } from '@utils/functions';
|
||||
|
||||
export class Justification implements ILegalBasis, IListable {
|
||||
readonly description?: string;
|
||||
readonly name: string;
|
||||
readonly reason?: string;
|
||||
readonly technicalName?: string;
|
||||
|
||||
constructor(justification: ILegalBasis) {
|
||||
this.description = justification.description;
|
||||
this.name = justification.name;
|
||||
this.reason = justification.reason;
|
||||
this.technicalName = justification.technicalName;
|
||||
}
|
||||
|
||||
get id(): string {
|
||||
@ -19,4 +22,13 @@ export class Justification implements ILegalBasis, IListable {
|
||||
get searchKey(): string {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
static toTechnicalName(value: string) {
|
||||
const baseTechnicalName = toSnakeCase(value.trim());
|
||||
let technicalName = baseTechnicalName.replaceAll(/[^A-Za-z0-9_-]/g, '');
|
||||
if (!technicalName.length && baseTechnicalName.length) {
|
||||
technicalName = '_';
|
||||
}
|
||||
return technicalName;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,4 +2,5 @@ export interface ILegalBasis {
|
||||
readonly name: string;
|
||||
readonly description?: string;
|
||||
readonly reason?: string;
|
||||
readonly technicalName?: string;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user