Appearance
Tree panel
Purpose and problems it solves
tree loads one root object and follows configured links to build a hierarchy. Use it to navigate equipment, orders and operations, organizational structures, or any object graph where each parent type determines which descendant links are available.
When to use it
Use Tree when parent-child context and progressive expansion matter. Use Table for a flat result set, or a Table plus linked request when only one parent-to-list step is needed.
Decide first how the root is obtained, then define one link rule for every parent type that can have children.
Prerequisites, inputs, and ownership
Tree calls the object-by-GUID endpoint for its root and linked-objects endpoint for descendants. The configured link names, parent meta-type names, requested attributes, filters, sorting, and pagination must exist in the current API/data model.
Every rendered row needs a stable object GUID. tree.columns defines visible display columns; the root and every link rule provide the value/template mapping for those column keys.
Capability map
Root sources
- Fixed root:
root.objectIdis a GUID string. - Event-selected root:
root.objectIdis{ "getSelectedObjectForEventId": "..." }. - User-selected root:
root.selectPanelsdeclares picker content. In the active UI it is reached through apanelActionsaction withmethod: "selectRoot"; the standalone picker buttons inPanelTreeare commented out.
The current picker reads only the first selectPanels entry. root.ui.selectRootLabel replaces the button label for that picker. When it is omitted, runtime combines the localized “Select tree root” text with the first select panel's localized label, for example Select tree root (Orders).
Descendant acquisition
tree.links is a set of branch rules. For an expanded node, runtime reads the node's actual meta type, selects every rule whose parentType matches it, and performs each rule's linked-object request with the node GUID supplied at runtime.
Each descendant request supports linkName, reverse, findAttributes, sortParams, and pagination. Results from all matching rules are appended in rule order.
Display and templates
tree.columns[].key addresses the corresponding entry in root.columns or links[].columns. A direct identity template such as "" for key status uses the typed attribute renderer. Composite or aliased templates such as " — " are evaluated to plain display text.
The first visible column owns the expansion control. It also receives the object icon when one is available.
Selection, events, and actions
selectionMode supports single and multiple, defaulting to single. Selection stores object selectors and runs the selected node's events, plus common panel events. Root events come from root.events; descendant events come from the matching link rule.
panelActions uses the common panel toolbar. Root and descendant itemActions use the Tree-specific row handler. That handler currently implements create, deleteLink for link nodes, runMethod, and reloadEntities. Its update branch is empty. Other methods do not gain generic row behavior automatically.
Expansion and collapse
root.expandOnLoad marks the root expanded and immediately loads its descendants. Otherwise, children load on the first expansion. Collapsing a node removes its loaded children; expanding it again fetches them again. Expansion keys that no longer address loaded non-leaf nodes are cleaned up.
Width and header behavior
Tree fills the panel width. fixedWidth fixes and truncates a display column; minWidth sets a lower bound and enables horizontal overflow; legacy width is a browser table-layout hint. minWidth wins over fixedWidth and logs a configuration error when both are present. tree.ui.hideHeader hides the header row.
Behavioral model and important interactions
- Resolve the root from a direct GUID or selection event.
- Fetch only attributes referenced by the root column mappings.
- Render one root node.
- On expansion, match link rules to the node's runtime meta type.
- Fetch linked objects with the node GUID and each rule's query state.
- Mark a child as a leaf only when no rule matches that child's type.
- Route selection events and actions through the rule that created each node.
Column mappings therefore affect both display and response projection. A template that references an attribute must be present in that root/link mapping. Descendant filters, sort, and page limits are applied independently per matching link rule.
For multiple selection, the store emits event context from the last processed selected node. Do not assume one event per selected node.
Alternatives, defaults, ordering, and precedence
- An object ID explicitly supplied by the user-selection action wins for that root load. Otherwise the configured fixed/event root is resolved.
reversedefaults tofalseat request serialization.- Link rules are evaluated in configured order; all rules matching
parentTyperun. selectionModedefaults tosingle.itemActionsMaxVisibledefaults to2; remaining actions move to overflow.columnsis optional in the type, but without display columns the hierarchy has no useful visible value.- For widths:
minWidth>fixedWidth> legacywidth> flexible layout.
Limitations and declaration/runtime drift
root.selectPanelsdoes not render picker buttons by itself. Use aselectRootpanel action, and expect only the first picker entry to be used.links[].linkTypeis required by the declared type but has no confirmed active Tree consumer; descendant fetching usesrequest.linkName.ColumnValue.colspanis declared but not consumed by the renderer.tree.columns[].headeris declared but the renderer useslabel.- Tree display columns are not sortable and there is no Tree filter UI. Descendant request filters/sorts are configured on each link.
- Collapse discards children rather than preserving a client-side subtree.
- Root-load failures are logged; descendant-load failures also show a request error toast. There is no configured Tree empty/error message.
- A descendant action configured as
updatecurrently does nothing.
Minimal valid configuration
Replace the GUID and type/link names with real data-model values.
json
{
"id": "asset-tree",
"type": "tree",
"tree": {
"root": {
"objectId": "00000000-0000-0000-0000-000000000001",
"columns": {
"name": "{{name}}"
}
},
"links": [],
"columns": [
{
"key": "name",
"label": "Наименование"
}
]
}
}Realistic end-to-end scenarios
Fixed root with typed display, filtering, sorting, and eager expansion
This hierarchy loads one ProductionOrder, then its OrderOperation links. The link request returns at most 50 non-archived operations in ascending sequence order. Selection publishes the chosen root or operation under one stable event ID.
json
{
"id": "order-operations-tree",
"type": "tree",
"selectionMode": "single",
"tree": {
"root": {
"objectId": "11111111-1111-1111-1111-111111111111",
"expandOnLoad": true,
"events": [
{
"id": "order-tree-node-selected",
"name": "onObjectSelect",
"actions": [
{
"name": "addSelectedObjectToRequest"
}
]
}
],
"columns": {
"name": "{{itemId}} — {{name}}",
"status": "{{status}}"
}
},
"links": [
{
"id": "order-to-operations",
"parentType": "ProductionOrder",
"linkType": "OrderOperation",
"request": {
"linkName": "OrderOperation",
"reverse": false,
"findAttributes": [
{
"attribute": {
"name": "archived",
"value": "false"
},
"compare": "EQUAL"
}
],
"sortParams": [
{
"attribute": "sequence",
"sortDirection": "ASC"
}
],
"pagination": {
"limit": 50,
"offset": 0
}
},
"events": [
{
"id": "order-tree-node-selected",
"name": "onObjectSelect",
"actions": [
{
"name": "addSelectedObjectToRequest"
}
]
}
],
"columns": {
"name": "{{sequence}}. {{name}}",
"status": "{{status}}"
}
}
],
"columns": [
{
"key": "name",
"label": "Узел",
"minWidth": "22rem"
},
{
"key": "status",
"label": "Статус",
"fixedWidth": "10rem"
}
]
}
}Root from another panel's selection
Use this shape inside a Group after a Table emits work-center-selected. Until that event exists, Tree cannot resolve a root and renders no hierarchy.
json
{
"id": "selected-work-center-tree",
"type": "tree",
"tree": {
"root": {
"objectId": {
"getSelectedObjectForEventId": "work-center-selected"
},
"columns": {
"name": "{{name}}"
}
},
"links": [
{
"id": "work-center-to-machines",
"parentType": "WorkCenter",
"linkType": "WorkCenterMachine",
"request": {
"linkName": "WorkCenterMachine",
"reverse": false
},
"columns": {
"name": "{{itemId}} — {{name}}"
}
}
],
"columns": [
{
"key": "name",
"label": "Рабочий центр / оборудование"
}
]
}
}For a user-driven root picker, configure root.selectPanels[0] with a Table selection panel and add a selectRoot action to panelActions. Treat that path as a current compatibility surface: the inline picker entry is disabled and additional picker entries are ignored.
json
{
"tree": {
"root": {
"ui": {
"selectRootLabel": "Choose an order"
},
"columns": {
"name": "{{name}}"
},
"selectPanels": [
{
"label": "Orders",
"panel": {
"id": "order-picker",
"type": "table",
"columns": [
{
"attribute": "name",
"label": "Order"
}
],
"request": {
"metaTypeName": "ProductionOrder"
}
}
}
]
},
"links": []
},
"panelActions": [
{
"id": "choose-root",
"method": "selectRoot",
"label": "Choose root"
}
]
}Verified demos
Open fixed-root trees with descendant loading, templates, widths, and row actions Open a fixed-root typed-value tree with selection eventsNo verified local fixture currently demonstrates the event-selected or user-selected root paths.
Exact parameter reference
Root and hierarchy:
tree.tree.root.objectIdtree.tree.root.selectPanels[]tree.tree.root.ui.selectRootLabeltree.tree.root.events[]tree.tree.root.itemActions[]tree.tree.root.itemActionsMaxVisibletree.tree.root.columnstree.tree.root.expandOnLoadtree.tree.links[].idtree.tree.links[].parentTypetree.tree.links[].linkTypetree.tree.links[].columnstree.tree.links[].requesttree.tree.links[].events[]tree.tree.links[].itemActions[]tree.tree.links[].itemActionsMaxVisible
Display and panel behavior:
columns.*.valuecolumns.*.colspantree.tree.columns[].keytree.tree.columns[].labeltree.tree.columns[].headertree.tree.columns[].widthtree.tree.columns[].fixedWidthtree.tree.columns[].minWidthtree.tree.ui.hideHeadertree.selectionModetree.panelActions[]
Descendant request fields:
request.linkNamerequest.reverserequest.findAttributes[]request.sortParams[]findAttributes[].attribute.namefindAttributes[].attribute.valuefindAttributes[].comparesortParams[].attributesortParams[].sortDirection
Related guides and next task
Define selection consumers with panel events. Use values and renderers for typed direct attributes and the actions guide before adding panel or node actions.