Skip to main content
Version: 10

Implement a custom request handler using remote module

Level: advanced

To implement the example:

  1. Create an Angular project. Read more >>>
  2. Install npm packages. Read more >>>
  3. Create a custom request. Read more >>>
  4. Create a custom service. Read more >>>
  5. Create custom request handlers. Read more >>>
  6. Add the request to the Freedom UI page. Read more >>>
Example

Add custom request handlers to the custom request page. The request handlers execute the following actions:

  • Display current date and time as a Label component.
  • Change the date and time value after a user clicks the Refresh date and time button.

Implement handlers using a remote module created in Angular framework.

1. Create an Angular project​

To create an Angular project, follow the instructions: Create an Angular project.

For this example:

  • <%projectName%> macro is set to "sdk_custom_request_handler."
  • <%vendorPrefix%> macro is set to "usr."

As a result, an Angular project to develop a custom request handler using a remote module will be added. The project contains:

  • A RemoteEntryDefinition object exported from the "src/main.ts" file.
  • The runtime feature files used to implement request handler.
  • The optional design feature files.
  • The "sdk_custom_request_handler-runtime" runtime feature ID.

2. Install npm packages​

To install npm packages, follow the instructions: Install npm packages.

As a result, required npm packages are installed.

3. Create a custom request​

  1. Ensure the project includes the "AGENTS.md" file. Instructions: Create a custom Freedom UI component (step 1).

  2. Run the ng g class features/runtime/requests/update-current-time.request command in the Visual Studio Code terminal to create an Angular class in the project. This adds the UpdateCurrentTimeRequest class files to the "src/app/features/runtime/requests" project directory.

  3. Implement the request.

    1. Open the "update-current-time.request.ts" file.
    2. Inherit the BaseRequest class from the @creatio-devkit/common library.
    3. Add the type and parameter of the request.
    4. Import the required functionality from the libraries into the class.
    5. Save the file.
    "update-current-time.request.ts" file
    /* Import the required functionality from the libraries. */
    import { BaseRequest } from "@creatio-devkit/common";

    export class UpdateCurrentTimeRequest extends BaseRequest{
    /* The type and parameters of the request. */
    public dateTime!: string;
    }

4. Create a custom service​

  1. Run the ng g class features/runtime/services/date-time.service command in the Visual Studio Code terminal to create an Angular class in the project. This adds the DateTimeService class files to the "src/app/features/runtime/services" project directory.

  2. Implement the service that receives current date and time.

    1. Open the "date-time.service.ts" file.
    2. Flag the DateTimeService class using the @Injectable decorator.
    3. Implement the getCurrentDateTime() method that receives current date and time.
    4. Import the required functionality from the libraries into the class.
    5. Save the file.
    "date-time.service.ts" file
    /* Import the required functionality from the libraries. */
    import { formatDate } from "@angular/common";
    import { Injectable } from "@angular/core";

    @Injectable({
    providedIn: 'root',
    })
    export class DateTimeService {
    /* Receive current date and time. */
    public getCurrentDateTime(dateTime: string): Promise<{
    dateTime: Record<string, unknown>
    }> {
    /* Return current date and time. */
    return Promise.resolve({
    dateTime: { dateTime: formatDate(new Date(), 'medium', 'en')}
    });
    }
    }

5. Create custom request handlers​

  1. Create a custom handler that displays current date and time on the Freedom UI page.

    1. Set up the Freedom UI page.

      1. Repeat steps 1-4 of the instructions: Add the custom Freedom UI component to the Freedom UI page. For this example, create a Requests app.

      2. Add a label to display the current date and time.

        1. Drag the Label component to the canvas.

        2. Fill out the component parameters.

          Parameter

          Value

          Style

          Body

          Text color

          #757575

          Element code

          UsrDateAndTime

      3. Add a button that refreshes current date and time.

        1. Drag the Button component to the canvas.

        2. Fill out the component parameters.

          Parameter

          Value

          Title

          Refresh date and time

          Style

          Focus

          Element code

          UsrRefreshDateAndTime

      4. Click btn_actions_in_freedom_ui_designer.png → Source code to open the source code of the Freedom UI page.

      5. Add an attribute.

        1. Go to the viewModelConfigDiff schema section → values configuration object.
        2. Add a CurrentDateTime attribute that stores data about the current date and time.
        viewModelConfigDiff schema section
        viewModelConfigDiff: /**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/[
        {
        "operation": "merge",
        "path": [
        "attributes"
        ],
        "values": {
        /* The attribute that stores the current date and time. */
        "CurrentDateTime": {}
        }
        }
        ]/**SCHEMA_VIEW_MODEL_CONFIG_DIFF*/,
      6. Bind an attribute to the label.

        1. Go to the viewConfigDiff schema section → UsrDateAndTime element.
        2. Bind the CurrentDateTime attribute to the caption property.
        viewConfigDiff schema section
        viewConfigDiff: /**SCHEMA_VIEW_CONFIG_DIFF*/[
        {
        "operation": "insert",
        "name": "UsrDateAndTime",
        "values": {
        /* Bind the CurrentDateTime attribute to the caption property. */
        "caption": "$CurrentDateTime",
        },
        }
        ]/**SCHEMA_VIEW_CONFIG_DIFF*/,
      7. Click Save.

    2. Run the ng g class features/runtime/request-handlers/update-current-time.handler command in the Visual Studio Code terminal to create an Angular class in the project. This adds the UpdateCurrentTimeHandler class files to the "src/app/features/runtime/request-handlers" project directory.

    3. Implement the handler.

      1. Open the "update-current-time.handler.ts" file.

      2. Add the configuration object that declares the request handler.

        • Set the type property to "usr.UpdateCurrentTimeHandler."
        • Set the requestType property to "crt.UpdateCurrentTimeRequest."
      3. Flag the UpdateCurrentTimeHandler class using the @CrtRequestHandler decorator.

      4. Inherit the BaseRequestHandler class from the @creatio-devkit/common library.

      5. Implement the handling of the request result.

      6. Generate the value to display on the Freedom UI page.

      7. Import the required functionality from the libraries into the class.

      8. Save the file.

      "update-current-time.handler.ts" file
      /* Import the required functionality from the libraries. */
      import {
      BaseRequestHandler,
      CrtRequestHandler
      } from "@creatio-devkit/common";
      import { DateTimeService } from "../services/date-time.service";
      import {
      UpdateCurrentTimeRequest
      } from "../requests/update-current-time.request";

      /* Add the CrtRequestHandler decorator to the UpdateCurrentTimeHandler class. */
      @CrtRequestHandler({
      type: 'usr.UpdateCurrentTimeHandler',
      requestType: 'crt.UpdateCurrentTimeRequest',
      })

      export class UpdateCurrentTimeHandler extends BaseRequestHandler{
      constructor(private _dateTimeService: DateTimeService) {
      super();
      }
      public async handle(request: UpdateCurrentTimeRequest): Promise<unknown> {
      const result = await this._dateTimeService.getCurrentDateTime(request.dateTime);
      const dateTime = result.dateTime[request.dateTime] ?? 0
      /* Generate the value to display on the Freedom UI page. */
      request.$context['CurrentDateTime'] = dateTime;
      return dateTime;
      }
      }
  2. Create a custom handler that is executed when Creatio initializes a Freedom UI page.

    1. Run the ng g class features/runtime/request-handlers/page-init-current-time.handler command in the Visual Studio Code terminal to create an Angular class in the project. This adds the PageInitCurrentTimeHandler class files to the "src/app/features/runtime/request-handlers" project directory.

    2. Implement the handler.

      1. Open the "page-init-current-time.handler.ts" file.

      2. Add the configuration object that declares the request handler.

        • Set the type property to "usr.PageInitCurrentTimeHandler."
        • Set the requestType property to "crt.HandleViewModelInitRequest."
        • Set the scopes property to "UsrRequests_FormPage."
      3. Flag the PageInitCurrentTimeHandler class using the @CrtRequestHandler decorator.

      4. Inherit the BaseRequestHandler class from the @creatio-devkit/common library.

      5. Implement the update of the current date and time when Creatio initializes the Freedom UI page.

      6. Import the required functionality from the libraries into the class.

      7. Save the file.

      "page-init-current-time.handler.ts" file
      /* Import the required functionality from the libraries. */
      import {
      BaseRequest,
      BaseRequestHandler,
      CrtRequestHandler,
      HandlerChainService
      } from "@creatio-devkit/common";
      import {
      UpdateCurrentTimeRequest
      } from "../requests/update-current-time.request";

      /* Add the CrtRequestHandler decorator to the PageInitCurrentTimeHandler class. */
      @CrtRequestHandler({
      type: 'usr.PageInitCurrentTimeHandler',
      requestType: 'crt.HandleViewModelInitRequest',
      scopes: ['UsrRequests_FormPage'],
      })

      export class PageInitCurrentTimeHandler extends BaseRequestHandler{
      public async handle(request: BaseRequest): Promise<unknown> {
      /* Update the current date and time when Creatio initializes the Freedom UI page. */
      await HandlerChainService.instance.process({
      type: 'crt.UpdateCurrentTimeRequest',
      dateTime: 'dateTime',
      $context: request.$context
      } as UpdateCurrentTimeRequest);

      return this.next?.handle(request);
      }
      }
  3. Register the handlers. The template already contains the runtime feature activation and bootstrapCrtModule() call. Extend the existing runtime feature files to register the request handlers.

    1. Open the "runtime-feature.module.ts" file.

    2. Add the UpdateCurrentTimeHandler and PageInitCurrentTimeHandler handlers to the requestHandlers section in the @CrtModule decorator.

      "runtime-feature.module.ts" file
      /* Import the required functionality from the libraries. */
      import { ApplicationRef, DoBootstrap, NgModule } from '@angular/core';
      import { BrowserModule } from '@angular/platform-browser';
      import { CrtModule } from '@creatio-devkit/common';
      import {
      PageInitCurrentTimeHandler
      } from './request-handlers/page-init-current-time.handler';
      import {
      UpdateCurrentTimeHandler
      } from './request-handlers/update-current-time.handler';

      @CrtModule({
      requestHandlers: [UpdateCurrentTimeHandler, PageInitCurrentTimeHandler],
      })
      @NgModule({
      declarations: [],
      imports: [BrowserModule],
      })
      export class RuntimeFeatureModule implements DoBootstrap {
      ngDoBootstrap(_appRef: ApplicationRef): void {}
      }
    3. Open the "runtime.feature-definition.ts" file.

    4. Add the public type property of the handlers to the discovery.requestHandlers section.

      "runtime.feature-definition.ts" file
      /* Import the required functionality from the libraries. */
      import type {
      RemoteFeatureDefinition,
      RemoteDesignerDefinitionsLoadContext
      } from '@creatio-devkit/common';

      /**
      * Root definition for the runtime feature.
      *
      * Describes the view elements this remote package contributes at runtime
      * and provides the entry points used to load designer metadata and
      * activate the feature.
      */
      export const runtimeFeatureDefinition = {
      id: 'sdk_custom_request_handler-runtime',
      discovery: {
      viewElements: [],
      mobileViewElements: [],
      requestHandlers: [
      {
      type: 'usr.UpdateCurrentTimeHandler',
      requestType: 'crt.UpdateCurrentTimeRequest',
      },
      {
      type: 'usr.PageInitCurrentTimeHandler',
      requestType: 'crt.HandleViewModelInitRequest',
      scopes: ['UsrRequests_FormPage'],
      },
      ],
      },
      loadDesignerDefinitions: (context: RemoteDesignerDefinitionsLoadContext) =>
      import('./runtime.designer-definitions').then(
      (m) => m.loadRuntimeDesignerDefinitions(context)),
      activate: () =>
      import('./runtime.feature-activation').then((m) => m.activateRuntimeFeature()),
      } satisfies RemoteFeatureDefinition;
    5. Import the required functionality from the libraries into the files.

    6. Save the files.

  4. Run the npm run build command in the Visual Studio Code terminal to build the project.

As a result, the build will be added to the "dist" directory of the Angular project. The build will have the "sdk_custom_request_handler" name.

6. Add the request to the Freedom UI page​

  1. 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.

  2. Open the Requests app in the Application Designer.

  3. Open the Requests form page.

  4. Drag the Button component to the canvas.

  5. Click btn_actions_in_freedom_ui_designer.png → Source code to open the source code of the Freedom UI page.

  6. Set up how to handle the action executed on button click.

    1. Go to the viewConfigDiff schema section → UsrRefreshDateAndTime element.
    2. Bind the sending of the crt.UpdateCurrentTimeRequest request to the clicked button event.
    viewConfigDiff schema section
    viewConfigDiff: /**SCHEMA_VIEW_CONFIG_DIFF*/[
    {
    "operation": "insert",
    "name": "UsrRefreshDateAndTime",
    "values": {
    "clicked": {
    /* Bind the sending of the crt.UpdateCurrentTimeRequest request
    to the button click event. */
    "request": "crt.UpdateCurrentTimeRequest",
    "params": {
    "dateTime": "dateTime"
    }
    }
    },
    },
    ]/**SCHEMA_VIEW_CONFIG_DIFF*/,
  7. Click Save.

As a result, the custom request handler will be added to the request page.

View the result​

  1. Open the Requests section.
  2. Create a request that has an arbitrary name. For example, "Vacation."
  3. Click the Refresh date and time button.

As a result:

  • Creatio will display the current date and time on the request page.
  • Creatio will change the date and time value after clicking the Refresh date and time button.

Both request handlers are implemented using a remote module created in the Angular framework.


Resources​

*.zip archive that contains the implemented Freedom UI app

Angular project that contains the implemented example