Customize sidebars
Sidebars are special pages you can view by clicking the buttons in the top right of the Creatio UI, for example, feed or chats. Learn more: Set up a sidebar (user documentation).
Migrate a Classic UI panel to Freedom UI
This functionality is available in beta version in Creatio 8.1.3. To access the functionality, turn on the "SidebarExtensions" and "ShowPageAddonsPropertiesPanel" additional features in Creatio 8.1.4 or "SidePanelExtensions" additional feature in Creatio 8.1.3. Instructions: Change the status of an additional feature for all users.
Detailed example: Migrate a Classic UI panel to Freedom UI.
1. Create a sidebar
-
Create a new Freedom UI app or open an existing app. Instructions: Create an app manually (user documentation).
-
Create a Freedom UI page to use as a sidebar. To do this, click New page → Blank page → Select. Make sure to use only Blank page template to ensure backwards compatibility of sidebars.
-
Open the sidebar properties. To do this, click → Advanced → Sidebar. This opens a window.
-
Fill out the sidebar properties.
Property
Property description
Title
Localizable sidebar name displayed above its content.
Code
The sidebar schema name. Starts with the prefix. Learn more: Manage configuration elements. Can contain Latin characters and digits.
Location
Location of the sidebar in an existing Freedom UI panel.
Sidebar icon
Icon of the sidebar.
Sidebar position
Sidebar order number in the Freedom UI panel. Out of the box, the position numbering is 1000, 2000, 3000, etc. Enter the number between these numbers to place the sidebar between existing sidebars.
-
Save the changes.
As a result, the sidebar will be created without being displayed on Freedom UI panel.
2. Implement loading a Classic UI custom panel in Freedom UI
-
Open the source code of the Freedom UI page to migrate a Classic UI panel. To do this, click .
-
Set up the binding parameters of client module schema that implements functionality of the Classic UI custom panel.
-
Go to the
viewConfigDiff
schema section. -
Add the configuration object that configures Classic UI custom panel.
-
Fill out the properties of binding parameters directly or using
BaseSchemaModuleV2
.Directly
Fill out the properties of binding parameters directly for panels that do not inherit functionality of base client module schemas. To do this, use the following properties.
Property
Property value
type
crt.ModuleLoader
module
Code of the client module schema that implements functionality of the Classic UI custom panel
View an example that binds the
SomeClassicUIPanel
client module schema to theSomeApp_FormPage
Freedom UI page schema directly below.SomeApp_FormPage/* Declare the AMD module. */
define("SomeApp_FormPage", /**SCHEMA_DEPS*/[] /**SCHEMA_DEPS*/, function/**SCHEMA_ARGS*/()/**SCHEMA_ARGS*/ {
return {
viewConfigDiff: /**SCHEMA_VIEW_CONFIG_DIFF*/[
/* Configuration object that binds the "SomeClassicUIPanel" client module schema. */
{
"operation": "insert",
"name": "SomeClassicUIPanel",
"values": {
"type": "crt.ModuleLoader",
/* "SomeClassicUIPanel" client module schema that implements functionality of the Classic UI custom panel. */
"module": "SomeClassicUIPanel"
},
"parentName": "MainContainer",
"propertyName": "items",
"index": 0
}
]/**SCHEMA_VIEW_CONFIG_DIFF*/,
viewModelConfigDiff: /**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/[]/**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/,
modelConfigDiff: /**SCHEMA_MODEL_CONFIG_DIFF*/[]/**SCHEMA_MODEL_CONFIG_DIFF*/,
handlers: /**SCHEMA_HANDLERS*/[]/**SCHEMA_HANDLERS*/,
converters: /**SCHEMA_CONVERTERS*/{}/**SCHEMA_CONVERTERS*/,
validators: /**SCHEMA_VALIDATORS*/{}/**SCHEMA_VALIDATORS*/
};
});Using
BaseSchemaModuleV2
Fill out the properties of binding parameters for panels that inherit functionality of base client module schemas. To do this, use the following properties.
Property
Property value
type
crt.ModuleLoader
module
BaseSchemaModuleV2
useHistoryState
false
isSchemaConfigInitialized
true
schemaName
Code of the client module schema that implements functionality of the Classic UI custom panel
View an example that binds the
SomeClassicUIPanel
client module schema to theSomeApp_FormPage
Freedom UI page schema usingBaseSchemaModuleV2
below.SomeApp_FormPage/* Declare the AMD module. */
define("SomeApp_FormPage", /**SCHEMA_DEPS*/[] /**SCHEMA_DEPS*/, function/**SCHEMA_ARGS*/()/**SCHEMA_ARGS*/ {
return {
viewConfigDiff: /**SCHEMA_VIEW_CONFIG_DIFF*/[
/* Configuration object that binds the "SomeClassicUIPanel" client module schema. */
{
"operation": "insert",
"name": "SomeClassicUIPanel",
"values": {
"type": "crt.ModuleLoader",
"module": "BaseSchemaModuleV2",
"instanceConfig": {
"useHistoryState": false,
"isSchemaConfigInitialized": true,
/* "SomeClassicUIPanel" client module schema that implements functionality of the Classic UI custom panel. */
"schemaName": "SomeClassicUIPanel"
}
},
"parentName": "MainContainer",
"propertyName": "items",
"index": 0
}
]/**SCHEMA_VIEW_CONFIG_DIFF*/,
viewModelConfigDiff: /**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/[]/**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/,
modelConfigDiff: /**SCHEMA_MODEL_CONFIG_DIFF*/[]/**SCHEMA_MODEL_CONFIG_DIFF*/,
handlers: /**SCHEMA_HANDLERS*/[]/**SCHEMA_HANDLERS*/,
converters: /**SCHEMA_CONVERTERS*/{}/**SCHEMA_CONVERTERS*/,
validators: /**SCHEMA_VALIDATORS*/{}/**SCHEMA_VALIDATORS*/
};
});
-
-
Save the changes.
As a result, Creatio will load a Classic UI custom panel in Freedom UI as a sidebar.
Manage sidebar events implemented using remote module
This functionality is available in beta version in Creatio 8.1.4. To access the functionality, turn on the "SidebarExtensions" and "ShowPageAddonsPropertiesPanel" additional features. Instructions: Change the status of an additional feature for all users.
1. Set up the page UI
- Enable the sidebar functionality in Creatio. To do this, change the status of the "SidebarExtensions" and "ShowPageAddonsPropertiesPanel" additional features. Instructions: Change the status of an additional feature for all users.
- Create a sidebar. Read more >>>
- Set up the sidebar page based on your business goals.
2. Create an Angular project
Instructions: Create an Angular project to develop a custom UI component using remote module.
3. Create a custom sidebar using remote module
-
Create an Angular component that implements a custom sidebar. Instructions: Create a custom UI component using remote module.
-
Add a constant that stores data of the custom sidebar code. Take this step if you need to implement multiple sidebar events.
-
Go to the
src/app/
directory. -
Create the
constants
directory. -
Go to the
src/app/constants
directory. -
Create the
sidebar-constants.ts
andindex.ts
files. -
Open the
sidebar-constants.ts
file. -
Export a constant that includes the value of the custom sidebar code.
View an example that exports the
SOME_SIDEBAR_CODE
constant below. TheSOME_SIDEBAR_CODE
constant includes an arbitraryUsrSomeCustomSidebar
code of the custom sidebar.sidebar-constants.ts file/* Export a constant that includes the value of the custom sidebar code. */
export const SOME_SIDEBAR_CODE = 'UsrSomeCustomSidebar'; -
Save the file.
-
Open the
index.ts
file. -
Export the required functionality from the module.
-
Save the file.
index.ts file/* Export the required functionality from the module. */
export * from './sidebar-constants';
-
4. Create a custom service
- Go to the
src/app/
directory. - Create the
services
directory. - Go to the
src/app/services
directory. - Implement the business logic. Instructions: Create a custom service using remote module.
5. Create requests and events of the custom sidebar
-
Enable the
HttpClientService
service that sends HTTP requests.- Open the
app.module.ts
file. - Add the
HttpClientService
service to theproviders
section in theNgModule
decorator. - Import the required functionality from the libraries into the class.
- Save the file.
app.module.ts file/* Import the required functionality from the libraries. */
import { NgModule } from '@angular/core';
import { HttpClientService } from '@creatio-devkit/common';
...
@NgModule({
...,
providers: [HttpClientService],
})
... - Open the
-
Create an Angular class in the project. To do this, run the
ng g class open-close-some-sidebar.handler
command at the command line terminal of Microsoft Visual Studio Code.As a result, Microsoft Visual Studio Code will add the
OpenCloseSomeSidebarHandler
class files to thesrc/app/
project directory. TheOpenCloseSomeSidebarHandler
class implements open and close events of the custom sidebar. -
Implement open and close events of the custom sidebar (optional).
-
Open the
open-close-some-sidebar.handler.ts
file. -
Add the
SomeSidebarEventRequest
class and inherit theBaseRequestHandler
class from the@creatio-devkit/common
library. -
Add the configuration object that declares the request handler.
Property
Property value
Property description
type
usr.OpenCloseSomeSidebarHandler
Custom request handler.
requestType
crt.HandleSidebarOpenRequest
Base request handler that opens the custom sidebar.
crt.HandleSidebarCloseRequest
Base request handler that closes the custom sidebar.
-
Flag the
OpenCloseSomeSidebarHandler
class using theCrtRequestHandler
decorator. -
Implement the business logic of the
handle(request: SomeSidebarEventRequest)
method. The method handles the user request. Since the request handler interacts withcrt.HandleSidebarOpenRequest
andcrt.HandleSidebarCloseRequest
request handlers from all sidebars, check the sidebar code. If the sidebar is available, implement the custom business logic. -
Import the required functionality from the libraries into the class.
-
Save the file.
View an example that implements open and close events of the custom sidebar below.
open-sidebar.handler.ts file/* Import the required functionality from the libraries. */
import { BaseRequest, BaseRequestHandler, CrtRequestHandler } from "@creatio-devkit/common";
import { SOME_SIDEBAR_CODE } from "./constants";
class SomeSidebarEventRequest extends BaseRequest {
public readonly sidebarCode!: string;
}
@CrtRequestHandler({
type: 'usr.OpenCloseSomeSidebarHandler',
/* Open event of the custom sidebar. */
requestType: "crt.HandleSidebarOpenRequest",
/* Close event of the custom sidebar. */
//requestType: "crt.HandleSidebarCloseRequest",
})
export class OpenCloseSomeSidebarHandler extends BaseRequestHandler {
public async handle(request: SomeSidebarEventRequest): Promise<void> {
/* Check the sidebar code. */
if (request.sidebarCode === SOME_SIDEBAR_CODE) {
/* Implement the custom business logic. */
...;
}
/* Call the next handler if it exists and return its result. */
await this.next?.handle(request);
}
} -
-
Create an Angular class in the project. To do this, run the
ng g class initialize-some-sidebar.handler
command at the command line terminal of Microsoft Visual Studio Code.As a result, Microsoft Visual Studio Code will add the
InitializeSomeSidebarHandler
class files to thesrc/app/
project directory. TheInitializeSomeSidebarHandler
class initializes the custom sidebar. -
Implement events that initialize the custom sidebar.
-
Open the
initialize-some-sidebar.handler.ts
file. -
Add the configuration object that declares the request handler.
Property
Property value
Property description
type
usr.SomeSidebarInitHandler
Custom request handler.
requestType
crt.SidebarInitRequest
Base request handler that initializes the custom sidebar.
-
Flag the
InitializeSomeSidebarHandler
class using theCrtRequestHandler
decorator. -
Inherit the
BaseRequestHandler
class from the@creatio-devkit/common
library. -
Create an instance of the HTTP client from the
@creatio-devkit/common
library. -
Create an instance of the custom service.
-
Implement the business logic of events based on your business goals.
Event that returns the state of the custom sidebar
Check whether the sidebar is available before executing custom actions to initialize the sidebar. This prevents functionality issues if the user disables the sidebar or if the sidebar is restricted by access rights. The
crt.GetSidebarStateRequest
request handler returns the state of the custom sidebar.View an example of the event that returns the state of the custom sidebar below.
initialize-some-sidebar.handler.ts file/* Import the required functionality from the libraries. */
import { BaseRequest, BaseRequestHandler, CrtRequestHandler } from "@creatio-devkit/common";
import { SOME_SIDEBAR_CODE } from "./constants";
/* Interface that explicitly specifies the type of the returned "GetUnreadMessages" request. */
interface GetUnreadMessagesResponse {
messages: string[];
}
@CrtRequestHandler({
type: 'usr.SomeSidebarInitHandler',
requestType: 'crt.SidebarInitRequest',
})
export class InitializeSomeSidebarHandler extends BaseRequestHandler {
/* Return the sidebar state. */
private async _getSidebarState(): Promise<{ available: boolean, opened: boolean }> {
return (await this.handlerChain.process({
type: 'crt.GetSidebarStateRequest',
sidebarCode: SOME_SIDEBAR_CODE,
$context: {}
} as BaseRequest)) as { available: boolean, opened: boolean };
}
}- If the custom sidebar whose code is specified in the
sidebarCode
property is available to the user, theavailable
property is set totrue
. Otherwise,false
. - If the custom sidebar is open, the
opened
property is set totrue
. Otherwise,false
. - Since Creatio handles the initialization request before the sidebar is opened, if you send a request that returns the state of the custom sidebar using the
crt.SidebarInitRequest
request handler, theopened
property is always set tofalse
.
Event that displays or hides the notification mark on the sidebar icon
To display the notification mark, use the
crt.ShowSidebarNotificationMarkRequest
request handler.To hide the notification mark, use the
crt.HideSidebarNotificationMarkRequest
request handler.View an example of the event that displays or hides the notification mark on the sidebar icon below.
initialize-some-sidebar.handler.ts file/* Import the required functionality from the libraries. */
import { BaseRequest, BaseRequestHandler, CrtRequestHandler } from "@creatio-devkit/common";
import { SOME_SIDEBAR_CODE } from "./constants";
interface GetUnreadMessagesResponse {
messages: string[];
}
@CrtRequestHandler({
type: 'usr.SomeSidebarInitHandler',
requestType: 'crt.SidebarInitRequest',
})
export class InitializeSomeSidebarHandler extends BaseRequestHandler {
/* Display a notification mark on the sidebar icon. */
private async _showNotificationMark(): Promise<void> {
await this.handlerChain.process({
type: 'crt.ShowSidebarNotificationMarkRequest',
sidebarCode: SOME_SIDEBAR_CODE,
$context: {}
} as BaseRequest);
}
/* Hide a notification mark on the sidebar icon. */
private async _hideNotificationMark(): Promise<void> {
await this.handlerChain.process({
type: 'crt.HideSidebarNotificationMarkRequest',
sidebarCode: SOME_SIDEBAR_CODE,
$context: {}
} as BaseRequest);
}
}Event that opens or closes the custom sidebar
To open the custom sidebar, use the
crt.OpenSidebarRequest
request handler.To close the custom sidebar, use the
crt.CloseSidebarRequest
request handler.View an example of the event that opens and closes the custom sidebar below.
initialize-some-sidebar.handler.ts file/* Import the required functionality from the libraries. */
import { BaseRequest, BaseRequestHandler, CrtRequestHandler } from "@creatio-devkit/common";
import { SOME_SIDEBAR_CODE } from "./constants";
interface GetUnreadMessagesResponse {
messages: string[];
}
@CrtRequestHandler({
type: 'usr.SomeSidebarInitHandler',
requestType: 'crt.SidebarInitRequest',
})
export class InitializeSomeSidebarHandler extends BaseRequestHandler {
/* Open the sidebar. */
private async _openSidebar(): Promise<void> {
await this.handlerChain.process({
type: 'crt.OpenSidebarRequest',
sidebarCode: SOME_SIDEBAR_CODE,
$context: {}
} as BaseRequest);
}
/* Close the sidebar. */
private async _closeSidebar(): Promise<void> {
await this.handlerChain.process({
type: 'crt.CloseSidebarRequest',
sidebarCode: SOME_SIDEBAR_CODE,
$context: {}
} as BaseRequest);
}
}Additional events that manage the custom sidebar
Implement the business logic of the additional events if needed.
Event
Description of event
_refreshSidebarData()
Refreshes sidebar data when the sidebar is opened.
_checkUnreadMessages()
Waits for data sent by the web service. When Creatio receives data, displays a notification mark on the sidebar icon.
_isSidebarAvailable()
Checks whether the sidebar is available.
_isSidebarOpened()
Checks whether the sidebar is open.
_handleWebServiceEvent()
Handles the data sent by the web service. If the sidebar is open, refreshes its data. Otherwise, opens the sidebar when the web service sends required data.
_subscribeToWebServiceEvents()
Subscribes to the data sent by the web service. When Creatio receives data, handles it.
handle()
Handles the user request. If the sidebar is available, waits for data sent by the web service and subscribes to data.
We recommend avoiding long-term asynchronous operations, such as an HTTP request that loads data, in the
init
event. Otherwise, it delays the data loading and Creatio proceeds after the request handlers are completed. If executing a long-term operation is necessary, handle data and wait for asynchronous data loading using thethen
method instead of theawait
keyword.View an example that implements the handling of long-term asynchronous operations below.
- Correct handling of long-term asynchronous operations
- Incorrect handling of long-term asynchronous operations
private _loadDataByHttpRequest(): Promise<CustomData> {
/* Implement the custom business logic. */
...;
}
public async handle(request: BaseRequest): Promise<void> {
this._loadDataByHttpRequest().then(data => {
/* Implement the business logic that handles loaded data. */
...;
});
await this.next?.handle(request);
}private _loadDataByHttpRequest(): Promise<CustomData> {
/* Implement the custom business logic. */
...;
}
public async handle(request: BaseRequest): Promise<void> {
const data = await this._loadDataByHttpRequest()
/* Implement the business logic that handles loaded data. */
...;
await this.next?.handle(request);
}View an example of additional events that manage the custom sidebar below.
initialize-some-sidebar.handler.ts file/* Import the required functionality from the libraries. */
import { BaseRequest, BaseRequestHandler, CrtRequestHandler, HttpClientService } from "@creatio-devkit/common";
import { SOME_SIDEBAR_CODE } from "./constants";
import { SomeService } from "./services/some-service.service";
interface GetUnreadMessagesResponse {
messages: string[];
}
@CrtRequestHandler({
type: 'usr.SomeSidebarInitHandler',
requestType: 'crt.SidebarInitRequest',
})
export class InitializeSomeSidebarHandler extends BaseRequestHandler {
constructor(
/* Create an instance of the HTTP client from the "@creatio-devkit/common" library. */
private readonly _httpClient: HttpClientService,
/* Create an instance of the "SomeService." */
private readonly _someService: SomeService
)
{
super();
}
/* Display a notification mark on the sidebar icon when the web service sends required data. */
private async _showNotificationMark(): Promise<void> {
await this.handlerChain.process({
type: 'crt.ShowSidebarNotificationMarkRequest',
sidebarCode: SOME_SIDEBAR_CODE,
$context: {}
} as BaseRequest);
}
/* Open the sidebar when the web service sends required data.*/
private async _openSidebar(): Promise<void> {
await this.handlerChain.process({
type: 'crt.OpenSidebarRequest',
sidebarCode: SOME_SIDEBAR_CODE,
$context: {}
} as BaseRequest);
}
/* Wait for data sent by the web service. When Creatio receives data, display a notification mark on the sidebar icon. */
private async _checkUnreadMessages(): Promise<void> {
/* Specify the URL to retrieve the list of unread messages. Use the "EventService" web service. */
const endpointUrl = `rest/EventService/GetUnreadMessages`;
/* Add some description here. */
const result = await this._httpClient.post<GetUnreadMessagesResponse>(endpointUrl, null, {
responseType: 'json',
});
/* Check whether a unread message occurs. If it happens, display a notification mark on the sidebar icon. */
if (result.body && result.body.messages.length > 0) {
await this._showNotificationMark();
}
}
/* Return the sidebar state. */
private async _getSidebarState(): Promise<{ available: boolean, opened: boolean }> {
return (await this.handlerChain.process({
type: 'crt.GetSidebarStateRequest',
sidebarCode: SOME_SIDEBAR_CODE,
$context: {}
} as BaseRequest)) as { available: boolean, opened: boolean };
}
/* Check whether the sidebar is available. */
private async _isSidebarAvailable(): Promise<boolean> {
const sidebarState = await this._getSidebarState();
return sidebarState.available;
}
/* Check whether the sidebar is open. */
private async _isSidebarOpened(): Promise<boolean> {
const sidebarState = await this._getSidebarState();
return sidebarState.opened;
}
/* Refresh sidebar data when it is opened. */
private async _refreshSidebarData(): Promise<void> {
await this.handlerChain.process({
type: 'usr.RefreshSomeSidebarDataRequest',
$context: {}
});
}
/* Handle the data sent by the web service. */
private async _handleWebServiceEvent(): Promise<void> {
/* Check whether the sidebar is open. */
if (await this._isSidebarOpened()) {
/* Refresh sidebar data. */
await this._refreshSidebarData();
} else {
/* Open the sidebar when the web service sends required data. */
await this._openSidebar();
}
}
/* Subscribe to the data sent by the web service. When Creatio receives data, handle it. */
private async _subscribeToWebServiceEvents(): Promise<void> {
this._someService.getEventsObservable().then(() => {
/* Handle the received data. */
this._handleWebServiceEvent().then();
});
}
public async handle(request: BaseRequest): Promise<void> {
/* Check whether the sidebar is available. */
if (await this._isSidebarAvailable()) {
/* Wait for data sent by the web service. */
this._checkUnreadMessages().then();
/* Subscribe to the data sent by the web service. */
this._subscribeToWebServiceEvents();
}
/* Call the next handler if it exists and return its result. */
await this.next?.handle(request);
}
} - If the custom sidebar whose code is specified in the
-
Import the required functionality from the libraries into the class.
-
Save the file.
-
-
Register the handlers.
- Open the
app.module.ts
file. - Add the
OpenCloseSomeSidebarHandler
andInitializeSomeSidebarHandler
handlers to therequestHandlers
section in theCrtModule
decorator. - Import the required functionality from the libraries into the class.
- Save the file.
app.module.ts file/* Import the required functionality from the libraries. */
import { CrtModule } from '@creatio-devkit/common';
import { OpenCloseSomeSidebarHandler } from './open-close-some-sidebar.handler';
import { InitializeSomeSidebarHandler } from './initialize-some-sidebar.handler';
...
@CrtModule({
...,
/* Specify that "OpenCloseSomeSidebarHandler" and "InitializeSomeSidebarHandler" are request handlers. */
requestHandlers: [
OpenCloseSomeSidebarHandler,
InitializeSomeSidebarHandler
],
})
... - Open the
-
Build the project. To do this, run the
npm run build
command at the command line terminal of Microsoft Visual Studio Code.
As a result, Microsoft Visual Studio Code will add the build to the dist
directory of the Angular project. The build will have the sdk_remote_module_package
name.
6. Add the implemented sidebar events to Creatio
Instructions: Add the custom UI component implemented using remote module to the Freedom UI page (steps 1–3).
As a result, Creatio will display the custom sidebar and handle the sidebar events implemented using remote module.
See also
Set up a sidebar (user documentation)
Manage an existing additional feature
Manage apps (user documentation)