import { Injectable } from "@angular/core" ; import { FormBuilder , FormGroup , Validators } from "@angular/forms" ; import { FormFieldConfig } from "./entity-form/FormConfig" ; import { Entity } from "../../entity/model/entity" ; import { EntityMapperService } from "../../entity/entity-mapper.service" ; import { EntitySchemaService } from "../../entity/schema/entity-schema.service" ; @ Injectable ( ) export class EntityFormService { constructor ( private fb , private entityMapper , private entitySchemaService ) { } public extendFormFieldConfig ( formFields , entity , forTable = false ) { formFields . forEach ( ( formField ) => { try { this . addFormFields ( formField , entity , forTable ) ; } catch ( err ) { throw new Error ( `Could not create form config for ${ formField . id }: ${ err }` ) ; } } ) ; } private addFormFields ( formField , entity , forTable ) { const propertySchema = entity . getSchema ( ) . get ( formField . id ) ; formField . edit = formField . edit || this . entitySchemaService . getComponent ( propertySchema , "edit" ) ; formField . view = formField . view || this . entitySchemaService . getComponent ( propertySchema , "view" ) ; formField . tooltip = formField . tooltip || propertySchema ?. description ; if ( forTable ) { formField . forTable = true ; formField . label = formField . label || propertySchema . labelShort || propertySchema . label ; } else { formField . forTable = false ; formField . label = formField . label || propertySchema . label || propertySchema . labelShort ; } } public createFormGroup ( formFields , entity ) { const formConfig = { } ; const entitySchema = entity . getSchema ( ) ; formFields . forEach ( ( formField ) => { const propertySchema = entitySchema . get ( formField . id ) ; if ( propertySchema ) { formConfig [ formField . id ] = [ entity [ formField . id ] ] ; if ( formField . required || propertySchema ?. required ) { formConfig [ formField . id ] . push ( Validators . required ) ; } } } ) ; return this . fb . group ( formConfig ) ; } param form param entity returns public saveChanges < T extends Entity > ( form , entity ) { this . checkFormValidity ( form ) ; const entityCopy = entity . copy ( ) as T ; this . assignFormValuesToEntity ( form , entityCopy ) ; entityCopy . assertValid ( ) ; return this . entityMapper . save ( entityCopy ) . then ( ( ) => Object . assign ( entity , entityCopy ) ) . catch ( ( err ) => { throw new Error ( `Could not save ${ entity . getType ( ) }: ${ err }` ) ; } ) ; } private checkFormValidity ( form ) { form . markAllAsTouched ( ) ; if ( form . invalid ) { const invalidFields = this . getInvalidFields ( form ) ; throw new Error ( `Fields: "${ invalidFields }" are invalid` ) ; } } private getInvalidFields ( form ) { const invalid = [ ] ; const controls = form . controls ; for ( const field in controls ) { if ( controls [ field ] . invalid ) { invalid . push ( field ) ; } } return invalid . join ( ", " ) ; } private assignFormValuesToEntity ( form , entity ) { Object . keys ( form . controls ) . forEach ( ( key ) => { entity [ key ] = form . get ( key ) . value ; } ) ; } }