Skip to content

Build cross-panel journeys

A useful configurator screen is usually a chain, not an isolated panel: selection supplies a request, an editor mutates data, and a response refreshes the panels the user can see. This guide assembles the shared contracts into complete tasks and links only to checked-in fixtures that demonstrate the described behavior.

Choose a journey

User taskShared capabilitiesChecked-in fixture
Select a master and inspect dependent dataapplication/group, event registry, condition, linked and single-object requestslocal-object-api-contract-demo
Filter and page a selected child collectionmaster event, linked-attribute request, visible filter state, server paginationlocal-filter-counter-demo
Replace a default branch after object selectionone selection event, Condition default/objectSelected, selected-object Attributes requestlocal-shared-config-journeys
Adapt nested JSON rows with local controlscustom GET, dataPath, non-default idField, typed columns, client sorting and paginationlocal-shared-config-journeys
Browse files linked to a selected objectselection event, ObjectToDataSetLink, file metadata/bytes, filesList, previewslocal-shared-config-journeys
Inspect assignments for a selected objectselection event, Calendar widget callback, Calendar/GetCalendarAssignments DTOlocal-shared-config-journeys
Publish a backend workflow without editingmethod request, triple-nested object/link graph, node mappings, readOnlylocal-shared-config-journeys
Create or edit an object and see current dataaction editor, metadata, Object API, reload/refetch lifecyclelocal-object-api-contract-demo
Run a method and show its response feedbackselection, runMethod, response processor, toast/modal notificationlocal-notification-display-modes

Use the smallest journey that represents the real task. Do not add variables, drawers, custom HTTP, or method requests when direct selection and object APIs solve the current problem.

Shared prerequisites

  • A backend application record returns the JSON envelope.
  • Every panel and event ID is unique and stable.
  • Referenced MetaTypes, links, attributes, methods, and permissions exist.
  • The source variant emits the configured event.
  • A selected-object consumer references an event with addSelectedObjectToRequest.
  • A runnable demo requires the local fixture server and the demo URL configured by the docs site. The links below target fixtures present in this checkout.

Minimal two-panel chain

This is the smallest coherent selection journey. It assumes ProductionOrder exists.

json
{
  "version": "1.0.0",
  "panel": {
    "id": "orders-root",
    "type": "group",
    "groupLayout": { "type": "rows" },
    "panels": [
      {
        "id": "orders",
        "type": "table",
        "request": { "metaTypeName": "ProductionOrder" },
        "events": [
          {
            "id": "order-selected",
            "name": "onObjectSelect",
            "actions": [{ "name": "addSelectedObjectToRequest" }]
          }
        ],
        "columns": [{ "attribute": "name", "label": "Order" }]
      },
      {
        "id": "order-details",
        "type": "attributes",
        "condition": {
          "scenario": "objectSelected",
          "eventId": "order-selected"
        },
        "request": {
          "getSelectedObjectForEventId": "order-selected"
        },
        "editor": {
          "fields": [{ "attribute": "name", "readonly": true }]
        }
      }
    ]
  }
}

Expected behavior: the detail panel is absent before selection, mounts after a row selection, loads that object's name, and disappears when the stored selection is reverted.

Condition selection and custom JSON rows

The checked-in shared-config fixture places two independent journeys in tabs. The first uses the Condition variant's own child selector, where default is the visible fallback and objectSelected replaces it after the source event:

json
{
  "id": "local-shared-config-condition-journey",
  "type": "group",
  "groupLayout": { "type": "rows", "resizable": true },
  "panels": [
    {
      "id": "local-shared-config-condition-orders",
      "type": "table",
      "request": { "metaTypeName": "LocalOrder" },
      "events": [
        {
          "id": "local-shared-config-order-selected",
          "name": "onObjectSelect",
          "actions": [{ "name": "addSelectedObjectToRequest" }]
        }
      ],
      "columns": [
        { "attribute": "code", "label": "Code", "sortable": true },
        { "attribute": "product", "label": "Product", "sortable": true },
        { "attribute": "status", "label": "Status" }
      ]
    },
    {
      "id": "local-shared-config-condition-branch",
      "type": "condition",
      "panels": [
        {
          "id": "local-shared-config-condition-default",
          "type": "message",
          "condition": { "scenario": "default" },
          "content": {
            "heading": "Default branch",
            "text": "Select an order."
          }
        },
        {
          "id": "local-shared-config-condition-selected",
          "type": "attributes",
          "condition": {
            "scenario": "objectSelected",
            "eventId": "local-shared-config-order-selected"
          },
          "request": {
            "getSelectedObjectForEventId": "local-shared-config-order-selected"
          },
          "editor": {
            "mode": "panel",
            "fields": [
              { "attribute": "code", "readonly": true },
              { "attribute": "product", "readonly": true },
              { "attribute": "status", "readonly": true },
              { "attribute": "priority", "type": "Integer", "readonly": true }
            ]
          }
        }
      ]
    }
  ]
}

Interaction sequence:

  1. Before selection, the Condition renderer chooses the Message child marked default.
  2. Selecting an order emits the fixture's only event and stores its object selector.
  3. The objectSelected child becomes the chosen branch because its eventId resolves an event containing addSelectedObjectToRequest.
  4. Attributes loads the same selected order through getSelectedObjectForEventId.

The second tab adapts the base fixture application's JSON envelope as a custom Table data source:

json
{
  "id": "local-shared-config-custom-request",
  "type": "table",
  "request": {
    "customRequest": {
      "method": "GET",
      "url": "/applications/local-panel-fixtures/json-data",
      "dataPath": "panel.panels",
      "idField": "type"
    }
  },
  "pagination": { "rowsPerPage": [1, 2] },
  "columns": [
    {
      "attribute": "id",
      "dataType": "String",
      "label": "Panel ID",
      "sortable": true
    },
    {
      "attribute": "type",
      "dataType": "String",
      "label": "Type",
      "sortable": true
    },
    {
      "attribute": "panelLayout",
      "dataType": "Json",
      "label": "Size settings"
    }
  ]
}

The response's nested panel.panels array contains two real rows. Their message and table types are unique, so this fixture can use type instead of the default id as stable row identity. Sorting the marked columns and choosing page size 1 or 2 operate on the complete response in the client. The custom executor uses only method and url; this journey intentionally does not claim request body or header support.

Run the Condition selection and Custom request tabs

Master-detail selection

Use this journey when a parent object owns linked children and a detail view.

Configuration

json
{
  "version": "1.0.0",
  "description": {
    "en": "Select an order to inspect operations and attributes.",
    "ru": "Выберите заказ, чтобы посмотреть операции и атрибуты."
  },
  "panel": {
    "id": "order-workspace",
    "type": "group",
    "groupLayout": { "type": "rows", "resizable": true },
    "panels": [
      {
        "id": "orders",
        "type": "table",
        "panelLayout": { "size": { "value": 40, "min": 25 } },
        "request": {
          "metaTypeName": "ProductionOrder",
          "attributeList": ["code", "name", "status"]
        },
        "pagination": { "rowsPerPage": [10, 25] },
        "events": [
          {
            "id": "order-selected",
            "name": "onObjectSelect",
            "actions": [
              { "name": "preventUnselectFromOtherPanels" },
              { "name": "unselectObjectsInOtherPanels" },
              { "name": "addSelectedObjectToRequest" }
            ]
          }
        ],
        "columns": [
          { "attribute": "code", "label": "Code", "sortable": true },
          { "attribute": "name", "label": "Name" },
          { "attribute": "status", "label": "Status" }
        ]
      },
      {
        "id": "operations",
        "type": "table",
        "panelLayout": { "size": { "value": 35, "min": 20 } },
        "condition": {
          "scenario": "objectSelected",
          "eventId": "order-selected"
        },
        "request": {
          "getSelectedObjectForEventId": "order-selected",
          "linkName": "OrderOperation",
          "reverse": false,
          "attributeList": ["code", "status", "link.sequence"]
        },
        "pagination": { "rowsPerPage": [10, 25] },
        "columns": [
          { "attribute": "code", "label": "Operation" },
          { "attribute": "status", "label": "Status" },
          { "attribute": "link.sequence", "label": "Sequence" }
        ]
      },
      {
        "id": "order-attributes",
        "type": "attributes",
        "panelLayout": { "size": { "value": 25, "min": 15 } },
        "condition": {
          "scenario": "objectSelected",
          "eventId": "order-selected"
        },
        "request": {
          "getSelectedObjectForEventId": "order-selected"
        },
        "editor": {
          "fields": [
            { "attribute": "code", "readonly": true },
            { "attribute": "name", "readonly": true },
            { "attribute": "status", "readonly": true }
          ]
        }
      }
    ]
  }
}

Interaction sequence

  1. The orders Table runs a standard MetaType request.
  2. Row selection runs the ordered event actions.
  3. addSelectedObjectToRequest stores the object selector under order-selected.
  4. Both dependent conditions pass and mount their panels.
  5. Operations loads getLinkedObjects; Attributes loads the object by GUID.
  6. A new selection replaces the event selector and both dependents refetch.

Runnable fixture

The fixture uses local MetaTypes and the same standard/linked/by-GUID chain:

Run the master, linked collection, Attributes, and read-only detail journey

Filter a selected child collection

Use this journey when children store a reference attribute to their parent and the user must narrow the resulting collection.

Configuration

json
{
  "id": "order-operations",
  "type": "group",
  "groupLayout": { "type": "rows" },
  "panels": [
    {
      "id": "orders",
      "type": "table",
      "request": { "metaTypeName": "ProductionOrder" },
      "events": [
        {
          "id": "order-selected",
          "name": "onObjectSelect",
          "actions": [{ "name": "addSelectedObjectToRequest" }]
        }
      ],
      "columns": [{ "attribute": "code", "label": "Order" }]
    },
    {
      "id": "operations",
      "type": "table",
      "condition": {
        "scenario": "objectSelected",
        "eventId": "order-selected"
      },
      "request": {
        "metaTypeName": "Operation",
        "getSelectedObjectForEventId": "order-selected",
        "linkedAttribute": "order",
        "sortParams": [
          { "attribute": "code", "sortDirection": "ASC" }
        ]
      },
      "filter": {
        "fields": [
          { "attribute": "code", "label": "Code" },
          { "attribute": "status", "label": "Status" }
        ]
      },
      "pagination": { "rowsPerPage": [5, 10, 25] },
      "columns": [
        { "attribute": "code", "label": "Operation", "sortable": true },
        { "attribute": "status", "label": "Status", "sortable": true }
      ]
    }
  ]
}

Expected behavior and precedence

  • Selecting an order appends the runtime equality filter order = <selected GUID>.
  • Visible user filters are added as findAttributes.
  • Applying a filter resets the child offset to the first page while keeping its current page size.
  • Clicking a sortable header changes server sorting for this standard linked-attribute request.
  • An explicit request.attributeList, if added, must include columns required for display; filter/sort fields do not enlarge it.
Run the selected-parent, linked-attribute, filter-counter, and pagination journey

Create, edit, and refresh

Use this journey when a panel must mutate an object and immediately show the authoritative returned state.

Panel actions

json
{
  "panelActions": [
    {
      "id": "order-mutations",
      "label": "Order",
      "renderType": "inline_buttons",
      "actions": [
        {
          "id": "create-order",
          "method": "create",
          "label": "Create",
          "icon": "plus",
          "editor": {
            "mode": "modal",
            "entityType": {
              "object": { "metaTypeName": "ProductionOrder" }
            },
            "fields": [
              {
                "attribute": "code",
                "type": "String",
                "regEx": "^PO-[0-9]+$"
              },
              { "attribute": "name", "type": "String" },
              {
                "attribute": "status",
                "type": "String",
                "listOfValue": "[\"draft\",\"released\"]",
                "defaultValue": "draft"
              }
            ]
          }
        },
        {
          "id": "update-order",
          "method": "update",
          "label": "Edit",
          "icon": "pencil",
          "editor": {
            "mode": "modal",
            "entityType": {
              "object": { "metaTypeName": "ProductionOrder" }
            },
            "fields": [
              { "attribute": "code", "readonly": true },
              { "attribute": "name" },
              { "attribute": "status" }
            ]
          }
        }
      ]
    }
  ]
}

Interaction sequence

  1. Create loads MetaType metadata, then explicit field values override it.
  2. The editor validates regex/JSON fields and submits the object.
  3. Update requires a current panel selection and loads the selected object detail before applying defaults.
  4. Loaded values win over defaultValue.
  5. The mutation lifecycle invalidates/refetches the affected visible data.
  6. Dependent panels resolve the current event selector and show the updated object.

The exact refresh path depends on the owning action/variant. When a method or HTTP endpoint does not participate in the object mutation lifecycle, configure a targeted reloadEntities response action.

Run local Object create, update, projection, and dependent-detail refresh Inspect typed defaults, metadata precedence, validation, and object selection

Method response feedback

Use this journey when the backend method returns client actions and the user needs explicit completion feedback.

json
{
  "id": "release-order",
  "method": "runMethod",
  "label": "Release",
  "request": {
    "parent": "ProductionOrder",
    "methodName": "release",
    "objects": [{ "getFromItem": true }]
  },
  "response": {
    "actions": [
      {
        "id": "reload-orders",
        "method": "reloadEntities",
        "label": "",
        "panels": [{ "panelId": "orders" }]
      },
      {
        "id": "release-success",
        "method": "showNotification",
        "label": "",
        "mode": "toast",
        "severity": "success",
        "summary": "Released",
        "message": "The order was released.",
        "life": 5000
      }
    ]
  }
}

Response actions run in order. The shared response processor currently handles reloadEntities and showNotification. The server response contract must provide or allow these actions; their presence in JSON does not repair an incompatible method response.

Run checked-in method-response toast and modal notifications

Limits and unsupported combinations

  • The Method request tab in local-shared-config-journeys proves the complete Table path from request.methodName, request.parent, and a fixed object endpoint through the shared request router to POST /MetaMethods/Run and an ObjectsResponse. It does not prove event-selected or created-object method arguments; use the request guide for those endpoint alternatives.
  • Direct Link mutation fixture handlers exist, but the interactive Object API journey does not exercise direct Link create/update/by-GUID.
  • Selection/event state is in memory and resets on reload.
  • A hidden dependent panel can unmount and clear variables marked cleanOnUnmounted.
  • required is not enforced by shared editor validation.
  • Schedule, BPMN, Files, Core Apps, and other package/variant journeys have additional ownership boundaries; use their variant guides.

Exact property reference

Next tasks