Freedom UI Designer setup area for a custom UI component
This functionality is available for Creatio 8.3.3 and later.
Freedom UI Designer enables no-code creators to build and customize pages without writing code. When developers extended the designer using custom UI components implemented using a remote module, no-code creators could only add those components to a page. Configuring any property of such a component still required a developer to modify the source code of the Freedom UI page directly. This slowed down page iteration and kept no-code creators dependent on development resources for every adjustment.
Since version 8.3.3, Creatio lets developers implement a custom Freedom UI Designer setup area for a custom UI component using a remote module. The setup area can be implemented as part of the same remote module as the UI component itself. A setup area implemented using a remote module behaves the same way as the setup areas of out-of-the-box components:
- Opens in Freedom UI Designer when a user selects the component on the canvas.
- Reads the current component properties from the Freedom UI page schema.
- Saves any changes back to the schema immediately.
- Reflects them on the canvas in real time.
It can expose any properties of the component, giving no-code creators full control over the component configuration directly in the designer.
Detailed example: Implement a custom setup area for a UI component implemented using remote module.
To implement a custom setup area, complete the following steps.
1. Create an Angular project
Develop a custom setup area in a dedicated npm package using an external IDE. This example covers the custom setup area development in Microsoft Visual Studio Code.
You can create an Angular project to develop a custom setup area in multiple ways, similarly to creating an Angular project to develop a custom UI component using a remote module. To do this, follow the instructions: Custom UI component implemented using remote module.
The project must include the @creatio/interface-designer library, which provides the API for interacting with the Freedom UI page schema from the setup area. To install the library, run the npm i @creatio/interface-designer command at the Visual Studio Code terminal.
2. Create the setup area component
-
Run the
ng g c view-elements/some-custom-setup-areacommand in the Visual Studio Code terminal to create an Angular component for the setup area in the project. -
Define the setup area constants. Export constants that define the setup area type identifier, property codes used in the Freedom UI page schema, and default property values.
-
Specify that the setup area component is a view element. Flag the component using the
@CrtViewElementdecorator and set thetypeproperty to the identifier constant of the setup area type.Example that registers the setup area component as a view element@CrtViewElement({
selector: 'usr-some-custom-setup-area',
type: SOME_SETUP_AREA_TYPE_CONSTANT
})
export class SomeCustomSetupAreaComponent implements PropertyPanel { }
3. Implement the business logic of the setup area
-
Add the
viewNodeEditorsetter to implement thePropertyPanelinterface. ThePropertyPanelinterface defines the contract for the setup area implemented using a remote module. The Freedom UI Designer calls theviewNodeEditorsetter when a user selects the component on the canvas.Example that implements the PropertyPanel interfaceimport { ViewNodeEditor } from '@creatio/interface-designer';
export interface PropertyPanel {
/* Provides methods to edit the schema view node for which the property panel
is opened in the Freedom UI Designer. */
set viewNodeEditor(nodeEditor: ViewNodeEditor);
}When switching between components of the same type, Creatio reuses the setup area instance and calls the setter again using a new
ViewNodeEditor. The implementation must handle multiple setter calls on the same instance correctly and reload state each time. To handle this, delegate initialization to a private async method called from the setter.Example that delegates initialization to a private async method@Input()
@CrtInput()
public set viewNodeEditor(nodeEditor: ViewNodeEditor) {
this._init(nodeEditor).catch(
(error) => console.error('Error initializing setup area:', error)
);
} -
Initialize
InterfaceDesignerSchemaServiceto access view model attributes and data sources.Example that initializes InterfaceDesignerSchemaServiceprivate readonly _schemaEditor = new InterfaceDesignerSchemaService().getSchemaEditor();InterfaceDesignerSchemaServiceprovides agetSchemaEditor()method that returns aSchemaEditorwith the following sub-editors. ThegetSchemaEditor()method throws an error if theSchemaEditoris not available. In the designer runtime, this is usually safe when the setup area is instantiated, but keep initialization ordering in mind, especially in tests. The code below shows theSchemaEditorstructure.Example that shows the SchemaEditor structureinterface SchemaEditor {
/* For working with UI elements. */
viewEditor: SchemaViewEditor;
/* For working with the data model. */
modelEditor: SchemaModelEditor;
/* For working with the view model. */
viewModelEditor: SchemaViewModelEditor;
} -
Implement the method that reads the current property values from the Freedom UI page schema asynchronously on setup area initialization. Use
ViewNodeEditorto read and write property values through the methods described in the table below.Method
Description
getPropertyValue(propertyName)
Reads the current value of a property.
setPropertyValue(propertyName, options)
Writes a new value to a property.
Both methods are asynchronous and return promises. Always use
awaitwhen calling them.A property value is a typified object that describes how a value is assigned in the schema. The table below lists the available property value types and how each type appears in the JSON of Freedom UI page schema.
Type
Description
Example of schema JSON
Constant
A literal value stored directly in the schema (a
string,number,boolean, orobject).{
"text": "32",
"visible": true
}Attribute binding
A reference to a view model attribute, prefixed using
$in the schema JSON.{
"control": "$Account.Name"
}Resource binding
A reference to a localization string, prefixed using
$Resources.Strings.in the schema JSON.{
"label": "$Resources.Strings.SaveButton_caption"
}Request binding
A reference to a request handler, stored as an object that has
requestand optionalparamsfields.{
"clicked": {
"request": "crt.SaveRecordRequest",
"params": {}
}
}Use optional chaining and default values when reading property values to avoid runtime errors if a property has not been set:
const value = propertyValue?.value ?? defaultValue. -
Implement the method that writes the updated property values back to the schema when the user changes a field. When you call
setPropertyValue, pass one of the following options in theoptionsparameter.Example that sets property values of different types/* Set a constant value. */
await this._viewNodeEditor.setPropertyValue('text', { constant: 'Some string' });
/* Bind to a view model attribute. */
await this._viewNodeEditor.setPropertyValue('value', { bindToAttribute: 'Account.Name' });
/* Bind to a localized resource. */
await this._viewNodeEditor.setPropertyValue('caption', { bindToResource: 'AccountCaption' });
/* Bind to a request. */
await this._viewNodeEditor.setPropertyValue('clicked', {
bindToRequest: {
request: 'crt.SaveRecordRequest',
params: { someParam: 'someValue' },
},
});The
bindToRequestoption accepts aRequestBindingOptionsobject with the following properties.RequestBindingOptions interfaceinterface RequestBindingOptions {
request: string;
params?: Record<string, JsonData>;
}setPropertyValuereturns a typified object that reflects the value written to the schema. The returned object includes atypefield and type-specific fields such asvalue,attributePath,resourcePath, orrequestType, depending on the binding type used.To clear a property, set it to a null constant:
setPropertyValue(name, { constant: null }).To bind a property to a view model attribute, for example, a value that maps to a data source column, use
viewModelEditorto manage view model attributes. The table below lists the key methods ofviewModelEditor. All methods are asynchronous and return promises. Always useawaitwhen calling them.Method
Description
getAttributeEditor(name)
Returns an attribute editor, or
undefinedif the attribute does not exist.createAttribute(name, options)
Creates a new attribute. Throws if the attribute already exists — remove it first using
removeAttribute().canRemoveAttribute(name)
Checks whether an attribute can be safely removed.
removeAttribute(name)
Deletes an attribute.
To bind a new attribute to a data source column, use
createAttributewith abindToModeloption. Before you bind, verify that the target data source exists usingmodelEditor.getDataSourceEditor(dataSourceName). The code below shows how to create an attribute with a model binding.Example that creates an attribute with a model bindingconst dataSource = await modelEditor.getDataSourceEditor(dataSourceName);
if (dataSource?.dataSourceType === DataSourceType.EntityDataSource) {
await viewModelEditor.createAttribute('MyAttribute', {
bindToModel: { dataSourceName: dataSourceName, dataSourceAttributePath: 'Name' }
});
}
4. Add the setup area to the Freedom UI Designer
-
Create a design-time Angular module.
- Go to the "src/app" directory and create the design-time module file.
- Add the setup area component to the
@CrtModuledecorator so that the Freedom UI Designer can display it when a user selects the UI component on the canvas. - Declare the setup area component in the
@NgModuledecorator and allow custom element schemas.
Example that creates a design-time Angular module/* Register SomeCustomSetupAreaComponent as a view element so that the Freedom UI Designer
can display it as a setup area when a user selects the UI component on the canvas. */
@CrtModule({
viewElements: [SomeCustomSetupAreaComponent],
})
/* Declare SomeCustomSetupAreaComponent in the Angular module and allow custom element schemas. */
@NgModule({
declarations: [SomeCustomSetupAreaComponent],
imports: [CommonModule],
exports: [SomeCustomSetupAreaComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class SomeDesignTimeModule { } -
Register the setup area component as a custom element so that the browser can render it inside Freedom UI Designer.
- Call
createCustomElementin the module constructor to convert the setup area component to a custom element. - Define
createCustomElementin the browser registry usingcustomElements.define.
Example that registers the setup area component as a custom elementconstructor() {
/* Register SomeCustomSetupAreaComponent as a custom element on module initialization. */
this._registerCustomElement('usr-some-custom-setup-area', SomeCustomSetupAreaComponent);
}
private _registerCustomElement(selector: string, component: Type): void {
if (!customElements.get(selector)) {
/* Convert the Angular component to a custom element and define it in the browser registry. */
const elementConstructor = createCustomElement(component, { injector: this._injector });
customElements.define(selector, elementConstructor);
}
} - Call
-
Import the design-time module into the "app.module.ts" file. To do this, add the design-time module to the
importsarray of the@NgModuledecorator.Example that imports the design-time module into the "app.module.ts" file@NgModule({
declarations: [SomeCustomComponent],
imports: [BrowserModule, SomeDesignTimeModule],
providers: [],
})
export class AppModule implements DoBootstrap { }
5. Link the setup area to the custom UI component
-
Open the
some-ui-component.component.tsfile that implements the functionality of the UI component. -
Set the
propertiesPanelproperty to the setup area type identifier in the@CrtInterfaceDesignerItemdecorator. The value must match thetypedefined in the@CrtViewElementdecorator of the setup area component.Example that links the setup area to the UI component@CrtInterfaceDesignerItem({
propertiesPanel: SOME_SETUP_AREA_TYPE_CONSTANT,
})When a user selects the UI component in the Freedom UI Designer, Creatio finds the registered setup area by that identifier and instantiates it.
As a result, the custom setup area will appear in Freedom UI Designer when a user selects the UI component on the canvas. No-code creators will be able to configure the component properties directly in the designer without modifying the Freedom UI page schema manually.
See also
Custom UI component implemented using remote module
Implement a custom setup area for a UI component implemented using remote module