Action Engine System

Professional Guidelines for JSON-based UI Engine Configuration

Overview

The Action Engine system allows you to create dynamic user interfaces through simple JSON configuration. You can trigger actions like API calls, screen navigation, and UI updates without writing any code - just by defining JSON objects that describe what you want to happen.

Action Configuration

We have a limited set of components that support the Action Engine. Within these supported components, the action can be defined in two ways:

  • Single Action Object
  • Multiple Actions Array

If you want to perform a single action, there's no need to pass an array of action objects—you can simply provide a single action object. However, if multiple actions need to be executed (e.g., on a button click, radio selection, or checkbox toggle), you can pass an array of actions. These actions will be processed using a queue system, executing them in a first-in, first-out (FIFO) order.

Key Features

  • No coding required - everything configured through JSON
  • Dynamic content updates in real-time
  • Flexible container system for precise content placement
  • Sequential actions for complex workflows
  • Seamless API integration
  • Built-in loading states and notifications
  • Automatic form validation and error handling

Supported Action Types

Complete list of available action types and their descriptions

Action Type Description
apiCall Legacy Action (Only support Single Action). It performs HTTP requests (GET, POST, DELETE) to fetch a JSON screen and loads the response into a specified container based on the defined configuration. Config object required define in json as shown in example
loadScreen Legacy Action (Only support Single Action): It searches for the JSON structure within the config and loads that JSON schema into the designated container defined in config. Config object required define in json as shown in example
appendJson New Action (Supports both single and multiple actions): It allows you to append a new JSON schema to an existing component without removing or clearing the current HTML content. The json parameter accepts either a URL or a direct JSON object. Both parameters required are defined in json as shown in example.
replaceJson New Action (Supports both single and multiple actions): It enables you to remove the existing HTML component and replace it with a new JSON schema. The json parameter supports both URL and direct JSON input. Both parameters required define in json as shown in example
navigate Internally navigates to different pages within the application using query parameters, following Angular routing conventions.
redirect Redirect to an external URL
clearContainer New Action (Supports both single and multiple actions): You can also clear the container content by passing the containerId as a string parameter in the action object. This action is useful when you want to clear the container (Global or Region) content before loading a new JSON schema. It is also useful when you want to close the modal or toast.

Action Type Details

Detailed examples and configurations for each action type

apiCall

Basic Structure:

{
  "action": {
    "actionType": "apiCall",
    "apiConfig": {
      "url": "https://api.example.com/data",
      "method": "GET",
      "containerId": 0
    },
    "loaderStatus": {
      "showLoader": true,
      "loaderType": 1
    }
  }
}

GET Request Example:

{
  "action": {
    "actionType": "apiCall",
    "apiConfig": {
      "url": "https://api.example.com/users",
      "method": "GET",
      "containerId": 0
    }
  }
}

POST Request Example:

{
  "action": {
    "actionType": "apiCall",
    "apiConfig": {
      "url": "https://api.example.com/users",
      "method": "POST",
      "body": "eyJuYW1lIjoiSm9obiIsImVtYWlsIjoiam9obkBleGFtcGxlLmNvbSJ9",
      "containerId": 0
    },
    "loaderStatus": {
      "showLoader": true,
      "loaderType": 1
    }
  }
}

loadScreen

{
  "action": {
    "actionType": "loadScreen",
    "loadScreenConfig": {
      "componentJson": {
        "type": "container",
        "components": [
          {
            "type": "text"
          }
        ]
      },
      "containerId": 0
    }
  }
}

appendJson

{
  "action": {
    "actionType": "appendJson",
    "containerId": "main-content",
    "json": {
      "type": "container",
      "components": [
        {
          "type": "text"         
        }
      ]
    }
  }
}

replaceJson

{
  "action": {
    "actionType": "replaceJson",
    "containerId": "main-content",
    "json": {
      "type": "container",
      "components": [
        {
          "type": "text"         
        }
      ]
    }
  }
}

navigate

{
  "action": {
    "actionType": "navigate",
    "route": {
      "path": "/dashboard",
      "data": {
        "userId": "123",
        "tab": "profile"
      }
    }
  }
}

redirect

{
  "action": {
    "actionType": "redirect",
    "redirectionUrl": "https://www.google.com"
  }
}

clearContainer

{
"action": {
  "actionType": "clearContainer",
  "containerId": "2"
}
}

Screen Actions

Loading screens and navigation between pages

loadScreen Action

{
  "action": {
    "actionType": "loadScreen",
    "loadScreenConfig": {
      "componentJson": {
        "type": "container",
        "components": [
          {
            "type": "text",
            "properties": {
              "text": "Welcome to the new screen!"
            }
          }
        ]
      },
      "containerId": 0
    }
  }
}

tabScreen Action

{
  "action": {
    "actionType": "tabScreen",
    "loadScreenConfig": {
      "screenId": "dashboard-123",
      "containerId": 0
    }
  }
}

JSON Actions

Manipulating content in containers

appendJson Action

Add new content to an existing container without clearing it

{
  "action": {
    "actionType": "appendJson",
    "containerId": "sidebar",
    "json": {
      "type": "text",
      "properties": {
        "text": "This will be added to existing content"
      }
    }
  }
}

replaceJson Action

Replace all content in a container with new content

{
  "action": {
    "actionType": "replaceJson",
    "containerId": "main-content",
    "json": {
      "type": "container",
      "components": [
        {
          "type": "text",
          "properties": {
            "text": "This replaces all previous content"
          }
        }
      ]
    }
  }
}

Multi Action Support

Our Action Engine supports both single and multiple actions. You can either pass a single action as an object or provide multiple actions within an array, depending on your use case.

Sample for single action object:

{
  "action": {
    "actionType": "apiCall",
    "apiConfig": {
      "url": "https://api.example.com/data",
      "method": "GET",
      "containerId": 0
    }
  }
}

Sample for multiple action array:

{
  "action": [
    {
      "actionType": "replaceJson",
      "containerId": "header",
      "json": {
        "type": "text",
        "properties": {
          "text": "Loading..."
        }
      }
    },
    {
      "actionType": "apiCall",
      "apiConfig": {
        "url": "https://api.example.com/data",
        "method": "GET",
        "containerId": 0
      }
    }
  ]
}

Components That Support Actions

Interactive components with action capabilities

Component Type Supports Actions Example Use Case
button ✅ Yes Trigger API calls, navigation, screen loads
link ✅ Yes Trigger API calls, navigation, screen loads
tab ✅ Yes Click to view details, load related content
radio ✅ Yes Trigger API calls, navigation, screen loads
checkbox ✅ Yes Trigger API calls, navigation, screen loads

Example Button Action

{
  "type": "button",
  "btnType": "button",
  "action": {
    "actionType": "apiCall",
    "apiConfig": {
      "url": "https://api.example.com/users",
      "method": "GET",
      "containerId": 0
    }
  }
}

Example Radio Action (with multi region)

{
  "type": "radio",
  "name": "loan_radio",
  "default": "",
  "action": [
    {
      "actionType": "replaceJson",
      "containerId": "loan-info-container",
      "json": "https://test.com?screenId=38"
    },
    {
      "actionType": "replaceJson",
      "containerId": "sa-request-discount-container",
      "json": "https://test.com?&screenId=40"
    }
  ],
  "dpRule": {
    "type": "static",
    "groupClass": [
      "radio-group",
      "mar-y-4"
    ],
    "options": [
      {
        "label": "1",
        "value": "1"
      }
    ]
  }
}

Example Checkbox Action

{
  "type": "checkbox",
  "name": "simpleCheckbox",
  "default": "",
  "dpRule": {
    "type": "static",
    "apiEndpoint": null,
    "pagination": false,
    "drRule": "lazy",
    "autocomplete": true,
    "options": [
      {
        "label": "test",
        "value": "test"
      }
    ]
  },
  "disabled": false,
  "action": {
    "actionType": "apiCall",
    "apiConfig": {
      "url": "https://api.example.com/data",
      "method": "GET",
      "containerId": 0
    }
  },
  "description": "Select preferences"
}

Container / Multi Region System / Single Region

Containers are sections of the UI designed to receive dynamic content updates. Some containers are predefined or globally registered, meaning users cannot modify them directly—but they can be overwritten with its own custom container via "containerId" attr in the "group" component. Therefore, when creating a new container, avoid using a containerId that is already globally registered unless intentional overwriting is required.

With the latest update, developers can register custom containers and dynamically append components using the Action Engine (supporting both single and multi-actions). Multi-region updates are supported only within "group" components, where the "containerId" must be provided. These only support "appendJson" and "replaceJson" action types.

Predefined / Global Containers / Single Region

Container ID Name Purpose
0 Main Body Primary content area
1 Tabs child Content pagination controls
2 Popup / Modal Modal dialogs and popups
3 Toast Temporary notifications

Custom Containers / Multi Region

To register a custom container, start by creating a group component and assigning it a unique containerId.

Example:

{
  "type": "group",
  "containerId": "custom-container-id"
}

This containerId will be used by the Action Engine to target this container when dynamically appending or replacing content.

{
  "action": {
    "actionType": "replaceJson",
    "containerId": "custom-container-id",
    "json": {
      "type": "text"
    }
  }
}

The following action replaces the content inside the container with containerId set to "custom-container-id" with a new text component. This means the existing content within the specified container will be completely cleared and replaced with the new text field defined in the json payload.

You can define as many containers as needed based on your requirements. However, multiple containers should not be initialized with the same containerId, as the last defined container will overwrite the earlier ones with the same ID.

Form Submission Actions

Forms have a specialized submission system that differs from regular actions. Instead of using the standard `action` property, forms use an `onSubmit` configuration that handles form validation, data processing, and submission automatically.

Form Submission Configuration

{
  "type": "form",
  "onSubmit": {
    "method": "POST",
    "action": "https://api.example.com/users",
    "target": "_self",
    "group": 0
  },
  "validatorSchema": {
    "email": {
      "type": "string"
    },
    "name": {
      "type": "string"
    }
  },
  "components": [
    {
      "type": "text",
      "name": "name"
    },
    {
      "type": "text",
      "name": "email"
    },
    {
      "type": "button",
      "btnType": "submit"
    }
  ]
}

Form Submission Properties

Property Type Description Support
method string Ensure that if the API method is POST, the values are passed as a proper request body. For GET requests, the values must be provided as query parameters. GET, POST, PUT, PATCH
action string API endpoint URL for form submission Required
target string Where to handle the response. Mostly use _self _self, _parent, _blank
container number Only global containerId values are supported for loading responses. By default, it uses containerId = 0, but this can be optionally overridden by specifying a different value. 0,1,2,3, no support for multi region yet

Target Behaviors

_self (Default):

{
  "onSubmit": {
    "method": "POST",
    "action": "https://api.example.com/contact",
    "target": "_self",
    "container": 0
  }
}

_parent:

{
  "onSubmit": {
    "method": "POST",
    "action": "https://api.example.com/login",
    "target": "_parent"
  }
}

_blank:

{
  "onSubmit": {
    "method": "POST",
    "action": "https://api.example.com/generate-report",
    "target": "_blank"
  }
}

Complete Contact Form Example

{
  "type": "form",
  "onSubmit": {
    "method": "POST",
    "action": "https://api.example.com/contact-messages",
    "target": "_self",
    "container": 2
  },
  "validatorSchema": {
    "name": {
      "type": "string"
    },
    "email": {
      "type": "string"
    },
    "subject": {
      "type": "string"
    },
    "message": {
      "type": "string"
    }
  },
  "components": [
    {
      "type": "text",
      "name": "name"
    },
    {
      "type": "input",
      "name": "email"
    },   
    {
      "type": "textarea",
      "name": "message"
    },
    {
      "type": "button",
      "btnType": "submit"
    }
  ]
}

Expected API Responses

Success Response:

{
  "code": "000",
  "message": "Success",
  "data": {
    "type": "container",
    "components": [
      {
        "type": "text"
      }
    ]
  }
}

Navigation Response:

{
  "code": "000",
  "route": {
    "path": "/dashboard",
    "data": {
      "userId": "123",
      "welcomeMessage": "Login successful"
    }
  }
}

Error Handling

Forms automatically handle and display:

  • Validation Errors (inline)
  • Submission Errors (toast in container 3)
  • API Errors (from codeDescription)

Error Response Example:

{
  "code": "001",
  "codeDescription": "Email address is already registered"
}

End-to-End Flow Example

Complete user dashboard with dynamic content loading

Scenario: User Dashboard with Dynamic Content Loading

A user visits a dashboard page. When they click a 'Load Reports' button, the system:

  1. Shows a loading message in the sidebar
  2. Fetches report data from an API
  3. Displays the reports in the main content area
  4. Shows a success notification

Complete JSON Configuration

{
  "type": "container",
  "class": "row",
  "components": [
    {
      "type": "container",
      "containerId": "sidebar",
      "components": [
        {
          "type": "text"
        },
        {
          "type": "button",
          "btnType": "button",
          "action": {
            "actionType": "multiAction",
            "actions": [
              {
                "actionType": "replaceJson",
                "containerId": "sidebar-status",
                "json": {
                  "type": "text"
                }
              },
              {
                "actionType": "apiCall",
                "apiConfig": {
                  "url": "https://api.company.com/reports",
                  "method": "GET",
                  "containerId": 0
                },
                "loaderStatus": {
                  "showLoader": true,
                  "loaderType": 1
                }
              },
              {
                "actionType": "appendJson",
                "containerId": 3,
                "json": {
                  "type": "toast"
                }
              }
            ]
          }
        },
        {
          "type": "container",
          "containerId": "sidebar-status",
          "components": [
            {
              "type": "text"
            }
          ]
        }
      ]
    },
    {
      "type": "group",
      "containerId": "main-content",
      "components": [
        {
          "type": "text"
        },
        {
          "type": "text"
        }
      ]
    }
  ]
}

Expected API Response Structure

{
  "data": {
    "type": "group",
    "components": [
      {
        "type": "text"
      }
    ]
  }
}

Field-by-Field Documentation

Detailed explanation of each field and component in Action Factory

Action Object Structure

The action object is the core configuration that defines what happens when an action is triggered. It contains all the necessary information to execute the desired functionality.

{
  "action": {
    "actionType": "apiCall",
    "apiConfig": {
      "url": "https://api.example.com/data",
      "method": "GET",
      "containerId": 0
    },
    "loaderStatus": {
      "showLoader": true,
      "loaderType": 1
    }
  }
}

actionType Field

Purpose: Specifies the type of action to be executed

Type: String (required)

Valid Values:

  • apiCall - Make HTTP requests to external APIs
  • loadScreen - Load a complete screen with component JSON
  • tabScreen - Load a screen from API using screen ID
  • appendJson - Add content to existing container
  • replaceJson - Replace all content in container
  • navigate - Navigate to different page
  • encodedNavigate - Navigate with encoded data
  • redirect - Redirect to external URL

Example: "actionType": "apiCall"

apiConfig Object

Purpose: Configuration for API call actions (used when actionType is "apiCall")

Type: Object (required for apiCall actions)

apiConfig.url

Purpose: The endpoint URL to make the HTTP request to

Type: String (required)

Example: "url": "https://api.example.com/users"

apiConfig.method

Purpose: HTTP method to use for the request

Type: String (required)

Valid Values: GET, POST, PUT, DELETE, PATCH

Example: "method": "POST"

apiConfig.containerId

Purpose: Specifies which container to load the API response into

Type: Number or String (required)

Predefined Values:

  • 0 - Main Body (primary content area)
  • 1 - Tabs child (content pagination controls)
  • 2 - Popup (modal dialogs)
  • 3 - Toast (temporary notifications)

Custom Values: Any string for custom containers (e.g., "sidebar", "user-panel")

Example: "containerId": 0 or "containerId": "user-sidebar"

apiConfig.body

Purpose: Request body data (typically for POST/PUT requests)

Type: String (optional)

Format: Base64 encoded JSON string

Example: "body": "eyJuYW1lIjoiSm9obiIsImVtYWlsIjoiam9obkBleGFtcGxlLmNvbSJ9"

Note: This is the base64 encoded version of: {"name":"John","email":"john@example.com"}

loaderStatus Object

Purpose: Controls the loading state display during API calls

Type: Object (optional)

loaderStatus.showLoader

Purpose: Whether to display a loading indicator

Type: Boolean (optional)

Default: false

Example: "showLoader": true

loaderStatus.loaderType

Purpose: Type of loading indicator to display

Type: Number (optional)

Values:

  • 1 - Spinner loader
  • 2 - Progress bar
  • 3 - Skeleton loader

Example: "loaderType": 1

loadScreenConfig Object

Purpose: Configuration for screen loading actions (used when actionType is "loadScreen" or "tabScreen")

Type: Object (required for loadScreen/tabScreen actions)

loadScreenConfig.componentJson

Purpose: The complete component structure to load into the container

Type: Object (required for loadScreen)

Example:

{
  "componentJson": {
    "type": "container",
    "components": [
      {
        "type": "text",
        "properties": {
          "text": "Welcome to the new screen!"
        }
      }
    ]
  }
}

loadScreenConfig.screenId

Purpose: Unique identifier for the screen to load from API

Type: String (required for tabScreen)

Example: "screenId": "dashboard-123"

loadScreenConfig.containerId

Purpose: Which container to load the screen content into

Type: Number or String (required)

Example: "containerId": 0

containerId Field (for JSON Actions)

Purpose: Specifies which container to manipulate (used in appendJson and replaceJson actions)

Type: String (required)

Example: "containerId": "sidebar" or "containerId": "main-content"

Note: Can be any custom container identifier

json Field (for JSON Actions)

Purpose: The component structure to add or replace in the container

Type: Object (required for appendJson and replaceJson)

Example:

{
  "json": {
    "type": "text",
    "properties": {
      "text": "This will be added to existing content"
    }
  }
}

route Object (for Navigation Actions)

Purpose: Navigation configuration (used when actionType is "navigate" or "encodedNavigate")

Type: Object (required for navigation actions)

route.path

Purpose: The URL path to navigate to

Type: String (required)

Example: "path": "/dashboard"

route.data

Purpose: Data to pass as query parameters

Type: Object (optional)

Example:

{
  "data": {
    "userId": "123",
    "tab": "profile"
  }
}

Note: For encodedNavigate, this data will be base64 encoded in the URL

redirectionUrl Field

Purpose: External URL to redirect to (used when actionType is "redirect")

Type: String (required for redirect actions)

Example: "redirectionUrl": "https://www.google.com"

Complete Example with All Fields Explained

{
  "action": {
    // Specifies this is an API call action
    "actionType": "apiCall",
    
    // API configuration object
    "apiConfig": {
      // The endpoint URL to call
      "url": "https://api.example.com/users",
      
      // HTTP method (GET, POST, PUT, DELETE)
      "method": "POST",
      
      // Which container to load response into
      "containerId": 0,
      
      // Request body (base64 encoded)
      "body": "eyJuYW1lIjoiSm9obiIsImVtYWlsIjoiam9obkBleGFtcGxlLmNvbSJ9"
    },
    
    // Loading state configuration
    "loaderStatus": {
      // Show loading indicator
      "showLoader": true,
      
      // Type of loader (1=spinner, 2=progress, 3=skeleton)
      "loaderType": 1
    }
  }
}

Coming Soon

Documentation sections currently in development

In progress

This section is currently being developed and will be available soon. We're working hard to provide comprehensive documentation for all features.

Stay Updated

Check back regularly for updates and new documentation sections. We're continuously improving and expanding our documentation to provide the best developer experience.