Skip to main content

Carerix Marketplace Framework - user interface configuration

This document outlines the structure and configuration details of the $.manifest.ui section.

Make sure you have also read our articles on Marketplace technical configuration and SSO.

Section Structure

The following table describes the structure of the $.manifest.ui section:

  • Path: $.components

    • Type: array

    • Description: List of component definitions

    • Example:

      - id: 'my-feature.component-id'
      type: 'left-menu-item'
      config:
      text: 'New Menu Item'
  • Path: $.components[*].id

    • Type: string

    • Description: - REQUIRED - Unique identifier of the component. To prevent conflicts, prefix all IDs with a unique feature prefix.

    • Example:

      'my-feature-id.my-component-id'
  • Path: $.components[*].type

    • Type: string

    • Description: - REQUIRED - The type of component being injected. See Component Types.

    • Example:

      'left-menu-item'
  • Path: $.components[*].parentId

    • Type: string

    • Description: The ID of the parent component into which the new component will be injected.

    • Example:

      'candidate-details.tabpanel'
  • Path: $.components[*].config

    • Type: object

    • Description: Configuration settings specific to the component type (see Component Types)

    • Example:

      text: 'New Menu Group'
      order: 2
  • Path: $.components[*].filters

    • Type: array

    • Description: List of filters that conditionally modify or remove the component (see Component Filters)

    • Example:

      - action:
      type: 'remove'
      condition:
      type: 'has-permission'
      expectedValue: false
      options:
      resource: 'urn:cx/activities:data/tasks'
      operation: 'access'
  • Path: $.translations

    • Type: array

    • Description: List of translation objects

    • Example:

      - key: 'MY_FEATURE.NAME'
      values:
      en_US: 'My Feature Name'
      nl_NL: 'Mijn Functienaam'
  • Path: $.translations[*].key

    • Type: string

    • Description: - REQUIRED - Translation key. To prevent conflicts with translations from other features, it is advisable to prefix all translation keys with a unique feature prefix.

    • Example:

      'MY_FEATURE.NAME'
  • Path: $.translations[*].values

    • Type: object

    • Description: - REQUIRED - [locale]: string object. en_US is always required. If a user's language is not found in the values object, the system will default to en_US.

    • Example:

      en_US: 'My Feature'
      nl_NL: 'Mijn Functienaam'

ℹ️ Full list of supported locales:

  • en_US - English required (fallback locale)

  • nl_NL - Dutch

  • it_IT - Italian

  • de_DE - German

  • es_ES - Spanish

  • fr_FR - French

  • pt_PT - Portuguese


Component Types

The list below shows all available component types.
Carerix determines which options are granted per partner.

Left Menu Group

Injects a new menu group into the application's left-side menu.

  • Type: left-menu-group

  • Config:

    • text - REQUIRED - The display name of the group

    • order - The position of the group in the left menu

  • Parent ID: N/A

  • Example:

    components:
    - id: 'feature-id.new-menu-group'
    type: 'left-menu-group'
    config:
    text: 'New Menu Group'
    order: 0

Left Menu Item

Injects a new item into an existing or newly created left menu group.

  • Type: left-menu-item

  • Config:

    • text - REQUIRED - The display name of the menu item

    • order - The position of the item in the menu group

    • icon - The SVG icon string for the menu item

    • command - REQUIRED - The command to be performed when clicked. See Commands.

      • type - The type of command to perform

      • data - Execution data for that command type

  • Parent ID: The ID of the menu group. Can be an existing group or a new one.

    • Existing menu group IDs:

      • Activiteitenmenu - 'Activities' menu

      • Dossiersmenu - 'Files' menu

      • Financieelmenu - 'Financial' menu

      • Marketingmenu - 'Marketing' menu

      • Beheermenu - 'Management' menu

      • Onderhoudmenu - 'Maintenance' menu

  • Example:

    components:
    - id: 'feature-id.new-menu-item'
    type: 'left-menu-item'
    parentId: 'Dossiersmenu'
    config:
    text: 'New Menu Item'
    order: 0
    icon: '<svg ...</svg>'
    command:
    type: 'open-iframe-view'
    data:
    url: 'https://....'

Custom Tab

Injects a new tab (iframe).

  • Type: tab

  • Config:

    • text - REQUIRED - The tab's display name

    • url - REQUIRED - The tab's URL

      URL Variables: The URL supports variables for context information:

      • {{ _id }} - current record ID (e.g., 12345)

      • {{ _kind }} - current record type (e.g., CREmployee, CRVacancy)

      • {{ tenant }} - name of the tenant

      • Example URL: https://my-app.com/?entityKind={{_kind}}&entityId={{_id}}&tenant={{tenant}}

  • Parent ID: The ID of the details tab panel component.

    • ID patterns:

      • Entity details pages: {entityName}-details.tabpanel

      • Entity overview pages: {entityName}-overview.tabpanel

        Where {entityName} is one of the following: email, note, event, task, systemactivity, match, candidate, vacancy, talentpool, lead, opportunity, contact, company, publication, placement, officeemployee

      • Calendar page: calendar.tabpanel

      • Example for Entity Details: candidate-details.tabpanel

      • Example for Entity Overviews: candidate-overview.tabpanel

      • Example for Calendar Page: calendar.tabpanel

  • Example:

    components:
    - id: 'feature-id.new-tab-in-candidate-details'
    type: 'tab'
    parentId: 'candidate-details.tabpanel'
    config:
    text: 'My new Iframe Tab in Candidate details'
    url: 'https://my-app.com/?entityId={{_id}}&entityKind={{_kind}}&tenant={{tenant}}'

Background Agent

A background iframe that is loaded once at the app bootstrap stage.

  • Type: background-agent

  • Config: url - REQUIRED - The iframe's src

  • Parent ID: N/A

  • Example:

    components:
    - id: 'feature-id.my-background-process'
    type: 'background-agent'
    config:
    url: 'https://my-app.com/'

Commands

Structure

Field

Type

Description

type

string

Type of command

data

object

Command's data

Command Types

  • Type: open-iframe-view

  • Data: url - REQUIRED - Iframe URL

    • The URL supports variables, allowing you to include context information: {{ tenant }} - name of the tenant

    • Example: url: 'https://my-app.com/?tenant={{tenant}}'

  • Description: Open data.url in the main viewport

  • Example:

    type: 'open-iframe-view'
    data:
    url: 'https://my-app.url/?tenant={{ tenant }}'
  • Type: open-entity-details

  • Data:

    • entity - REQUIRED

      • _id - REQUIRED - Entity ID

      • _kind - REQUIRED - Entity kind (e.g., Candidate)

    • activeTab - ID of tab to activate (optional, defaults to first tab)

  • Description: Open data.entity details page in the main viewport

  • Example:

    type: 'open-entity-details'
    data:
    entity:
    _kind: 'Candidate'
    _id: '1234'
    activeTab: 'my-tab-id'
  • Type: open-entity-preview

  • Data:

    • entity - REQUIRED

      • _id - REQUIRED - Entity ID

      • _kind - REQUIRED - Entity kind (e.g., Candidate)

    • activeTab - ID of tab to activate (optional, defaults to first tab)

  • Description: Open data.entity preview modal

  • Example:

    type: 'open-entity-preview'
    data:
    entity:
    _kind: 'Candidate'
    _id: '1234'
    activeTab: 'my-tab-id'
  • Type: open-entity-overview

  • Data:

    • entity - REQUIRED - Entity name (e.g., Candidate)

  • Description: Opens data.entity overview (entity list) page

  • Example:

    type: 'open-entity-overview'
    data:
    entity: 'Candidate'
  • Type: update-menu-item-info

  • Data:

    • menuItemId - REQUIRED - ID of menu item to update

    • counter - Counter value

  • Description: Updates a menu item

  • Example:

    type: 'update-menu-item-info'
    data:
    menuItemId: 'feature-x-menu-item'
    counter: 10

Component Filters

Filters are used to adjust a component's visibility or configuration based on specific conditions, like user permissions, system settings or your feature's own settings.

Structure

Field

Type

Description

action

object

Action for the filter to execute

action.type

string

Action type

action.options

object

Options for the action type

condition

object

The condition under which the action is executed.

condition.type

string

Condition type

condition.options

object

Options of the condition type

condition.expectedValue

boolean / string / number

The expected value of a condition to be met

Examples:

type: 'apply-config'
options:
config:
text: 'Conditional Text'
type: 'has-permission'
expectedValue: false
options:
resource: 'urn:cx/activities:data/tasks'
operation: 'access'

Action Types

  • Type: remove

  • Options: none

  • Description: Removes the component if the condition is met.

  • Example:

    - id: 'my-menu-item'
    config:
    ...
    filters:
    - action:
    type: 'remove'
    condition:
    type: 'has-permission'
    expectedValue: false
    options:
    resource: 'urn:my-resource'
    operation: 'access'
  • Type: remove-property-from-path

  • Options:

    • path - REQUIRED - Array<string | number> - Path to the property within the config object

  • Description: Removes a specific property from the config object.

  • Example:

    - id: 'my-menu-item'
    config:
    text: 'Text'
    showCreateButton: true
    filters:
    - action:
    type: 'remove-property-from-path'
    options:
    path:
    - showCreateButton
    condition:
    type: 'has-permission'
    expectedValue: false
    options:
    resource: 'urn:my-resource'
    operation: 'create'
  • Type: apply-config

  • Description: Applies a config object to the existing one using PATCH merge strategy.

  • Options:

    • config - REQUIRED - Config object to apply

  • Example:

    - id: 'my-menu-item'
    config:
    text: 'Text'
    filters:
    - action:
    type: 'apply-config'
    options:
    config:
    showCreateButton: true
    condition:
    type: 'has-permission'
    expectedValue: true
    options:
    resource: 'urn:my-resource'
    operation: 'create'

Condition Types

  • Type: has-permission

  • Description: Checks if the user has a specific permission.

  • Options:

    • resource : string - REQUIRED - Resource name

    • operation : string - REQUIRED - Operation name

  • Example:

    condition:
    type: 'has-permission'
    expectedValue: true
    options:
    resource: 'urn:my-resource'
    operation: 'create'
  • Type: has-some-permissions

  • Description: Checks if the user has any of the specified permissions.

  • Options:

    • Array of permission objects:

      • [*].resource : string - REQUIRED - Resource name

      • [*].operation : string - REQUIRED - Operation name

  • Example:

    condition:
    type: 'has-some-permissions'
    expectedValue: true
    options:
    - resource: 'urn:my-resource'
    operation: 'access'
    - resource: 'urn:my-resource-2'
    operation: 'access'
  • Type: system-setting

  • Description: Checks a system setting value.

  • Options:

    • settingName : string - REQUIRED - Setting name

  • Example:

    condition:
    type: 'system-setting'
    expectedValue: 'my-dev-system-name'
    options:
    settingName: 'customerName'
  • Type: feature-setting

  • Description: Checks the value the tenant has stored for one of your feature's settings (the settings declared in your manifest and set by the tenant administrator in the Marketplace).

  • Options:

    • featureId : string - REQUIRED - ID of the feature that owns the setting, i.e. the $.id of its manifest (normally your own feature)

    • settingName : string - REQUIRED - The code of the setting. Use the bare code, not service.code: the settings of all services in a manifest are combined into one list.

  • Matching: The stored value is compared to expectedValue with strict equality: same type and same value. See the recipe Show or Hide a Component Based on a Feature Setting.

  • Example:

    condition:
    type: 'feature-setting'
    expectedValue: true
    options:
    featureId: 'feature-x'
    settingName: 'disableAdvancedTab'

Recipes

Add a New Menu Item to the Activities Menu

Manifest

ui:
components:
- id: 'feature-x.my-settings'
type: 'left-menu-item'
parentId: 'Activiteitenmenu'
config:
text: 'My Settings'
order: 0
icon: '<svg...</svg>'
command:
type: 'open-iframe-view'
data:
url: 'https://my-app.com/my-settings-page'

UI Result

Add a New Menu Group and Menu Item

Manifest

ui:
components:
- id: 'feature-x.new-menu-group'
type: 'left-menu-group'
config:
text: 'My Feature'
order: 0

- id: 'feature-x.my-settings-menu-item'
type: 'left-menu-item'
parentId: 'feature-x.new-menu-group'
config:
text: 'My Settings'
order: 0
icon: '<svg....</svg>'
command:
type: 'open-iframe-view'
data:
url: 'https://my-app.com/my-settings-page'

UI Result

Add a Custom Tab to the Candidate Details Page

Manifest

ui:
components:
- id: 'feature-x.my-new-tab-in-candidate-details'
type: 'tab'
parentId: 'candidate-details.tabpanel'
config:
text: 'My Tab In Candidate'
url: 'https://my-app.com/?entityId={{_id}}&entityKind={{_kind}}&tenant={{tenant}}'

UI Result

Add a Custom Tab to the Calendar Page

Manifest

id: 'feature-x'
name: 'MARKETPLACE.FEATURE-X.NAME'
description: 'MARKETPLACE.FEATURE-X.DESCRIPTION'
....
ui:
components:
- id: 'feature-x.custom-tab-in-calendar-id'
parentId: 'calendar.tabpanel'
type: 'tab'
config:
text: 'New Tab'
url: 'https://my-app.com/?tenant={{tenant}}'

UI Result

Remove Component Based on User Permissions

Manifest

ui:
components:
- id: 'feature-x.restricted-tab'
type: 'tab'
parentId: 'candidate-details.tabpanel'
config:
text: 'Tab'
url: 'https://my-app.com/?entityId={{_id}}&entityKind={{_kind}}&tenant={{tenant}}'
filters:
- action:
type: 'remove'
condition:
type: 'has-permission'
expectedValue: false
options:
resource: 'urn:my-feature:my-resource'
operation: 'access'

Show or Hide a Component Based on a Feature Setting

Combine the remove action with the feature-setting condition. This works for every component type: tabs, menu items, menu groups and top-bar buttons.

In this example, your manifest declares a checkbox setting with code disableAdvancedTab that the tenant administrator can switch on in the Marketplace. See Marketplace technical configuration (Settings section) for how to declare settings.

Manifest

id: 'feature-x'
....
ui:
components:
- id: 'feature-x.advanced-tab'
type: 'tab'
parentId: 'candidate-details.tabpanel'
config:
text: 'Advanced'
url: 'https://my-app.com/?entityId={{_id}}&entityKind={{_kind}}&tenant={{tenant}}'
# Remove the tab as soon as the customer switches the setting on
filters:
- action:
type: 'remove'
condition:
type: 'feature-setting'
expectedValue: true
options:
featureId: 'feature-x'
settingName: 'disableAdvancedTab'

Make sure expectedValue has the same type as the stored setting value:

Setting type

Stored value

expectedValue

checkbox

boolean

true / false, unquoted. 'true' never matches.

singleLineText, multiLineText, radioGroup

string

The exact text or option code, quoted.

Add Component with Multi-Language Support

Manifest

ui:
translations:
- key: 'MARKETPLACE.FEATURE-X.MENU_ITEM_TEXT' # This is the key you need to use in the component instead of actual text
values:
en_US: 'English text'
nl_NL: 'Nederlandse tekst'
components:
- id: 'feature-x.new-menu-item'
type: 'left-menu-item'
parentId: '...'
config:
text: 'MARKETPLACE.FEATURE-X.MENU_ITEM_TEXT' # Here you specify the translation key from translations[*].key
...

Add Translations for Feature Name and Description

Manifest

id: 'feature-x'
name: 'MARKETPLACE.FEATURE-X.NAME'
description: 'MARKETPLACE.FEATURE-X.DESCRIPTION'
....
ui:
translations:
- key: 'MARKETPLACE.FEATURE-X.NAME'
values:
en_US: 'My awesome feature name'
nl_NL: 'Mijn geweldige featurenaam'
- key: 'MARKETPLACE.FEATURE-X.DESCRIPTION'
values:
en_US: 'My awesome feature description'
nl_NL: 'Mijn geweldige functiebeschrijving'

Add Item to Topbar Quick Access Panel

Manifest

ui:
components:
- id: 'feature-x.new-topbar-item'
type: 'button'
parentId: 'quick-access-panel'
config:
icon: '<svg width="24px" height="24px".....'
order: 0
command:
type: 'open-iframe-view'
data:
url: 'https://my-app.com/my-settings-page'

UI Result


Want to learn more about our partnerships? Send us an email - support@carerix.com

Did this answer your question?