Admin UI
Edit / Create View Configuration

Edit / Create Action | Form View

The edit and create views both show a form component and are quite similar.

The actions behave as follows:

Save

  • checks required values, continues only if all required validations pass
  • calls save mutation
    • if mutation validation returns validationErrors - shows validation errors at the fields
    • if mutation was successful - redirects to show action

Cancel

  • redirects to show action without any further action

Form

Both actions will query all necessary data to render the form:

  • all attributes (per configuration)
  • all assocTo and assocToMany relationships that are referenced by this entity's item
  • all items for any assocTo and assocToMany relationships to populate the select / autocomplete controls (if this would be too much data, consider providing a custom query or - as always - implementing this in a custom component.)

Configuration

Optiontypedefaultdescription
fields(string|FieldConfig)[]see belowwhat fields to show in the form and what control to use to capture input
queryQueryFncustom query for all form data
queryQueryFncustom query for all form data

FieldConfig

Optiontypedefaultdescription
namestringthe name of the attribute or entity of the assoc or assocToMany
typestringthe type from the domain configurationthe type of the attribute or entity of the assoc
labelstring | ()=>stringlookup in resources or humanized field namethe column label for the field
listbooleandependent from the attribute / assoc type in the domainConfigurationthe column label for the field
prepareFormInputFunctioncalled before setting the field value in form
sanitizeFormInputFunctioncalled before setting the field value in the save mutation
disabledbooleanfalsedisable input / read-only field
requiredbooleanfalseadds client-side required validation to field
listbooleanvalue from domain configuration for fieldeffect on control
query`()=>stringany`part of query for this field, especially lookup
controlstringwhich control should be used to render this field / assoc
options(data:any)=>FormOptionType[]generates the form options (if this is lookup field) from the data of the action query

Label

If you do not provide a label, the default label will be looked up under this path in the resources of the AdminConfig.

['resources', locale, 'entities', entity, 'label', field]

If no such entry exists, the humanized attribute name of the entity or the humanized name of the assoc entity will be used.

prepareFormInput / sanitizeFormInput

You can influence the value from the GraphQL API before it is presented to the user. Let's take as an example the price of a car. You decided in you entity configuration to manage the price of a car as an integer (of the smalles currency unit) e.g. cents instead of a float to avoid round issues and having to deal with fixed decimals on the server.

entity:
  Car: 
    attributes:
      license: Key
      price: Int      

In your UI nonetheless you want to present the user with the € value. So we have to calculate this value before it is set to the form. We also have to calculate the Int value from the € before sending it to the save mutation. Of course, the usage of lodash (opens in a new tab) is absolutely optional.

const adminConfig:AdminConfig = {
  entities: {
    Car: {
      edit: {
        fields: [
          'license',
          { 
            name: price, 
            prepareFormInput: (value:any) => ( _.toNumber(value) / 100 ).toFixed(2),
            sanitizeFormInput: (value:any) => _.round( _.toNumber( value ) * 100 )
          }
        ]
      }
    }
  }
}

control

defaultimplementation
select{list:true}mat-select (opens in a new tab) or mat-autocomplete (opens in a new tab) if more then configured items
multipleassocToManymat-select (opens in a new tab)
number{type:'Int'|'Float'}matInput (opens in a new tab)
datepicker{type:'Date'|'DateTime'}matDatepicker (opens in a new tab)
file{type:'File'}<input type="file">
richtext{mediaType:'richtext'}ngx-quill (opens in a new tab)
chipsmat-chip-list (opens in a new tab)
[any other]matInput (opens in a new tab)

If you need any other control, you have to create a custom route / custom component and implement the (whole) form yourself.