Dynamic forms (eav)
Dynamic forms are used for:
- extending standard entity attributes with custom, project specific attributes,
- dynamic configurations - e.g. system connector configurations.
Dynamic forms are supported for selected entities:
SysSystem
- linked to the systemsIdmIdentity
- identitiesIdmIdentityContract
- Contractual relationshipsIdmRole
- rolesIdmTreeNode
- tree structure items.
Dynamic form instances (values) are saved in the individual tables according to the entity which they are linked to ⇒ which is their owner (e.g. the entity IdmIdentityForlmValue
, IdmRoleFormValue
).
FormService
service for working with the extended attributes on the back-end.
EavForm
.
Dynamic form attribute supports data types (persistentType
):
CHAR
- one characterTEXT
- stringsINT
- integerLONG
- longDOUBLE
- saved as bigdecimalBOOLEAN
- true / false / nullDATE
- date (without time)DATETIME
- date with timeBYTEARRAY
- byte[]UUID
- uuid identifier
with properties:
required
readonly
multi values
- Is represented on the front-end by a textarea, where a line is a value (a new line separates the values). This property is supported for persistent typesCHAR
,TEXT
,INT
,LONG
,DOUBLE
andUUID
.confidential
- .The values are stored in an confidential storage). Stored values of these attributes - substitute characters only - are loaded on the front-end. The value can only be changed and determined whether it is filled in. This property is supported for persistent typesCHAR
,TEXT
,INT
,LONG
,DOUBLE
,UUID
,BYTEARRAY
.
Dynamic form attribute can be rendered differently on frontend. Face type (faceType) property is used for choosing frontend renderer. Default renderer is chosen by persistent type (e.g. UUID → UUID).
Renderer is frontend component, superclass component AbstractFormAttributeRenderer
is used for all renderer implementations. Renderer is responsible for IdmFormValue ⇔ input value
transformation.
Renderers are registered in module's component-descriptor.js
as single component with attributes:
id
- unique component identifiertype
=form-value
- static component type is used for allform-value
rendererpersistentType
- which persistent type renderer supportsfaceType
- renderer face type ⇒ key. Unique face type should be given (by persistent type). Its optionalpersistentType
is used as default, when nofaceType
is given.component
- renderer implementation (AbstractFormAttributeRenderer
descendant).labelKey
- localization key ⇒ renderer name. Its optional,faceType
is used, when nolabelKey
is given.
All component descriptor features are supported. Read tutorial, how to create custom form attribute renderer.
Adding the support of extended attributes for a new entity
Backend
- Adding an interface implementation
FormableEntity
to the new entity, - creating a manager implementation by inheriting
AbstractFormableService
for the new entity, - creating the entity by inheriting
AbstractFormValue
, which will represent the values of extended attributes for the new entity (owner), - creating a repository by inheriting
AbstractFormValueRepository
for the values of the extended attributes, - creating the manager by inheriting
AbstractFormValueService
for the values of the extended attributes.
Frontend
- issuing a REST endpoint for saving the extended attributes from the FE - e.g.
IdmIdentityController
- controller has to evaluate security to read / save form values by their owner (e.g. by identity), - creating a service and redux manager communicating with REST by inheriting
FormableEntityManager
- e.g.IdentityManager
, - using the component
EavForm
for filling in and sending the values of the extended attributes from the FE to the BE - e.g.IdentityEav
content.
Agenda for working with forms
On the FE, there is an agenda of forms - their definition and attributes. Each definition can contain zero or more attributes. To maintain the integrity, an interface UnmodifiableEntity has been created, which allows adding a flag that the entity has been created by the system and cannot be modified (or some of its attributes) and deleted (this logic now needs to be implemented manually into the relevant controllers), for example in IdmFormAttributeController.
It is necessary to be cautious when editing individual form attributes as the logic linked to this form can be rendered non-functional.
persistentType
or confidential
is changed is not supported now.
Common forms
Common forms is used for saving internal dynamic forms for: - report filters - long running task properties (comming soon) - authorization policiy properties (comming soon)
Form has to have form definition and owner, which can be an entity implementing FormableEntity
interface. One owner can have more forms. When owner is deleted, then all forms have to be deleted to - override owner's service delete method properly. Form can be shared between owners - e.g. report filter can be used as input (properties) for long running task - this is the main reason, why common forms exists, don't use this common forms for storing extended attributes mentioned above (e.g. they will not be shown on frontend).
Future development
- API for saving the owner and the eav form in one transaction (⇒ save
IdmFormInstance
). - Attribute properties validation - by supported persistent type (see above).
- Form value data migration, when persistent type is changed.
- Split
TEXT
andLONGTEXT
persistent type -TEXT
will be indexed varchar(xxx).