Freedom UI Designer setup area for a custom Freedom UI component
This functionality is available for Creatio 8.3.3 and later.
The Freedom UI Designer lets no-code creators build and customize pages without writing code. When developers extended the designer with custom Freedom UI components, no-code creators could only add those components to a page. Configuring any property of such a component required a developer to modify the source code of the Freedom UI page directly.
Since version 8.3.3, Creatio lets developers implement a custom setup area for a custom Freedom UI component using a remote module. The setup area can be implemented as part of the same remote module as the corresponding Freedom 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 the Freedom UI Designer when a user selects the corresponding Freedom UI component on the canvas.
- Reads the current component properties from the Freedom UI page schema.
- Stores 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.
Example: Implement a Freedom UI Designer setup area for a custom Freedom UI component.
To implement a custom setup area for a custom Freedom UI component, complete the following steps.
1. Create an Angular project
To create an Angular project to develop a custom setup area, follow the instructions: Create an Angular project.
2. Install npm packages
To install npm packages, follow the instructions: Install npm packages.
3. Create a custom Freedom UI component
To implement a custom Freedom UI component, follow the instructions: Custom Freedom UI component implemented using remote module.
4. Create the setup area component
-
Ensure the project includes the "AGENTS.md" file. Instructions: Create a custom Freedom UI component (step 1).
-
For Creatio version 8.3.4 and later, run the
ng g c features/design/property-panels/some-component-setup-areacommand in the Visual Studio Code terminal to create an Angular class in the project, wheresome-component-setup-areais a custom class name. This adds theSomeComponentSetupAreaComponentclass files to the "src/app/features/design/property-panels" project directory.For Creatio version 8.3.3 only
Run the
ng g c view-elements/some-component-setup-areacommand in the Visual Studio Code terminal to create an Angular class in the project, wheresome-component-setup-areais a custom class name. This adds theSomeComponentSetupAreaComponentclass files to the "src/app" project directory. -
Define the component constants.
-
For Creatio version 8.3.4 and later, go to the "src/app/features/runtime/view-elements/some-component-setup-area" directory.
For Creatio version 8.3.3 only
Go to the "src/app/" directory.
-
Create the "some-component-setup-area.constants.ts" file.
-
Open the "some-component-setup-area.constants.ts" file.
-
Export the following constants that define:
- setup area type, for example,
SOME_SETUP_AREA_TYPE_CONSTANT - property codes, for example,
SOME_PROPERTY_CODE - default property values, for example,
SOME_DEFAULT_VALUE
- setup area type, for example,
-
Save the file.
-
-
Specify that the
SomeComponentSetupAreaComponentis a view element.- Open the "some-component-setup-area.component.ts" file.
- Flag the component using the
@CrtViewElementdecorator. - Import the required functionality from the libraries into the file.
- Save the file.
"some-component-setup-area.component.ts" file/* Import the required functionality from the libraries. */import {CrtViewElement} from '@creatio-devkit/common';/* Define the setup area type identifier. */export const SOME_SETUP_AREA_TYPE_CONSTANT = 'usr.SomeComponentSetupArea';/* Define the property codes used in the Freedom UI page schema. */export const SOME_PROPERTY_CODE = 'someProperty';/* Define the default property values. */export const SOME_DEFAULT_VALUE = 'someDefaultValue';@CrtViewElement({selector: 'usr-some-component-setup-area-component',type: SOME_SETUP_AREA_TYPE_CONSTANT})export class SomeComponentSetupAreaComponent { }
5. Implement the business logic of the setup area component
-
Open the "some-component-setup-area.component.ts" file.
-
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 corresponding Freedom UI component on the canvas."some-component-setup-area.component.ts" fileimport { ViewNodeEditor } from '@creatio/interface-designer';export interface PropertyPanel {/* Provides methods to edit the schema view node the property panel isopened 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 with 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. The_init()method stores the nodeEditor for later use, reads the current property values from the schema, and marks the setup area as ready to display."some-component-setup-area.component.ts" file@Input()@CrtInput()public set viewNodeEditor(nodeEditor: ViewNodeEditor) {this._init(nodeEditor).catch((error) => console.error('Error initializing setup area:', error));}/* Store the view node editor, read the current property values from theschema, and mark the setup area as ready to display. */private async _init(nodeEditor: ViewNodeEditor): Promise<void> {/* Store the view node editor for later use when reading or writingproperty values. */this._viewNodeEditor = nodeEditor;/* Read the current property values from the schema. Implement thismethod in step 4. */await this._loadElementData();/* Mark the setup area as ready once initialization is complete. */this.isPanelReady.set(true);} -
Initialize
InterfaceDesignerSchemaServiceto access view model attributes and data sources."some-component-setup-area.component.ts" fileprivate readonly _schemaEditor = new InterfaceDesignerSchemaService().getSchemaEditor();InterfaceDesignerSchemaServiceprovides agetSchemaEditor()method that returns aSchemaEditor.SchemaEditoris the entry point for reading and modifying the Freedom UI page schema — it groups together the sub-editors for working with UI elements, the data model, and the view model. ThegetSchemaEditor()method throws an error if theSchemaEditoris not available. In the designer runtime, this call is safe to make during component initialization. The code below shows theSchemaEditorstructure.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 typed 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 Freedom UI page schema JSON.
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 with
$in the schema JSON.{"control": "$Account.Name"}Resource binding
A reference to a localization string, prefixed with "$Resources.Strings." in the schema JSON.
{"label": "$Resources.Strings.SaveButton_caption"}Request binding
A reference to a request handler, stored as an object with
requestand optionalparamsfields.{"clicked": {"request": "crt.SaveRecordRequest","params": {}}}Use optional chaining and default values when reading property values: "
const value = propertyValue?.value ?? defaultValue. This avoids runtime errors when a property has not been set yet. -
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 typed 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 with
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' }});} -
Save the file.
-
Add the markup of the setup area component to the "some-component-setup-area.component.html" file.
-
Add the styles of the setup area component to the "some-component-setup-area.component.scss" file. For Creatio 8.3.4 and later, use the "@creatio/interface-designer/styles/properties-panel-styles.scss" file to align the setup area styles with the visual style of the out-of-the-box setup areas.
-
Link the setup area to the custom Freedom UI component.
For Creatio version 8.3.4 and later:
-
Open the "runtime.designer-definitions.ts" file.
-
Set the
propertiesPanelproperty to the setup area type identifier in the component designer definition. The value must match thetypedefined in the@CrtViewElementdecorator of the setup area component. -
Save the file.
"runtime.designer-definitions.ts" fileexport async function loadRuntimeDesignerDefinitions(_context: RemoteDesignerDefinitionsLoadContext): Promise<RemoteFeatureDesignerDefinitions> {return {viewElements: [{type: SOME_COMPONENT_TYPE,propertiesPanel: SOME_SETUP_AREA_TYPE_CONSTANT,},],};}
For Creatio version 8.3.3 only
-
Open the "some-component-name.component.ts" file that implements the functionality of the corresponding Freedom 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. -
Save the file.
Example that links the setup area to the corresponding Freedom UI component@CrtInterfaceDesignerItem({propertiesPanel: SOME_SETUP_AREA_TYPE_CONSTANT,})
-
As a result, when a user selects the corresponding Freedom UI component in the Freedom UI Designer, Creatio reads the component designer definition, resolves the propertiesPanel type, and instantiates the registered setup area.
6. Add the setup area component to the Freedom UI Designer
-
Register the
SomeComponentSetupAreaComponentview element in the design feature so that Freedom UI Designer can display it.For Creatio version 8.3.4 and later:
-
Open the "design-feature.module.ts" file.
-
Add the
SomeComponentSetupAreaComponentto the@CrtModuledecorator and Angular module declarations."design-feature.module.ts" file@CrtModule({viewElements: [SomeComponentSetupAreaComponent],})@NgModule({declarations: [SomeComponentSetupAreaComponent],imports: [CommonModule],schemas: [CUSTOM_ELEMENTS_SCHEMA],})export class DesignFeatureModule {} -
Open the "design.feature-activation.ts" file.
-
Define the
SomeComponentSetupAreaComponentas an Angular Element. Learn more: Angular elements overview (official vendor documentation)."design.feature-activation.ts" fileexport async function activateDesignFeature(): Promise<void> {const moduleRef = await ensureFeatureModuleRef(DesignFeatureModule);if (!customElements.get('usr-some-component-setup-area')) {const element = createCustomElement(SomeComponentSetupAreaComponent, {injector: moduleRef.injector,});customElements.define('usr-some-component-setup-area', element);}bootstrapCrtModule('some-package-name', DesignFeatureModule, {resolveDependency: (token) => moduleRef.injector.get(token as ProviderToken<unknown>),});} -
Open the "design.feature-definition.ts" file.
-
Add the public type of the
SomeComponentSetupAreaComponentto thediscovery.viewElementssection."design.feature-definition.ts" fileexport const designFeatureDefinition = {id: 'some-package-name-design',discovery: {viewElements: [{ type: SOME_SETUP_AREA_TYPE_CONSTANT }],},activate: () =>import('./design.feature-activation').then((m) => m.activateDesignFeature()),} satisfies RemoteFeatureDefinition; -
Save the files.
For Creatio version 8.3.3 only
-
Register the setup area so that Freedom UI Designer can display it.
- Go to the "src/app" directory.
- Create the "some-component.design-time.module.ts" file.
- Add the
SomeComponentSetupAreaComponentto the@CrtModuledecorator and Angular module declarations. - Save the file.
"some-component.design-time.module.ts" file/* Import the required functionality from the libraries. */import { CommonModule } from '@angular/common';import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';import { CrtModule } from '@creatio-devkit/common';import {SomeComponentSetupAreaComponent} from './some-component-setup-area.component';/* Register SomeComponentSetupAreaComponent as a view element so thatFreedom UI Designer can display it as a setup area when a user selectsthe corresponding Freedom UI component on the canvas. */@CrtModule({viewElements: [SomeComponentSetupAreaComponent],})/* Declare SomeComponentSetupAreaComponent in the Angular module andallow custom element schemas. */@NgModule({declarations: [SomeComponentSetupAreaComponent],imports: [CommonModule],exports: [SomeComponentSetupAreaComponent],schemas: [CUSTOM_ELEMENTS_SCHEMA],})export class SomeDesignTimeModule { } -
Register the
SomeComponentSetupAreaComponentview element as a component.- Open the "app.module.ts" file.
- Add
SomeComponentDesignTimeModuleto theimportsarray. - Define the
SomeComponentSetupAreaComponentas an Angular Element. Learn more: Angular elements overview (official vendor documentation). - Save the file.
"app.module.ts" file/* Import the required functionality from the libraries. */import { DoBootstrap, Injector, NgModule, Type } from '@angular/core';import { createCustomElement } from '@angular/elements';import { BrowserModule } from '@angular/platform-browser';import { SomeComponentSetupAreaComponent } from './some-component-setup-area.component';import { SomeDesignTimeModule } from './some-component.design-time.module';@NgModule({declarations: [SomeCustomComponent],imports: [BrowserModule, SomeDesignTimeModule],providers: [],})export class AppModule implements DoBootstrap {/* Injector is used to create Angular Elements from components. */private readonly _injector = inject(Injector);constructor() {/* Register SomeComponentSetupAreaComponent as a custom element onmodule initialization. */this._registerCustomElement('usr-some-component-setup-area',SomeComponentSetupAreaComponent);}private _registerCustomElement(selector: string, component: Type<unknown>): 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);}}}
-
-
Run the
npm run buildcommand in the Visual Studio Code terminal to build the project. This adds the build to the "dist" directory of the Angular project. -
Repeat step 2 of the add the custom Freedom UI component to the Freedom UI page instructions to upload packages to Creatio using the Clio utility.
As a result, the custom setup area will appear in the Freedom UI Designer when a user selects the corresponding Freedom 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 Freedom UI component implemented using remote module
Implement a Freedom UI Designer setup area for a custom Freedom UI component
Resources
Remote module template (for Creatio version 8.3.4 and later)
Remote module template (for Creatio version 8.3.3 and earlier)