File

libs/core/dynamic-form/src/base/base.model.ts

Index

Properties

Properties

acl (Optional)
Type DfFormAcl[]
Description

ACL rules to be applied to this form.

fields
Type T[]
layout (Optional)
Type DfFormLayout
import { AclRuleState } from '@allianz/taly-acl';
import { DynamicFormValidationConfig, type BusinessEventConfig } from '@allianz/taly-core';
import { InjectionToken, Type } from '@angular/core';
import { DfFormLayout } from '../utils/form-layout/form-layout.model';
import { DfInfoIconConfig } from './info-icon.model';

// Why is this here?
// Because there was a circular dependency...
export interface BaseDynamicFormConfiguration<T extends DfBaseConfig = DfBaseConfig> {
  layout?: DfFormLayout;
  fields: T[];
  /**
   * ACL rules to be applied to this form.
   */
  acl?: DfFormAcl[];
}

/**
 * Common interface for all configuration types for formfield components.
 */
export interface DfBaseConfig {
  /**
   * This field's type.
   */
  type: string;

  /**
   * This field's ID.
   *
   * The ID will serve as the ACL resource name for the form field. If the field is a form element, it will also be used as a form control name within the FormGroup to which it is added.
   * IDs must be unique within your form.
   * @examples ["myField"]
   */
  id: string;

  /**
   * The optional renderName is added as the attribute "render-name" to the df-formfield elements in the DOM.
   * It can be used to find the rendered element of a specific field of a form.
   */
  renderName?: string;

  /**
   * This field's label.
   * It's translatable by default and supports string interpolation.
   * @examples ["My label", "My label {$['bb-pgr-simple'].person.firstName}"]
   */
  label: string;

  /**
   * Info icon with associated pop-over.
   */
  infoIcon?: DfInfoIconConfig;

  /**
   * This field's custom size.
   *
   * Number of column(s) the element should span. It's only applicable with the "CUSTOM_COLUMN" layout.
   * The value can be 1-12, following the 12-column grid system. The default value is 12.
   *
   */
  columnSpan?: number;

  /**
   * This field's custom spacing.
   *
   * If defined, it will be used to set the spacing between this field and the next one.
   *
   */
  spacing?: DfFormfieldSpacing;

  /**
   * The id used to select the element in the tests (unit test, e2e testing)
   */
  testId?: string;

  /**
   * ACL rules to be applied to this field.
   */
  acl?: DfFieldAcl[];
}

export type DfInteractiveEventConfig = Exclude<BusinessEventConfig, string>;

export interface DfInteractiveBaseConfig extends DfBaseConfig {
  /**
   * The field's initial value.
   *
   * If set, the field will be pre-filled with / pre-set to this value.
   */
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  value?: any;

  /**
   * Validators to set on this form field.
   */
  validators?: DynamicFormValidationConfig[];

  /**
   * The hint text to be displayed under the field.
   * It's translatable by default and supports string interpolation.
   * @examples ["Hint text", "Hint text with dynamic value {$['bb-pgr-simple'].date}"]
   */
  hint?: string;

  /**
   * The note text is displayed in an info message box below the field.
   * It's translatable by default and supports string interpolation.
   * @examples ["Note", "Note with dynamic value {$['bb-pgr-simple'].date}"]
   */
  note?: string;

  /**
   * Configure either a PFE action or service activator configuration handler for the field's `valueChanges` event.
   */
  onValueChangesEvent?: DfInteractiveEventConfig;

  /**
   * Configure either a PFE action or service activator configuration handler for the field's `blur` event.
   */
  onBlurEvent?: DfInteractiveEventConfig;
}

export interface DfFieldAcl {
  /**
   * State can be either "hidden", "readonly", "disabled", "visible" or "editable"
   */
  state: AclRuleState;

  /**
   * Conditions are evaluated using the library filtrex.
   * Please refer to their documentation for details on how to write conditions: https://github.com/m93a/filtrex/tree/v2?tab=readme-ov-file#expressions.
   * In addition to what filtrex provides out of the box, you can use the function s(\"$['state-key']\") to use values from the application state in your conditions.
   * Please note that a specific usage of quotes is required. Filtrex ONLY uses double quotes (") for strings, never single quotes (').
   * However, inside the s() expressions, single quotes have to be used.
   *
   * These are examples of valid conditions:
   *  - s(\"$['my-dynamic-form'].myRadioButtons\") == \"first\"
   *  - s(\"$['my-dynamic-form'].myRadioButtons\")
   *
   * @TJS-pattern ^((?!\').|\[.*\'.*\])*$
   * @examples ["s(\"$['my-dynamic-form'].myRadioButtons\") == \"first\"", "s(\"$['my-dynamic-form'].myRadioButtons\")"]
   */
  // This aims to prevent the usage of single quotes that could lead to silent failures.
  // Since Filtrex treats everything inside single quotes as a property, it silently transforms the given expression to `undefined`.
  condition?: string;
}

export interface DfFormAcl extends DfFieldAcl {
  /**
   * Path to the ACL resource or the target that the ACL rule should be applied to.
   * The path can either be an "id" of the child fields or an asterisk (*) if you want to target the entire form.
   */
  path: string;
}

export const DfFormfieldSpacing = {
  none: 'NONE',
  xs: 'XS',
  s: 'S',
  m: 'M',
  l: 'L',
  xl: 'XL',
  xxl: 'XXL'
} as const;
export type DfFormfieldSpacing = (typeof DfFormfieldSpacing)[keyof typeof DfFormfieldSpacing];

export type DfComponentConfig = {
  load: () => Promise<Record<string, Type<unknown>>>;
  componentName: string;
  moduleName?: string;
};

export const NATIVE_DYNAMIC_FORM_COMPONENTS = new InjectionToken<Record<string, DfComponentConfig>>(
  'NATIVE_DYNAMIC_FORM_COMPONENTS',
  {
    factory: () => {
      throw new Error('NATIVE_DYNAMIC_FORM_COMPONENTS is not provided');
    }
  }
);

export interface DfEventPayload {
  type: string;
  fieldIdConfig: string;
  data?: unknown;
}

results matching ""

    No results matching ""