diff --git a/src/app/core/common-components/basic-autocomplete/custom-form-control.directive.ts b/src/app/core/common-components/basic-autocomplete/custom-form-control.directive.ts index f7985ffff8..64f197e6ed 100644 --- a/src/app/core/common-components/basic-autocomplete/custom-form-control.directive.ts +++ b/src/app/core/common-components/basic-autocomplete/custom-form-control.directive.ts @@ -11,9 +11,11 @@ import { Directive, DoCheck, ElementRef, + EventEmitter, HostBinding, Input, OnDestroy, + Output, } from "@angular/core"; import { Subject } from "rxjs"; import { coerceBooleanProperty } from "@angular/cdk/coercion"; @@ -34,10 +36,12 @@ export abstract class CustomFormControlDirective get required() { return this._required; } + set required(req: boolean) { this._required = coerceBooleanProperty(req); this.stateChanges.next(); } + private _required = false; stateChanges = new Subject(); @@ -80,6 +84,8 @@ export abstract class CustomFormControlDirective _value: T; + @Output() valueChange = new EventEmitter(); + constructor( public elementRef: ElementRef, public errorStateMatcher: ErrorStateMatcher, @@ -126,6 +132,7 @@ export abstract class CustomFormControlDirective writeValue(val: T): void { this.value = val; + this.valueChange.emit(val); } registerOnChange(fn: any): void { diff --git a/src/app/core/entity/entity-field-select/entity-field-select.component.ts b/src/app/core/entity/entity-field-select/entity-field-select.component.ts index eb0cf04921..6377546fcd 100644 --- a/src/app/core/entity/entity-field-select/entity-field-select.component.ts +++ b/src/app/core/entity/entity-field-select/entity-field-select.component.ts @@ -6,9 +6,8 @@ import { } from "app/core/common-components/basic-autocomplete/basic-autocomplete.component"; import { EntityConstructor } from "../model/entity"; import { EntityRegistry } from "../database-entity.decorator"; -import { EntitySchemaService } from "../schema/entity-schema.service"; -import { DefaultDatatype } from "../default-datatype/default.datatype"; import { EntitySchema } from "../schema/entity-schema"; +import { FormFieldConfig } from "../../common-components/entity-form/FormConfig"; @Component({ selector: "app-entity-field-select", @@ -20,41 +19,38 @@ import { EntitySchema } from "../schema/entity-schema"; { provide: MatFormFieldControl, useExisting: EntityFieldSelectComponent }, ], }) -export class EntityFieldSelectComponent extends BasicAutocompleteComponent { - private entityCtor: EntityConstructor; +export class EntityFieldSelectComponent extends BasicAutocompleteComponent< + FormFieldConfig, + string +> { @Input() override placeholder: string = - $localize`:EntityFieldSelect placeholder: Select Entity Field`; + $localize`:EntityFieldSelect placeholder:Select Entity Field`; - override optionToString = (option: string) => - this.entityCtor.schema.get(option).label; - dataTypeMap: { [name: string]: DefaultDatatype }; - selectedEntityField: string; - @Input() override hideOption: (option: string) => boolean; + override optionToString = (option: FormFieldConfig) => option.label; + override valueMapper = (option: FormFieldConfig) => option.id; - private entityRegistry = inject(EntityRegistry); - private entitySchemaService = inject(EntitySchemaService); + @Input() override hideOption: (option: FormFieldConfig) => boolean; - @Input() set entityType(entity: string) { + @Input() set entityType(entity: string | EntityConstructor) { if (!entity) { return; } - this.initializeEntity(entity); - } + if (typeof entity === "string") { + this._entityType = this.entityRegistry.get(entity); + } else { + this._entityType = entity; + } - private initializeEntity(entity: string): void { - this.entityCtor = this.entityRegistry.get(entity); - this.dataTypeMap = {}; - this.options = this.getAllFieldProps(this.entityCtor.schema); + this.options = this.getAllFieldProps(this._entityType.schema); } - private getAllFieldProps(schema: EntitySchema): string[] { + private _entityType: EntityConstructor; + + private entityRegistry = inject(EntityRegistry); + + private getAllFieldProps(schema: EntitySchema): FormFieldConfig[] { return [...schema.entries()] .filter(([_, fieldSchema]) => fieldSchema.label) - .map(([name, fieldSchema]) => { - this.dataTypeMap[name] = this.entitySchemaService.getDatatypeOrDefault( - fieldSchema.dataType, - ); - return name; - }); + .map(([name, fieldSchema]) => ({ ...fieldSchema, id: name })); } } diff --git a/src/app/core/import/import-column-mapping/import-column-mapping.component.html b/src/app/core/import/import-column-mapping/import-column-mapping.component.html index 5e40843765..dd173cdaa5 100644 --- a/src/app/core/import/import-column-mapping/import-column-mapping.component.html +++ b/src/app/core/import/import-column-mapping/import-column-mapping.component.html @@ -16,28 +16,28 @@
{{ col.column }} - - + @if (dataTypeMap[col.propertyName]?.importConfigComponent) { + + }
diff --git a/src/app/core/import/import-column-mapping/import-column-mapping.component.ts b/src/app/core/import/import-column-mapping/import-column-mapping.component.ts index 4edebf6cfa..f8e82ac1a4 100644 --- a/src/app/core/import/import-column-mapping/import-column-mapping.component.ts +++ b/src/app/core/import/import-column-mapping/import-column-mapping.component.ts @@ -11,9 +11,9 @@ import { EntityRegistry } from "../../entity/database-entity.decorator"; import { EntityConstructor } from "../../entity/model/entity"; import { MatDialog } from "@angular/material/dialog"; import { HelpButtonComponent } from "../../common-components/help-button/help-button.component"; -import { NgForOf, NgIf } from "@angular/common"; +import { NgForOf } from "@angular/common"; import { MatInputModule } from "@angular/material/input"; -import { BasicAutocompleteComponent } from "../../common-components/basic-autocomplete/basic-autocomplete.component"; +import { EntityFieldSelectComponent } from "../../entity/entity-field-select/entity-field-select.component"; import { FormsModule } from "@angular/forms"; import { MatButtonModule } from "@angular/material/button"; import { MatBadgeModule } from "@angular/material/badge"; @@ -21,6 +21,7 @@ import { EntitySchemaService } from "../../entity/schema/entity-schema.service"; import { ComponentRegistry } from "../../../dynamic-components"; import { DefaultDatatype } from "../../entity/default-datatype/default.datatype"; import { ImportColumnMappingService } from "./import-column-mapping.service"; +import { FormFieldConfig } from "../../common-components/entity-form/FormConfig"; /** * Import sub-step: Let user map columns from import data to entity properties @@ -35,10 +36,9 @@ import { ImportColumnMappingService } from "./import-column-mapping.service"; HelpButtonComponent, NgForOf, MatInputModule, - BasicAutocompleteComponent, + EntityFieldSelectComponent, FormsModule, MatButtonModule, - NgIf, MatBadgeModule, ], }) @@ -47,6 +47,8 @@ export class ImportColumnMappingComponent implements OnChanges { @Input() columnMapping: ColumnMapping[] = []; @Output() columnMappingChange = new EventEmitter(); + entityCtor: EntityConstructor; + @Input() set entityType(value: string) { if (!value) { return; @@ -54,30 +56,24 @@ export class ImportColumnMappingComponent implements OnChanges { this.entityCtor = this.entities.get(value); this.dataTypeMap = {}; - this.allProps = [...this.entityCtor.schema.entries()] + + [...this.entityCtor.schema.entries()] .filter(([_, schema]) => schema.label) .map(([name, schema]) => { this.dataTypeMap[name] = this.schemaService.getDatatypeOrDefault( schema.dataType, ); - return name; }); } - private entityCtor: EntityConstructor; - - /** entity properties that have a label */ - allProps: string[] = []; - /** properties that need further adjustments through a component */ dataTypeMap: { [name: string]: DefaultDatatype }; /** warning label badges for a mapped column that requires user configuration for the "additional" details */ mappingAdditionalWarning: { [key: string]: string } = {}; - labelMapper = (name: string) => this.entityCtor.schema.get(name).label; - isUsed = (option: string) => - this.columnMapping.some(({ propertyName }) => propertyName === option); + isUsed = (option: FormFieldConfig) => + this.columnMapping.some(({ propertyName }) => propertyName === option.id); constructor( private entities: EntityRegistry, diff --git a/src/app/features/notification/notification-rule/notification-rule.component.html b/src/app/features/notification/notification-rule/notification-rule.component.html index d0d4f2b233..1ef10f9d77 100644 --- a/src/app/features/notification/notification-rule/notification-rule.component.html +++ b/src/app/features/notification/notification-rule/notification-rule.component.html @@ -13,11 +13,13 @@
- + Select an entity type