Untitled

 avatar
unknown
plain_text
a month ago
5.0 kB
1
Indexable
import { Component } from '@angular/core';
import {
  AbstractControl,
  AsyncValidatorFn,
  FormArray,
  FormBuilder,
  FormGroup,
  ValidationErrors,
  Validators,
} from '@angular/forms';
import {
  EditorObjectItemValue,
  ItemDataService,
  SetupDataService,
} from '@tosis/domain';
import {
  ItemNameModel,
  ItemNameRequest,
  SetupListModel,
} from '@tosis/dal-api-client';
import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
import { Observable, catchError, map, of, switchMap, timer } from 'rxjs';

@Component({
  selector: 'tosis-editor-save-dialog',
  templateUrl: './save-dialog.component.html',
  styleUrls: ['./save-dialog.component.scss'],
})
export class SaveDialogComponent {
  public saveDialogForm: FormGroup;
  public readonly currentSetupName: string;
  public readonly userOwnsSetup: boolean;
  public readonly savingSingleItem = false;

  versionCar!: string;
  itemNames: { id: string; items: ItemNameModel[] }[] = [];
  setupNames: string[] = [];
  constructor(
    private fb: FormBuilder,
    private dialogRef: DynamicDialogRef,
    private dialogConfig: DynamicDialogConfig,
    private itemDataService: ItemDataService,
    private setupDataService: SetupDataService
  ) {
    const dialogData = this.dialogConfig.data;
    this.currentSetupName = dialogData?.setupName;
    this.userOwnsSetup = dialogData?.userOwnsSetup;
    this.savingSingleItem = dialogData?.saveSingleItem;
    this.versionCar = dialogData?.versionCar;
    this.saveDialogForm = this.fb.group({
      setupName: [
        {
          value: dialogData && dialogData.setupName ? dialogData.setupName : '',
          disabled: !this.currentSetupName === undefined,
        },
        this.savingSingleItem
          ? {}
          : {
              validators: [Validators.required],
              asyncValidators: [this.validateSetupName()],
            },
      ],
      items: this.fb.array<EditorObjectItemValue[]>(
        (dialogData?.items ?? []).map((item: EditorObjectItemValue) => {
          return this.fb.group({
            itemId: [item.itemId],
            itemName: [item.itemName],
            parentNodeDefId: [item.parentNodeDefId],
            itemNewName: [
              null,
              {
                validators: [Validators.required],
                asyncValidators: [this.validateUniqueItemName()],
              },
            ],
          });
        })
      ),
    });
  }

  private get setupName() {
    return this.saveDialogForm.get('setupName')?.value;
  }

  get items() {
    return this.saveDialogForm.get('items') as FormArray;
  }

  hasNewSetupName(): boolean {
    return this.setupName && this.setupName !== this.currentSetupName;
  }

  private validateSetupName(): AsyncValidatorFn {
    return (control: AbstractControl): Observable<ValidationErrors | null> => {
      if (!this.userOwnsSetup && !this.hasNewSetupName()) {

        return of({ notOwner: true });
      }
      return this.validateUniqueSetupName()(control);
    }
  }

  private validateUniqueSetupName(): AsyncValidatorFn {
    return (control: AbstractControl): Observable<ValidationErrors | null> => {
      return of(null);
    };
  }

  private validateUniqueItemName(): AsyncValidatorFn {
    return (control: AbstractControl): Observable<ValidationErrors | null> => {
      const parentNodeDefId = control.parent?.value.parentNodeDefId;
      const itemNameList = this.itemNames.find(
        (list) => list.id === parentNodeDefId
      );

      if (itemNameList !== undefined) {
        const nameExists = itemNameList.items.some(
          (item) => item.itemName === control.value
        );
        return of(nameExists ? { nameExists: { value: control.value } } : null);
      }

      return timer(250).pipe(
        switchMap(() =>
          this.itemDataService
            .getItemNameList(<ItemNameRequest>{
              nodeDefIds: [parentNodeDefId],
              versioncar: this.versionCar,
            })
            .pipe(
              catchError(() => {
                return of(<ItemNameModel[]>[]);
              }),
              map((items) => {
                this.itemNames.push({ id: parentNodeDefId, items });
                const nameExists = items.some(
                  (item) => item.itemName === control.value
                );
                return nameExists
                  ? { nameExists: { value: control.value } }
                  : null;
              })
            )
        )
      );
    };
  }

  onSave() {
    if (!this.saveDialogForm.valid) {
      return;
    }

    this.dialogRef.close({
      newSetupName: this.hasNewSetupName() ? this.setupName : undefined,
      items: this.items.getRawValue(),
    });
  }

  onClose() {
    this.dialogRef.close(undefined);
  }
}
Editor is loading...
Leave a Comment