Implement a custom UI component based on a classic page
Display the history of the selected account on the Account timeline tab of the record page of the Requests custom section. The tab is a web component. Implement the web component based on the 7.X Timeline tab displayed on the contact page.
1. Create an app
-
Create a custom
Requests
app based on the Records & business processes template. To do this, follow the procedure in the user documentation: Create a custom app. -
Open the Requests form page page in the workspace of the
Requests
app page.The Requests form page page includes the Name field by default.
-
Add an account field:
-
Add a new field of the Dropdown type to the Freedom UI Designer’s workspace.
-
Click the button on the Freedom UI Designer’s action panel and fill out the field properties in the setup area:
- Set Title to "Account."
- Set Code to "UsrAccount."
- Select "Account" in the Lookup property.
- Clear the Enable adding new values checkbox.
-
-
Add a tab that contains the history of the selected account.
-
Add a new Tabs layout element to the Freedom UI Designer’s workspace.
-
Delete the Tab 2 tab the Requests form page page includes by default.
-
Click the button on the Freedom UI Designer’s action panel and specify "Account timeline" in the Title tab property in the setup area.
-
-
Click Save on the Freedom UI Designer’s action panel.
2. Create a custom web component
-
Go to the Configuration section and select a custom package to add the schema.
-
Click Add → Module on the section list toolbar.
-
Fill out the schema properties in the Module Designer.
- Set Code to "UsrTimelineModule."
- Set Title to "Timeline module."
-
Implement a custom web component.
-
Add the
@creatio-devkit/common
,Base7xViewElement
, andckeditor-base
modules as dependencies to the AMD module declaration.Dependencies of the UsrTimelineModule AMD module/* AMD module declaration. */
define("UsrTimelineModule", ["@creatio-devkit/common", "Base7xViewElement", "ckeditor-base"], function (sdk, Base7xViewElement) {
...
}); -
Declare a custom
UsrTimelineModule
web component class.UsrTimelineModule class declaration/* AMD module declaration. */
define("UsrTimelineModule", ["@creatio-devkit/common", "Base7xViewElement", "ckeditor-base"], function (sdk, Base7xViewElement) {
/* Class declaration. */
class UsrTimelineModule extends Base7xViewElement {
set primaryColumnValue(value) {
this._primaryColumnValue = value;
this._init();
}
get primaryColumnValue() {
return this._primaryColumnValue;
}
set entitySchemaName(value) {
this._entitySchemaName = value;
this._init();
}
get entitySchemaName() {
return this._entitySchemaName;
}
set cardSchemaName(value) {
this._cardSchemaName = value;
this._init();
}
get cardSchemaName() {
return this._entitySchemaName;
}
constructor() {
super("Timeline");
}
_init() {
if (this._primaryColumnValue && this._cardSchemaName && this._entitySchemaName) {
this.initContext(() => {
this._moduleId = this.sandbox.id + "_UsrTimelineModule";
this.sandbox.subscribe("GetColumnsValues", (attributeNames) => this._getColumnValues(attributeNames), null, [this._moduleId]);
this.sandbox.subscribe("GetEntityInfo", () => this._getEntityInfo(), null, [this._moduleId]);
this._loadTimelineSchemaModule();
});
}
}
_loadTimelineSchemaModule() {
this._moduleId = this.sandbox.loadModule("BaseSchemaModuleV2", {
id: this._moduleId,
renderTo: this._renderTo,
instanceConfig: {
schemaName: "TimelineSchema",
isSchemaConfigInitialized: true,
useHistoryState: false,
showMask: true,
parameters: {
viewModelConfigDiff: {
"CardSchemaName": this._cardSchemaName,
"ReferenceSchemaName": this._entitySchemaName,
"InitialConfig": {
"entities": []
}
},
},
}
});
}
_getColumnValues(attributeNames) {
const values = {};
attributeNames?.forEach((attributeName) => {
switch (attributeName) {
case "Id":
values[attributeName] = this._primaryColumnValue?.value;
break;
case "Name":
values[attributeName] = this._primaryColumnValue?.displayValue;
break;
default: break;
}
});
return values;
}
_getEntityInfo() {
return {
entitySchemaName: this._entitySchemaName,
primaryColumnValue: this._primaryColumnValue?.value,
primaryDisplayColumnValue: this._primaryColumnValue?.displayValue
};
}
getMessages() {
const messages = super.getMessages();
return Object.assign(messages, {
"GetColumnsValues": {
mode: Terrasoft.MessageMode.PTP,
direction: Terrasoft.MessageDirectionType.SUBSCRIBE
},
"GetEntityInfo": {
mode: Terrasoft.MessageMode.PTP,
direction: Terrasoft.MessageDirectionType.SUBSCRIBE
}
});
}
disconnectedCallback() {
this.sandbox.unloadModule(this._moduleId, this._renderTo);
}
}
...
}); -
Register the
UsrTimelineModule
web component on the page.Register the UsrTimelineModule web component/* AMD module declaration. */
define("UsrTimelineModule", ["@creatio-devkit/common", "Base7xViewElement", "ckeditor-base"], function (sdk, Base7xViewElement) {
...
/* Web component registration. */
customElements.define('usr-timeline', UsrTimelineModule);
...
}); -
Register the
usr-timeline
web component as a visual element.usr-timeline web component registration/* AMD module declaration. */
define("UsrTimelineModule", ["@creatio-devkit/common", "Base7xViewElement", "ckeditor-base"], function (sdk, Base7xViewElement) {
...
/* Register a web component as a visual element. */
sdk.registerViewElement({
type: 'usr.Timeline',
selector: 'usr-timeline',
inputs: {
primaryColumnValue: {},
cardSchemaName: {},
entitySchemaName: {}
}
});
});
-
-
Click Save on the Module Designer’s toolbar.
3. Add the custom web component to the Freedom UI page
-
Open the
UsrRequests_FormPage
schema of the Freedom UI Requests form page page in the Configuration section. -
Click the button on the Freedom UI Designer’s action panel. This opens the source code of the Freedom UI page.
-
Add the custom web component.
-
Add the
UsrTimelineModule
module of the custom web component as a dependency to the AMD module declaration.Dependencies of the UsrRequests_FormPage AMD module/* AMD module declaration. */
define("UsrRequests_FormPage", /**SCHEMA_DEPS*/["UsrTimelineModule"]/**SCHEMA_DEPS*/, function/**SCHEMA_ARGS*/()/**SCHEMA_ARGS*/ {
...
}); -
Add the configuration object of the
UsrTimelineModule
module with the custom web component to theviewConfigDiff
schema section.viewConfigDiff schema sectionviewConfigDiff: /**SCHEMA_VIEW_CONFIG_DIFF*/[
...,
{
"operation": "insert",
"name": "Timeline_qwerty",
"values": {
"type": "usr.Timeline",
"layoutConfig": {
"column": 1,
"row": 1,
"colSpan": 12,
"rowSpan": 8
},
"primaryColumnValue": "$UsrAccount",
"cardSchemaName": "AccountPageV2",
"entitySchemaName": "Account"
},
"parentName": "GridContainer_qaocexw",
"propertyName": "items",
"index": 0
},
...
]/**SCHEMA_VIEW_CONFIG_DIFF*/,
-
-
Click Save on the Client Module Designer’s toolbar.
Outcome of the example
To view the outcome of the example:
- Open the
Requests
app page and click Run app. - Click New on the
Requests
app toolbar. - Enter "Request’s name" in the Name field.
- Select an account in the Account field, for example, "Accom."
As a result, Creatio will display the Account timeline tab of the selected "Accom" account on the request page.
Freedom UI Designer will display a stub in place of the custom web component.
Source codes
- UsrTimelineModule
- UsrRequests_FormPage
/* AMD module declaration. */
define("UsrTimelineModule", ["@creatio-devkit/common", "Base7xViewElement", "ckeditor-base"[, function(sdk, Base7xViewElement) {
/* Class declaration. */
class UsrTimelineModule extends Base7xViewElement {
set primaryColumnValue(value) {
this._primaryColumnValue = value;
this._init();
}
get primaryColumnValue() {
return this._primaryColumnValue;
}
set entitySchemaName(value) {
this._entitySchemaName = value;
this._init();
}
get entitySchemaName() {
return this._entitySchemaName;
}
set cardSchemaName(value) {
this._cardSchemaName = value;
this._init();
}
get cardSchemaName() {
return this._entitySchemaName;
}
constructor() {
super("Timeline");
}
_init() {
if (this._primaryColumnValue && this._cardSchemaName && this._entitySchemaName) {
this.initContext(() => {
this._moduleId = this.sandbox.id + "_UsrTimelineModule";
this.sandbox.subscribe("GetColumnsValues", (attributeNames) => this._getColumnValues(attributeNames), null, [this._moduleId]);
this.sandbox.subscribe("GetEntityInfo", () => this._getEntityInfo(), null, [this._moduleId]);
this._loadTimelineSchemaModule();
});
}
}
_loadTimelineSchemaModule() {
this._moduleId = this.sandbox.loadModule("BaseSchemaModuleV2", {
id: this._moduleId,
renderTo: this._renderTo,
instanceConfig: {
schemaName: "TimelineSchema",
isSchemaConfigInitialized: true,
useHistoryState: false,
showMask: true,
parameters: {
viewModelConfigDiff: {
"CardSchemaName": this._cardSchemaName,
"ReferenceSchemaName": this._entitySchemaName,
"InitialConfig": {
"entities": []
}
},
},
}
});
}
_getColumnValues(attributeNames) {
const values = {};
attributeNames?.forEach((attributeName) => {
switch (attributeName) {
case "Id":
values[attributeName] = this._primaryColumnValue?.value;
break;
case "Name":
values[attributeName] = this._primaryColumnValue?.displayValue;
break;
default: break;
}
});
return values;
}
_getEntityInfo() {
return {
entitySchemaName: this._entitySchemaName,
primaryColumnValue: this._primaryColumnValue?.value,
primaryDisplayColumnValue: this._primaryColumnValue?.displayValue
};
}
getMessages() {
const messages = super.getMessages();
return Object.assign(messages, {
"GetColumnsValues": {
mode: Terrasoft.MessageMode.PTP,
direction: Terrasoft.MessageDirectionType.SUBSCRIBE
},
"GetEntityInfo": {
mode: Terrasoft.MessageMode.PTP,
direction: Terrasoft.MessageDirectionType.SUBSCRIBE
}
});
}
disconnectedCallback() {
this.sandbox.unloadModule(this._moduleId, this._renderTo);
}
}
/* Web component registration. */
customElements.define('usr-timeline', UsrTimelineModule);
/* Register a web component as a visual element. */
sdk.registerViewElement({
type: 'usr.Timeline',
selector: 'usr-timeline',
inputs: {
primaryColumnValue: {},
cardSchemaName: {},
entitySchemaName: {}
}
});
return Terrasoft.UsrTimelineModule;
});
/* AMD module declaration. */
define("UsrRequests_FormPage", /**SCHEMA_DEPS*/["UsrTimelineModule"]/**SCHEMA_DEPS*/, function/**SCHEMA_ARGS*/()/**SCHEMA_ARGS*/ {
return {
viewConfigDiff: /**SCHEMA_VIEW_CONFIG_DIFF*/[
{
"operation": "insert",
"name": "UsrName",
"values": {
"layoutConfig": {
"column": 1,
"row": 1,
"colSpan": 1,
"rowSpan": 1
},
"type": "crt.Input",
"label": "$Resources.Strings.UsrName",
"control": "$UsrName"
},
"parentName": "LeftAreaProfileContainer",
"propertyName": "items",
"index": 0
},
{
"operation": "insert",
"name": "UsrAccount",
"values": {
"layoutConfig": {
"column": 1,
"row": 2,
"colSpan": 1,
"rowSpan": 1
},
"type": "crt.ComboBox",
"loading": false,
"control": "$UsrAccount",
"label": "$Resources.Strings.UsrAccount",
"labelPosition": "auto",
"listActions": [],
"showValueAsLink": true,
"placeholder": "",
"controlActions": []
},
"parentName": "LeftAreaProfileContainer",
"propertyName": "items",
"index": 1
},
{
"operation": "insert",
"name": "TabPanel_grveew2",
"values": {
"layoutConfig": {
"column": 1,
"row": 1,
"colSpan": 2,
"rowSpan": 1
},
"type": "crt.TabPanel",
"items": [],
"styleType": "default",
"bodyBackgroundColor": "primary-contrast-500",
"tabTitleColor": "auto",
"selectedTabTitleColor": "auto",
"headerBackgroundColor": "auto",
"underlineSelectedTabColor": "auto"
},
"parentName": "ControlGroupContainer",
"propertyName": "items",
"index": 0
},
{
"operation": "insert",
"name": "AccountTimeline",
"values": {
"type": "crt.TabContainer",
"items": [],
"caption": "#ResourceString(AccountTimeline_caption)#",
"iconPosition": "only-text"
},
"parentName": "TabPanel_grveew2",
"propertyName": "items",
"index": 0
},
{
"operation": "insert",
"name": "GridContainer_qaocexw",
"values": {
"type": "crt.GridContainer",
"items": [],
"rows": "minmax(32px, max-content)",
"columns": [
"minmax(32px, 1fr)",
"minmax(32px, 1fr)"
],
"gap": {
"columnGap": "large",
"rowGap": 0
}
},
"parentName": "AccountTimeline",
"propertyName": "items",
"index": 0
},
{
"operation": "insert",
"name": "Timeline_qwerty",
"values": {
"type": "usr.Timeline",
"layoutConfig": {
"column": 1,
"row": 1,
"colSpan": 12,
"rowSpan": 8
},
"primaryColumnValue": "$UsrAccount",
"cardSchemaName": "AccountPageV2",
"entitySchemaName": "Account"
},
"parentName": "GridContainer_qaocexw",
"propertyName": "items",
"index": 0
}
]/**SCHEMA_VIEW_CONFIG_DIFF*/,
viewModelConfigDiff: /**SCHEMA_VIEW_MODEL_CONFIG*/{
"attributes": {
"UsrName": {
"modelConfigDiff": {
"path": "PDS.UsrName"
}
},
"Id": {
"modelConfigDiff": {
"path": "PDS.Id"
}
},
"UsrAccount": {
"modelConfigDiff": {
"path": "PDS.UsrAccount"
}
}
}
}/**SCHEMA_VIEW_MODEL_CONFIG*/,
modelConfigDiff: /**SCHEMA_MODEL_CONFIG*/{
"dataSources": {
"PDS": {
"type": "crt.EntityDataSource",
"config": {
"entitySchemaName": "UsrRequests"
},
"scope": "page"
}
},
"primaryDataSourceName": "PDS"
}/**SCHEMA_MODEL_CONFIG*/,
handlers: /**SCHEMA_HANDLERS*/[]/**SCHEMA_HANDLERS*/,
converters: /**SCHEMA_CONVERTERS*/{}/**SCHEMA_CONVERTERS*/,
validators: /**SCHEMA_VALIDATORS*/{}/**SCHEMA_VALIDATORS*/
};
});