src/app/core/basic-datatypes/schema-embed/schema-embed.datatype.ts
Datatype for the EntitySchemaService transforming values of complex objects recursively.
Can be used in two ways:
dataType: "schema-embed" and define the inner schema
in additional as a SchemaEmbedDatatypeAdditional map.embeddedType to point to a class
with @DatabaseField() annotations.The config in additional is merged with the embeddedType schema (if present),
allowing runtime config to extend or override a class's annotations.
Properties |
|
Methods |
| transformToDatabaseFormat | |||||||||
transformToDatabaseFormat(value: EntityType, schemaField?: EntitySchemaField)
|
|||||||||
|
Inherited from
DefaultDatatype
|
|||||||||
|
Defined in
DefaultDatatype:92
|
|||||||||
|
Parameters :
Returns :
DBType
|
| transformToObjectFormat | |||||||||
transformToObjectFormat(value: DBType, schemaField?: EntitySchemaField)
|
|||||||||
|
Inherited from
DefaultDatatype
|
|||||||||
|
Defined in
DefaultDatatype:103
|
|||||||||
|
Parameters :
Returns :
EntityType
|
| Async anonymize | ||||||||||||||||
anonymize(value: EntityType, schemaField: EntitySchemaField, parent: any)
|
||||||||||||||||
|
Inherited from
DefaultDatatype
|
||||||||||||||||
|
Defined in
DefaultDatatype:190
|
||||||||||||||||
|
(Partially) anonymize to "retain-anonymized" for reporting purposes without personal identifiable information.
Parameters :
Returns :
Promise<any>
|
| Static detectFieldInEntity | ||||||||||||
detectFieldInEntity(entityOrType: Entity | EntityConstructor, dataTypes: string | string[])
|
||||||||||||
|
Inherited from
DefaultDatatype
|
||||||||||||
|
Defined in
DefaultDatatype:57
|
||||||||||||
|
Detect the first field of the given datatype(s) in an entity's schema. Scans the schema for a field whose Subclasses typically override this without the extra
Parameters :
Returns :
string | undefined
The field name of the first matching field, or |
| importIncompleteAdditionalConfigBadge | ||||||
importIncompleteAdditionalConfigBadge(col: ColumnMapping)
|
||||||
|
Inherited from
DefaultDatatype
|
||||||
|
Defined in
DefaultDatatype:166
|
||||||
|
Output a label indicating whether the given column mapping needs user configuration for the "additional" config or has a valid, complete "additional" config. returns "undefined" if no user action is required.
Parameters :
Returns :
string
|
| Async importMapFunction | ||||||||||||||||||||
importMapFunction(val: any, schemaField: EntitySchemaField, additional?: any, importProcessingContext?: any)
|
||||||||||||||||||||
|
Inherited from
DefaultDatatype
|
||||||||||||||||||||
|
Defined in
DefaultDatatype:145
|
||||||||||||||||||||
|
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 :
Returns :
Promise<EntityType>
|
| normalizeSchemaField | ||||||||
normalizeSchemaField(schemaField: EntitySchemaField)
|
||||||||
|
Inherited from
DefaultDatatype
|
||||||||
|
Defined in
DefaultDatatype:182
|
||||||||
|
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
Parameters :
Returns :
EntitySchemaField
The schema field to use (default: unchanged) |
| Static Readonly dataType |
Type : string
|
Default value : "schema-embed"
|
|
Inherited from
DefaultDatatype
|
|
Defined in
DefaultDatatype:66
|
| Optional embeddedType |
Type : SchemaEmbeddedType<EntityType>
|
| Protected Readonly schemaService |
Type : unknown
|
Default value : inject(EntitySchemaService)
|
| editComponent |
Type : string
|
Default value : "EditText"
|
|
Inherited from
DefaultDatatype
|
|
Defined in
DefaultDatatype:101
|
| Readonly importAllowsMultiMapping |
Type : boolean
|
Default value : false
|
|
Inherited from
DefaultDatatype
|
|
Defined in
DefaultDatatype:80
|
|
Whether this datatype allows multiple values to be mapped to the same entity field during import. |
| Optional importConfigComponent |
Type : string
|
|
Inherited from
DefaultDatatype
|
|
Defined in
DefaultDatatype:158
|
|
A component to be display as a dialog to configure the transformation function (e.g. defining a format or mapping) |
| Static label |
Type : string
|
Default value : $localize`:datatype-label:any`
|
|
Inherited from
DefaultDatatype
|
|
Defined in
DefaultDatatype:89
|
|
The human-readable name for this dataType, used in config UIs. |
| viewComponent |
Type : string
|
Default value : "DisplayText"
|
|
Inherited from
DefaultDatatype
|
|
Defined in
DefaultDatatype:100
|
|
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 |
import { DefaultDatatype } from "../../entity/default-datatype/default.datatype";
import { EntitySchemaService } from "../../entity/schema/entity-schema.service";
import { EntitySchemaField } from "../../entity/schema/entity-schema-field";
import {
EntitySchema,
SchemaEmbeddedType,
} from "../../entity/schema/entity-schema";
import { inject, Injectable } from "@angular/core";
/**
* Configuration for the "schema-embed" datatype's `additional` field.
*
* Defines the inner schema of the embedded object, using the same format as
* entity `attributes` config: a map of field names to their schema definitions.
*
* @example
* ```
* @DatabaseField({
* dataType: "schema-embed",
* additional: {
* "phoneNumber": { dataType: "string" },
* "type": { dataType: "string" }
* } as SchemaEmbedDatatypeAdditional
* })
* phoneNumber: { phoneNumber: string; type: string };
* ```
*/
export interface SchemaEmbedDatatypeAdditional {
[fieldId: string]: EntitySchemaField;
}
/**
* Datatype for the EntitySchemaService transforming values of complex objects recursively.
*
* Can be used in two ways:
* 1. **Config-based** (directly via annotation): Set `dataType: "schema-embed"` and define the inner schema
* in `additional` as a {@link SchemaEmbedDatatypeAdditional} map.
* 2. **Subclass-based** (extending this class): Override `embeddedType` to point to a class
* with `@DatabaseField()` annotations.
*
* The config in `additional` is merged with the `embeddedType` schema (if present),
* allowing runtime config to extend or override a class's annotations.
*/
@Injectable()
export class SchemaEmbedDatatype<
EntityType = any,
DBType = any,
> extends DefaultDatatype<EntityType, DBType> {
static override readonly dataType: string = "schema-embed";
embeddedType?: SchemaEmbeddedType<EntityType>;
protected readonly schemaService = inject(EntitySchemaService);
/**
* Build the effective inner schema from the embedded type's annotations
* and/or the `additional` config.
*/
private getEffectiveSchema(schemaField?: EntitySchemaField): EntitySchema {
// Clone the base schema to avoid mutating the original class schema
const baseSchema: EntitySchema = new Map(
this.embeddedType?.schema ?? new Map(),
);
const additional: SchemaEmbedDatatypeAdditional =
schemaField?.additional ?? {};
// Add schema from additional config, taking precedence over baseSchema if present
for (const [key, value] of Object.entries(additional)) {
baseSchema.set(key, { ...value, id: key });
}
return baseSchema;
}
override transformToDatabaseFormat(
value: EntityType,
schemaField?: EntitySchemaField,
): DBType {
const schema = this.getEffectiveSchema(schemaField);
return this.schemaService.transformEntityToDatabaseFormat(
value as any,
schema,
) as DBType;
}
override transformToObjectFormat(
value: DBType,
schemaField?: EntitySchemaField,
): EntityType {
const schema = this.getEffectiveSchema(schemaField);
const transformedValue =
this.schemaService.transformDatabaseToEntityFormat<EntityType>(
value,
schema,
);
if (this.embeddedType) {
const instance = new this.embeddedType();
Object.assign(instance, transformedValue);
return instance;
}
return transformedValue;
}
}