File

src/app/core/default-values/default-value-service/default-value.service.ts

Description

Reduced "DefaultValueHint" if no referenced parent entity is selected but a rule to inherit values is configured.

Index

Properties

Properties

inheritedFromField
inheritedFromField: string
Type : string
inheritedFromType
inheritedFromType: undefined
Type : undefined
Optional
isEmpty
isEmpty:
isInSync
isInSync: undefined
Type : undefined
Optional
syncFromParentField
syncFromParentField: undefined
Type : undefined
Optional
import { Inject, Injectable } from "@angular/core";
import { Entity } from "../../entity/model/entity";
import { EntityForm } from "../../common-components/entity-form/entity-form.service";
import { AbstractControl } from "@angular/forms";
import { EntitySchemaField } from "../../entity/schema/entity-schema-field";
import { DefaultValueStrategy } from "../default-value-strategy.interface";
import { Logging } from "../../logging/logging.service";

/**
 * Handle default values like the current date or user for forms when editing an Entity.
 */
@Injectable({
  providedIn: "root",
})
export class DefaultValueService {
  constructor(
    @Inject(DefaultValueStrategy)
    private defaultValueStrategies: DefaultValueStrategy[],
  ) {}

  async handleEntityForm<T extends Entity>(
    form: EntityForm<T>,
    entity: Entity,
  ): Promise<void> {
    if (!(form.fieldConfigs?.length > 0)) {
      return;
    }

    for (const strategy of this.defaultValueStrategies) {
      await strategy.initEntityForm(form);
    }
    this.enableChangeListener(form);

    for (const fieldConfig of form.fieldConfigs) {
      if (!fieldConfig.defaultValue) {
        continue;
      }

      let targetFormControl = form.formGroup.get(fieldConfig.id);
      if (
        !this.preConditionsFulfilled(
          entity.isNew,
          targetFormControl,
          fieldConfig,
        )
      ) {
        continue;
      }

      const strategy = this.defaultValueStrategies.find(
        (s) => s.mode === fieldConfig.defaultValue?.mode,
      );
      if (strategy) {
        strategy.setDefaultValue(targetFormControl, fieldConfig, form);
      } else {
        Logging.warn(
          `DefaultValue strategy "${fieldConfig.defaultValue?.mode}" not found`,
        );
      }
    }
  }

  private preConditionsFulfilled(
    isNew: boolean,
    formControl: AbstractControl,
    fieldConfig: EntitySchemaField,
  ): boolean {
    if (!isNew) {
      return false;
    }

    if (!formControl) {
      return false;
    }

    if (!fieldConfig.isArray && !!formControl.value) {
      return false;
    }

    if (
      fieldConfig.isArray &&
      formControl.value &&
      formControl.value.length > 0
    ) {
      return false;
    }

    return true;
  }

  private enableChangeListener<T extends Entity>(form: EntityForm<T>) {
    form.watcher.set(
      "formGroupValueChanges",
      form.formGroup.valueChanges.subscribe(async (change) =>
        this.defaultValueStrategies.forEach((s) => s.onFormValueChanges(form)),
      ),
    );
  }

  getDefaultValueUiHint<T extends Entity>(
    form: EntityForm<T>,
    fieldId: string,
  ): DefaultValueHint | EmptyDefaultValueHint | undefined {
    if (!form) {
      return;
    }

    const fieldConfig = form?.fieldConfigs?.find((x) => x.id === fieldId);
    const strategy = this.defaultValueStrategies.find(
      (s) => s.mode === fieldConfig?.defaultValue?.mode,
    );

    return strategy?.getDefaultValueUiHint(form, fieldConfig);
  }
}

export type DefaultValueHint = FullDefaultValueHint | EmptyDefaultValueHint;

/**
 * Details of the source for an "inherited" default value in a field,
 * used to display context to the user about this.
 */
export interface FullDefaultValueHint {
  isInSync: boolean;
  inheritedFromType: string;
  inheritedFromField: string;

  syncFromParentField: () => void;

  isEmpty?: undefined | false;
}

/**
 * Reduced "DefaultValueHint" if no referenced parent entity is selected but a rule to inherit values is configured.
 */
export interface EmptyDefaultValueHint {
  inheritedFromField: string;
  isEmpty: true;

  isInSync?: undefined;
  inheritedFromType?: undefined;
  syncFromParentField?: undefined;
}

results matching ""

    No results matching ""