RED-10220: added support for justification technical name.

This commit is contained in:
Nicoleta Panaghiu 2024-10-22 12:45:34 +03:00
parent d396b782a7
commit a7b652c137
5 changed files with 53 additions and 8 deletions

View File

@ -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>

View File

@ -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],
});
}
}

View File

@ -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 });
}

View File

@ -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;
}
}

View File

@ -2,4 +2,5 @@ export interface ILegalBasis {
readonly name: string;
readonly description?: string;
readonly reason?: string;
readonly technicalName?: string;
}