File

src/app/core/entity/default-datatype/default.datatype.ts

Description

Extend this class to define new data types (i.e. for properties of entities) and provide your implementation using Angular DI: { provide: DefaultDatatype, useClass: MyCustomDatatype, multi: true },

This class is also used as the default fallback Datatype for the EntitySchemaService that keeps values unchanged between database and entity instance. This type is automatically used whenever no fitting Datatype can be found for that config or TypeScript type.

Index

Properties
Methods
Accessors

Properties

Static dataType
Type : string
Default value : ""

Key for this datatype that must be specified in the DatabaseField annotation to use this transformation.

for example @DatabaseField({dataType: 'foo'}) myField will trigger the datatype implementation with name "foo".

If you set the name to a TypeScript type, class properties with this type will automatically use that EntitySchemaDatatype without the need to explicitly state the dataType config in the annotation (e.g. @DatabaseField() myField: string is triggering the EntitySchemaDatatype with name "string".

editComponent
Type : string
Default value : "EditText"
Readonly importAllowsMultiMapping
Type : boolean
Default value : false

Whether this datatype allows multiple values to be mapped to the same entity field during import.

Optional importConfigComponent
Type : string

A component to be rendered inline to configure the import transformation (e.g. defining a format or value mapping).

The component receives inputs: col, rawData, entityType, otherColumnMappings, additionalSettings, onColumnMappingChange

Static label
Type : string
Default value : $localize`:datatype-label:any`

The human-readable name for this dataType, used in config UIs.

viewComponent
Type : string
Default value : "DisplayText"

The default component how this datatype should be displayed in lists and forms.

The edit component has to be a registered component. Components that are registered contain the DynamicComponent decorator

Methods

Async anonymize
anonymize(value: EntityType, schemaField: EntitySchemaField, parent: any)

(Partially) anonymize to "retain-anonymized" for reporting purposes without personal identifiable information.

Parameters :
Name Type Optional Description
value EntityType No

The original value to be anonymized

schemaField EntitySchemaField No
parent any No
Returns : Promise<any>
Static detectAllFieldsInEntity
detectAllFieldsInEntity(entityOrType: Entity | EntityConstructor, dataTypes: string | string[])

Detect all fields of the given datatype(s) in an entity's schema.

Parameters :
Name Type Optional Description
entityOrType Entity | EntityConstructor No

An entity instance or entity constructor to inspect.

dataTypes string | string[] No

One or more datatype identifiers to match against.

Returns : literal type[]

Array of matching fields with their id and schema definition.

Static detectFieldInEntity
detectFieldInEntity(entityOrType: Entity | EntityConstructor, dataTypes: string | string[])

Detect the first field of the given datatype(s) in an entity's schema.

Scans the schema for a field whose dataType matches one of the provided strings and returns its property name.

Subclasses typically override this without the extra dataTypes parameter, forwarding their own relevant datatype identifiers.

Parameters :
Name Type Optional Description
entityOrType Entity | EntityConstructor No

An entity instance or entity constructor to inspect.

dataTypes string | string[] No

One or more datatype identifiers to match against.

Returns : string | undefined

The field name of the first matching field, or undefined if none is found.

getExportColumns
getExportColumns(schemaField: EntitySchemaField)

Export columns for a field using this datatype.

Each returned column contributes a CSV header and its own value resolver. The returned keySuffix is appended to the field id to form the exported column key.

The default implementation returns a single column with the raw field value. Readable formatting can be applied by callers during CSV transformation. Override this to provide custom or additional columns (e.g. entity references can add a human-readable name column alongside the ID column).

Parameters :
Name Type Optional
schemaField EntitySchemaField No
Returns : ExportColumnMapping[]
Async importMapFunction
importMapFunction(val: any, schemaField: EntitySchemaField, additional?: any, importProcessingContext?: any)

The function used to map values from the import data to values in the entities to be created. to share information across processing of multiple columns and rows.

Parameters :
Name Type Optional Description
val any No

The value from an imported cell to be mapped

schemaField EntitySchemaField No

The schema field definition for the target property into which the value is mapped

additional any Yes

config as returned by the configComponent

importProcessingContext any Yes

an object that the datatype can use to store any relevant context across multiple calls to share information across processing of multiple columns and rows.

normalizeSchemaField
normalizeSchemaField(schemaField: EntitySchemaField)

Return the (potentially adjusted) schema field for this datatype.

Called when schema fields are set up (e.g. from config), allowing the datatype to normalize or fill in required settings.

Override this in a subclass to enforce constraints (e.g. always setting isArray: true).

Parameters :
Name Type Optional Description
schemaField EntitySchemaField No

The current schema field definition

Returns : EntitySchemaField

The schema field to use (default: unchanged)

sortValue
sortValue(_fieldValue: EntityType)

Return a comparable primitive for sorting this field's value in a list column. Return undefined to fall through to the default sort logic. Override this in datatypes that store arrays or complex objects where the raw value cannot be sorted meaningfully.

Parameters :
Name Type Optional
_fieldValue EntityType No
Returns : number | string | undefined
transformToDatabaseFormat
transformToDatabaseFormat(value: EntityType, schemaField?: EntitySchemaField, parent?: Entity)

Transformation function taking a value in the format that is used in entity instances and returning the value in the format used in database objects.

Example :
     This can be set as a parameter to the `@DatabaseField()` annotation in Entity classes.
Parameters :
Name Type Optional Description
value EntityType No

The value (in Entity format) to be transformed

schemaField EntitySchemaField Yes

The EntitySchemaField configuration providing details of how the value should be transformed. This can be set as a parameter to the @DatabaseField() annotation in Entity classes.

parent Entity Yes

The full entity instance this value is part of (e.g. to allow cross-related transformations)

Returns : DBType
transformToObjectFormat
transformToObjectFormat(value: DBType, schemaField?: EntitySchemaField, parent?: any)

Transformation function taking a value in the format that is used in database objects and returning the value in the format used in entity instances.

Example :
     This can be set as a parameter to the `@DatabaseField()` annotation in Entity classes.
Parameters :
Name Type Optional Description
value DBType No

The value (in database format) to be transformed

schemaField EntitySchemaField Yes

The EntitySchemaField configuration providing details of how the value should be transformed. This can be set as a parameter to the @DatabaseField() annotation in Entity classes.

parent any Yes

The full entity instance this value is part of (e.g. to allow cross-related transformations)

Returns : EntityType

Accessors

dataType
getdataType()
label
getlabel()
import { $localize } from "@angular/localize/init"; // import needed to make this file work in e2e test fixtures also
import { EntitySchemaField } from "../schema/entity-schema-field";
import { Entity, EntityConstructor } from "../model/entity";
import { asArray } from "../../../utils/asArray";

/**
 * Definition of an export column contributed by a datatype.
 *
 * Each datatype's `getExportColumns` returns an array of these,
 * fully controlling which CSV columns a field produces.
 */
export interface ExportColumnMapping<EntityType = any> {
  /**
   * Suffix appended to the source field id to build the final export column key.
   * Use an empty string for the primary/default column.
   */
  keySuffix: string;

  /**
   * Human-readable header shown in the exported CSV.
   */
  label: string;

  /**
   * Resolve the value for this export column.
   */
  resolveValue: (
    value: EntityType,
    schemaField: EntitySchemaField,
  ) => Promise<any> | any;
}

/**
 * Extend this class to define new data types (i.e. for properties of entities)
 * and provide your implementation using Angular DI:
 * `{ provide: DefaultDatatype, useClass: MyCustomDatatype, multi: true },`
 *
 * This class is also used as the default fallback Datatype for the EntitySchemaService that keeps values unchanged between database and entity instance.
 * This type is automatically used whenever no fitting Datatype can be found for that config or TypeScript type.
 */
export class DefaultDatatype<EntityType = any, DBType = any> {
  /**
   * Key for this datatype that must be specified in the DatabaseField annotation to use this transformation.
   *
   * for example `@DatabaseField({dataType: 'foo'}) myField` will trigger the datatype implementation with `name` "foo".
   *
   * If you set the name to a TypeScript type, class properties with this type will automatically use
   * that EntitySchemaDatatype without the need to explicitly state the dataType config in the annotation
   * (e.g. `@DatabaseField() myField: string` is triggering the EntitySchemaDatatype with `name` "string".
   */
  static dataType: string = "";

  /**
   * Detect the first field of the given datatype(s) in an entity's schema.
   *
   * Scans the schema for a field whose `dataType` matches one of the provided strings
   * and returns its property name.
   *
   * Subclasses typically override this without the extra `dataTypes` parameter,
   * forwarding their own relevant datatype identifiers.
   *
   * @param entityOrType An entity instance or entity constructor to inspect.
   * @param dataTypes One or more datatype identifiers to match against.
   * @returns The field name of the first matching field, or `undefined` if none is found.
   */
  static detectFieldInEntity(
    entityOrType: Entity | EntityConstructor,
    dataTypes: string | string[],
  ): string | undefined {
    const fields = this.detectAllFieldsInEntity(entityOrType, dataTypes);
    return fields.length > 0 ? fields[0].fieldId : undefined;
  }

  /**
   * Detect all fields of the given datatype(s) in an entity's schema.
   *
   * @param entityOrType An entity instance or entity constructor to inspect.
   * @param dataTypes One or more datatype identifiers to match against.
   * @returns Array of matching fields with their id and schema definition.
   */
  static detectAllFieldsInEntity(
    entityOrType: Entity | EntityConstructor,
    dataTypes: string | string[],
  ): { fieldId: string; schemaField: EntitySchemaField }[] {
    dataTypes = asArray(dataTypes);

    const schema =
      "schema" in entityOrType
        ? (entityOrType as EntityConstructor).schema
        : entityOrType.getConstructor().schema;

    const result: { fieldId: string; schemaField: EntitySchemaField }[] = [];
    for (const [fieldId, field] of schema.entries()) {
      if (dataTypes.includes(field.dataType)) {
        result.push({ fieldId, schemaField: field });
      }
    }
    return result;
  }

  /**
   * Whether this datatype allows multiple values to be mapped to the same entity field
   * during import.
   */
  readonly importAllowsMultiMapping: boolean = false;

  get dataType(): string {
    return (this.constructor as typeof DefaultDatatype).dataType;
  }

  /**
   * The human-readable name for this dataType, used in config UIs.
   */
  static label: string = $localize`:datatype-label:any`;
  get label(): string {
    return (this.constructor as typeof DefaultDatatype).label;
  }

  /**
   * The default component how this datatype should be displayed in lists and forms.
   *
   * The edit component has to be a registered component. Components that are registered contain the `DynamicComponent`
   * decorator
   */
  viewComponent = "DisplayText";
  editComponent = "EditText";

  /**
   * Transformation function taking a value in the format that is used in entity instances and returning the value
   * in the format used in database objects.
   *
   * @param value The value (in Entity format) to be transformed
   * @param schemaField The EntitySchemaField configuration providing details of how the value should be transformed.
   *          This can be set as a parameter to the `@DatabaseField()` annotation in Entity classes.
   * @param parent The full entity instance this value is part of (e.g. to allow cross-related transformations)
   */
  transformToDatabaseFormat(
    value: EntityType,
    schemaField?: EntitySchemaField,
    parent?: Entity,
  ): DBType {
    return value as any;
  }

  /**
   * Transformation function taking a value in the format that is used in database objects and returning the value
   * in the format used in entity instances.
   *
   * @param value The value (in database format) to be transformed
   * @param schemaField The EntitySchemaField configuration providing details of how the value should be transformed.
   *          This can be set as a parameter to the `@DatabaseField()` annotation in Entity classes.
   * @param parent The full entity instance this value is part of (e.g. to allow cross-related transformations)
   */
  transformToObjectFormat(
    value: DBType,
    schemaField?: EntitySchemaField,
    parent?: any,
  ): EntityType {
    return value as any;
  }

  /**
   * The function used to map values from the import data to values in the entities to be created.
   * @param val The value from an imported cell to be mapped
   * @param schemaField The schema field definition for the target property into which the value is mapped
   * @param additional config as returned by the configComponent
   * @param importProcessingContext an object that the datatype can use to store any relevant context across multiple calls
   *                                to share information across processing of multiple columns and rows.
   */
  async importMapFunction(
    val: any,
    schemaField: EntitySchemaField,
    additional?: any,
    importProcessingContext?: any,
  ): Promise<EntityType> {
    return this.transformToObjectFormat(val, schemaField);
  }

  /**
   * A component to be rendered inline to configure the import transformation
   * (e.g. defining a format or value mapping).
   *
   * The component receives inputs:
   * `col`, `rawData`, `entityType`, `otherColumnMappings`, `additionalSettings`, `onColumnMappingChange`
   */
  importConfigComponent?: string;

  /**
   * Return the (potentially adjusted) schema field for this datatype.
   *
   * Called when schema fields are set up (e.g. from config),
   * allowing the datatype to normalize or fill in required settings.
   *
   * Override this in a subclass to enforce constraints
   * (e.g. always setting `isArray: true`).
   *
   * @param schemaField The current schema field definition
   * @returns The schema field to use (default: unchanged)
   */
  normalizeSchemaField(schemaField: EntitySchemaField): EntitySchemaField {
    return schemaField;
  }

  /**
   * Export columns for a field using this datatype.
   *
   * Each returned column contributes a CSV header and its own value resolver.
   * The returned `keySuffix` is appended to the field id to form the exported column key.
   *
   * The default implementation returns a single column with the raw field value.
   * Readable formatting can be applied by callers during CSV transformation.
   * Override this to provide custom or additional columns (e.g. entity references
   * can add a human-readable name column alongside the ID column).
   */
  getExportColumns(
    schemaField: EntitySchemaField,
  ): ExportColumnMapping<EntityType>[] {
    if (!schemaField.label) {
      return [];
    }
    return [
      {
        keySuffix: "",
        label: schemaField.label,
        resolveValue: (value) => value,
      },
    ];
  }

  /**
   * Return a comparable primitive for sorting this field's value in a list column.
   * Return `undefined` to fall through to the default sort logic.
   * Override this in datatypes that store arrays or complex objects where the
   * raw value cannot be sorted meaningfully.
   */
  sortValue(_fieldValue: EntityType): number | string | undefined {
    return undefined;
  }

  /**
   * (Partially) anonymize to "retain-anonymized" for reporting purposes without personal identifiable information.
   * @param value The original value to be anonymized
   */
  async anonymize(
    value: EntityType,
    schemaField: EntitySchemaField,
    parent: any,
  ): Promise<any> {
    return undefined;
  }
}

results matching ""

    No results matching ""