Skip to content

Connect panels with events

Events turn a local interaction into application state that another panel can consume. Use them for master-detail selection, coordinated unselection, visibility variables, and drawers. Conditions read that state to decide which panels are mounted.

An event is not a generic message bus. Only configured event names and action branches are handled, and the selection registry is in-memory application state.

Prerequisites and identity

  • The source variant must actually emit the chosen event name.
  • Event id must be stable and unique anywhere it will be referenced.
  • name matches the runtime occurrence; it is not a custom event name.
  • Actions execute in array order.
  • A selected-object consumer needs addSelectedObjectToRequest, not merely an onObjectSelect event.

Event names

NameIntended occurrenceTypical emitters
onButtonClickan actions wrapper is activatedcommon action surface
onObjectSelectobject or node selection changesTable, Tree
onObjectCreatea configured create lifecycle emitseditor/variant-specific flows
onObjectUpdatean update lifecycle emitseditor/variant-specific flows
onObjectDeletea delete lifecycle emitsvariant-specific flows

Enum membership does not prove that every variant emits every name.

Event action names

Action nameEffectRequired input
setVariablesmerges configured variable values into the event-variable storevariables
unselectObjectsInOtherPanelsclears selection outside the sourcesource panelId
unselectObjectsclears selection in a panelsource or configured panel context
preventUnselectFromOtherPanelsprotects the source selection during coordinated selectionsource panelId
addSelectedObjectToRequeststores the current object selector under event idselected object
openPanelInDraweropens a referenced or inline paneldrawer
selectObjectselects the supplied objectsitem-action method accepted by the event switch

sendToApplicationWithParams is declared but has no current event switch branch. Generic event-action params and request are also declared without a shared consumer.

Publish a selected object

json
{
  "events": [
    {
      "id": "orders-selected",
      "name": "onObjectSelect",
      "actions": [
        { "name": "preventUnselectFromOtherPanels" },
        { "name": "unselectObjectsInOtherPanels" },
        { "name": "addSelectedObjectToRequest" }
      ]
    }
  ]
}

Dependent requests and endpoints use the same orders-selected ID. When the selection is reverted, the stored event entry is removed.

Variables and conditions

Variable conditions compare the current event-variable store entry with the condition's expected value:

ComparisonCheck
EQUALstrict equality
NOT_EQUALstrict inequality
CONTAINboth values are strings and the runtime value contains the expected value
START_WITHboth values are strings and the runtime value starts with the expected value
EMPTYthe runtime value is falsy
NOT_EMPTYthe runtime value is truthy

All variables in one condition must pass.

json
{
  "condition": {
    "scenario": "variables",
    "variables": {
      "detailsVisible": {
        "value": true,
        "compare": "EQUAL",
        "cleanOnUnmounted": true
      }
    }
  }
}

cleanOnUnmounted is tracked by the conditioned panel. When that panel unmounts, the named variable is removed. Use it for genuinely temporary state; otherwise unmounting a child can unexpectedly hide another consumer.

The declared setVariables shape and its current setter are inconsistent: the type describes { value, compare, cleanOnUnmounted }, while the event branch stores that whole entry instead of only value. A primitive condition therefore does not form a source-verified round trip from this event action alone. Use variable conditions only with a runtime producer already verified to write compatible primitive values; use objectSelected for ordinary selection-driven visibility.

For selection-driven visibility:

json
{
  "condition": {
    "scenario": "objectSelected",
    "eventId": "orders-selected",
    "objectTypeNames": ["WorkOrder"]
  }
}

The shared filter accepts it only when the event is present and includes addSelectedObjectToRequest. The optional objectTypeNames list additionally requires an exact, case-sensitive match with the selected object's already loaded metaType.typeName; it does not inspect link metadata or make another API request.

Drawers

openPanelInDrawer accepts either a registered panelId or a complete inline panel, plus presentation hints:

json
{
  "name": "openPanelInDrawer",
  "drawer": {
    "position": "right",
    "header": { "en": "Order details", "ru": "Детали заказа" },
    "width": "42rem",
    "panel": {
      "id": "drawer-order-details",
      "type": "attributes",
      "request": {
        "getSelectedObjectForEventId": "orders-selected"
      },
      "editor": {
        "fields": [{ "attribute": "name", "readonly": true }]
      }
    }
  }
}

Positions are left, right, top, bottom, or full. A referenced panelId must resolve in the current application. An inline panel must be a complete valid panel and uses the same in-memory event state.

Minimal valid event

json
{
  "id": "order-selected",
  "name": "onObjectSelect",
  "actions": [{ "name": "addSelectedObjectToRequest" }]
}

It is useful only on a selectable source panel.

Complete selection and visibility example

json
{
  "id": "orders",
  "type": "table",
  "request": { "metaTypeName": "ProductionOrder" },
  "events": [
    {
      "id": "order-selected",
      "name": "onObjectSelect",
      "actions": [{ "name": "addSelectedObjectToRequest" }]
    }
  ],
  "columns": [{ "attribute": "name", "label": "Order" }]
}

A sibling can now use objectSelected with this eventId and a request/endpoint referencing the same event.

The shared-config fixture uses exactly one event ID for two supported selection-driven sources:

  1. its source Tabs expose an orders Table and a linked-object Tree;
  2. either source emits onObjectSelect with addSelectedObjectToRequest under local-shared-config-order-selected;
  3. the runtime stores the selected object's selector and actual metatype in the same event context;
  4. the Condition panel initially chooses its default Message child;
  5. a Table row activates the LocalOrder Attributes branch, while a linked Tree child activates the LocalAttributeRendererMatrixCase branch;
  6. each Attributes request resolves the same event-owned selector that supplied the metatype used by its condition.

It does not use variable actions, coordinated unselection, drawers, or mutation events, so the demo is evidence only for this object-selection chain.

Open the Condition tab and switch between Table and Tree metatype branches Open a checked-in selection event and dependent filtered table Open one selection consumed by linked, attributes, and read-only detail panels

Ordering and lifecycle interactions

  1. The source emits a supported occurrence.
  2. Every matching configured event runs, in declaration order.
  3. Each event action runs in its array order.
  4. addSelectedObjectToRequest stores the selector under the event ID.
  5. dependent conditions re-evaluate and panels may mount;
  6. dependent request/editor consumers resolve the stored selector.
  7. Revert/unselection removes stored selection and reverts event effects.

If a dependent panel mounts before the selector exists, its selected-object request has no input. Keep the condition and request on the same event ID.

Limits and current drift

  • sendToApplicationWithParams, generic params, generic request, and the shared condition value field are declared without a verified runtime branch.
  • setVariables stores its configured entry object while conditions compare the stored entry directly with condition.variables.*.value. The declared event-to-condition round trip is currently drift, not a recommended journey.
  • onUnmounted is commented out of the event enum. Variable cleanup is driven by condition tracking, not by configuring that event name.
  • default condition semantics are consumer-specific; the shared child filter does not explicitly accept it.
  • Conditions used by Group/Tabs filter children. A Condition variant applies its own child-selection logic and can choose the last matching child.
  • Event state is not persisted across a fresh application load.

Exact property reference

Event identity and actions:

Variables and conditions:

Drawer configuration:

Declared fields without current behavior:

Related Condition fields:

Next tasks