Skip to main content

Tables


Tables

The table component is a highly configurable, feature rich and navigable data grid. It allows for presentation of data in many different ways, and it is often possible fulfil business requests, just by configuration. The table implements the common framework concept and uses Cytoscape.js#data eles data select keys to configure data into cells. Read Understanding the graph model to learn more about the high level concept.

{
"tables" : {
"example" : {
"datasets": ["rootNodesInitalLoadData"],
"columns": [
"title",
"owner",
"state",
"DEFAULT_SEPARATOR",
"related_docs"
],
"services": ["initialLoadService"],
"expand": {
"services": ["expandService"],
"datasets": ["expandData"]
}
}
}
}

Table properties​

Prop NameDescriptionData TypeRequiredExample
columnsList of column names to display in the table. "DEFAULT_SEPARATOR" is a built in column that adds a small space in between columns.array stringyes["title", "name","DEFAULT_SEPARATOR" "state"]
contextMenuReference to a context menu definition.stringno"issueContextMenu"
datasetsReferences to datasets providing data for the table.array stringyes["issueData"]
deferredServicesServices loaded lazily after initial render.array stringno["lazyLoadDetails"]
dropHandlerReference to a drop handler for drag-and-drop functionality.stringno"dropHandler": "cr_table_drop_zone",
expandConfiguration for expandable rows or data.objectnoTable expand
nameName of the table (not used explicitly here).stringyes"IssueTable"
servicesReferences to services fetching data for the table.array stringno"services": ["fetchAllIssues"]
settingsTable-specific settings (e.g., drag behavior, column mapping).objectno{"multiDraggable": true}
toolbarsReference to a toolbar definition for interactivity. Panel commands may use useSelectedRow to bind the opened form to the selected table row. See Commands — Panel commands.stringno"toolbars": "toolbar_issue_details"

Context menu​

Right-clicking a table row shows a context menu. Define menus in the top-level contextMenus map and reference one by name from the table's contextMenu property. Each menu is an array of command-name references — commands themselves are defined in the top-level commands map (same pattern used by toolbars).

{
"tables": {
"productStructure": {
"datasets": ["contextNode"],
"columns": ["title", "owner", "state"],
"contextMenu": "openWithMenu"
}
},
"contextMenus": {
"openWithMenu": ["openWith", "promote", "demote"]
},
"commands": {
"openWith": {
"type": "openWith",
"isMenu": true,
"label": "Open With",
"openApps": {
"ENOLCMI_AP": { "label": "Item Lifecycle" },
"VPLMProjectManagement_AP": { "label": "Project Management" },
"ENO3DMultiCAD_AP": { "label": "3D Multi CAD" }
}
},
"promote": {
"label": "Promote",
"type": "genericService",
"settings": {
"relatedConfig": {
"services": ["promoteItemService"],
"responseMapping": { "expression": "results[0].maturityState", "attribute": "state" }
}
}
},
"demote": {
"label": "Demote",
"type": "genericService",
"settings": {
"relatedConfig": {
"services": ["demoteItemService"],
"responseMapping": { "expression": "results[0].maturityState", "attribute": "state" }
}
}
}
}
}

contextMenus map​

FieldDescriptionTypeRequired
<menuName>An ordered list of command-name references. Items are rendered in declaration order.array of stringyes

Open With submenu​

If one of the referenced commands has type: "openWith", it is rendered as a submenu (with a ▶ arrow) instead of a plain menu item. Hovering the entry reveals a submenu containing:

  1. The apps declared in the command's openApps, in declaration order.
  2. A More apps… entry (always appended) — opens the Compass side panel so the user can pick any other compatible app.

The submenu label comes from the openWith command's label. openApps is an object where each key is the app ID and the value is { "label": "..." }. An app entry may also carry icon, ds-icon and icon-color to show a coloured glyph next to its label — see Commands — Icons. Only configured entries take these; apps discovered from the platform supply their own image, which is not recoloured.

Any context menu entry can be turned into a nested submenu by setting isMenu: true and defining the submenu in the top-level menus array. Hovering the entry reveals the submenu with a ▶ arrow.

{
"contextMenus": {
"myMenu": [
"openWith",
"stateActions"
]
},
"menus": {
"stateActions": {
"label": "State Actions",
"icon": "Workflow",
"ds-icon": "fonticon fonticon-collaborative-lifecycle-management",
"commands": ["promote", "demote"]
}
},
"commands": {
"promote": {
"label": "Promote",
"type": "genericService",
"settings": {
"relatedConfig": {
"services": ["promoteItemService"],
"responseMapping": [
{ "expression": "results[0].maturityState", "attribute": "state" }
]
}
}
},
"demote": {
"label": "Demote",
"type": "genericService",
"settings": {
"relatedConfig": {
"services": ["demoteItemService"],
"responseMapping": [
{ "expression": "results[0].maturityState", "attribute": "state" }
]
}
}
}
}
}

The context menu entry "stateActions" is resolved from the top-level menus map because that name is defined there. The label, icon and ds-icon on the menu definition control what the parent entry looks like — you do not repeat them in contextMenus. Commands inside the submenu are looked up from the same top-level commands map.

ds-icon renders the 3DEXPERIENCE icon-font glyph inside the DS widget shell, with icon as the bundled fallback everywhere else, and the optional icon-color tints whichever one is drawn; see Commands — Icons.

You can still use { "name": "stateActions", "isMenu": true } explicitly, or add inline label / icon / ds-icon / icon-color overrides on the context menu reference when needed.

FieldDescriptionTypeRequired
nameUnique identifier referenced by isMenu: true entries in contextMenus.stringyes
labelDisplay label for the submenu parent entry.stringyes
iconBundled icon for the submenu parent entry — a lucide icon name, or a path/URL to an image.stringno
ds-icon3DEXPERIENCE icon-font classes for the submenu parent entry, e.g. "fonticon fonticon-collaborative-lifecycle-management". Used in preference to icon when the shell's icon font is loaded. See Commands — Icons.stringno
icon-colorOptional CSS colour for the submenu parent entry's icon, e.g. "#6a1b9a". Applies to the ds-icon glyph and to a lucide icon; image icons are not recoloured.stringno
commandsOrdered list of { "name": "<commandName>" } references into the top-level commands map.arrayyes

contextMenus entry fields (when using isMenu)​

A context menu array item can be either a plain string (command reference) or an object:

FieldDescriptionTypeRequired
nameCommand or menu name to look up.stringyes
isMenuSet to true to render this entry as a submenu (resolved from the menus array). When omitted, a name that exists only in menus is treated as a submenu automatically. Set to false to force command lookup.booleanno
labelInline label override. When present, overrides the label from the resolved command/menu definition.stringno
iconInline icon override.stringno
ds-iconInline icon-font override, e.g. "fonticon fonticon-pin". Wins over the ds-icon on the resolved command/menu definition. See Commands — Icons.stringno
icon-colorInline icon-colour override, e.g. "#c0392b". Wins over the icon-color on the resolved command/menu definition.stringno

Command types​

Commands referenced from a context menu (or from inside a menus submenu) support the following type values:

typeDescription
openWithRenders an Open With submenu populated by the command's openApps.
genericServiceCalls a service on the selected row's object. services is an array of service names (strings). After the call completes, the row is refreshed according to settings.relatedConfig.refreshBehavior or responseMapping.
close / closeContextRemoves the right-clicked row (or all selected rows) from the widget context. Only shown for rows that are part of the widget context (i.e. xuiContext: true).

Commands without a type are treated as plain menu items — clicking invokes the configured onClick handler (if any).

Conditional visibility (condition)​

A command can declare a condition that is evaluated against the row data at render time. If the condition is not satisfied, the menu item is hidden. The syntax uses bracket-notation — the same style as service nodeCondition / edgeCondition selectors.

"commands": {
"close": {
"label": "Close",
"type": "close",
"icon": "X",
"condition": "[xuiContext]"
},
"promote": {
"label": "Promote",
"type": "genericService",
"condition": "[state = \"InWork\"]",
"settings": {
"relatedConfig": {
"services": ["promoteItemService"],
"responseMapping": { "expression": "results[0].maturityState", "attribute": "state" }
}
}
},
"reject": {
"label": "Reject",
"type": "genericService",
"condition": "[state != \"Approved\"]",
"settings": {
"relatedConfig": {
"services": ["rejectItemService"]
}
}
}
}

Supported expressions:

ExpressionEvaluates to true when…
[prop]row.prop is truthy (non-null, non-empty, non-false)
[prop = "value"]row.prop equals "value" (string comparison)
[prop != "value"]row.prop does not equal "value"

Multiple bracket expressions are AND-ed together:

"condition": "[xuiContext][state = \"InWork\"]"

This shows the item only when the row is a context object and its state is InWork.

The condition field is supported on:

  • Top-level context menu commands
  • Commands inside a menus submenu (isMenu: true)

When condition is omitted, the item is always visible (existing behaviour unchanged).

refreshBehavior values​

ValueDescription
refreshRowWithColumnServiceRe-fetches column-level services for the affected row only.
refreshRowRe-renders the row from the current graph data without a network call. Used automatically when responseMapping is defined.
expandRowExpands the affected row, rebuilding its children from the graph datasets alone — no service call. Use it when the action already put the children in the graph.
expandRowWithServiceExpands the affected row and calls the table's expand service to fetch children that are not in the graph yet.
removeRowDetaches the affected row from the table. Use it after an action that moves the object out of the current view.
syncRowsTable scoped: re-runs the table's datasets against the graph, adding rows that are new and dropping ones that are gone. Needs no selected row, so it is the one to use after a service that creates an object.

refreshParents also exists in the configuration schema but is currently a no-op — do not rely on it.

warning

refreshBehavior is ignored whenever responseMapping is set on the same command — the row is re-rendered from the mapped graph data instead (equivalent to refreshRow). If you configure expandRow (or any other value) and nothing happens, check whether the command also defines responseMapping, and remove it if you want the refresh behaviour to run.

responseMapping — update the row from the service response​

When a genericService command returns data that should be immediately reflected in the table (for example a maturity state change), use responseMapping instead of refreshRowWithColumnService. The row updates instantly from the service response — no second network round-trip is needed.

"promote": {
"label": "Promote",
"type": "genericService",
"settings": {
"relatedConfig": {
"services": ["promoteItemService"],
"responseMapping": { "expression": "results[0].maturityState", "attribute": "state" }
}
}
}

responseMapping fields:

FieldDescriptionTypeRequired
expressionJSONata expression evaluated against the raw HTTP response body.stringyes
attributeGraph node attribute to write the result to. Must match the data field of the target column definition.stringyes

Finding the right attribute name — look at the column definition; the data field is the graph attribute:

"maturity_state": {
"label": "Maturity State",
"data": "state"
}

Here "data": "state" means the graph attribute is state, so "attribute": "state" is correct.

Multiple attributes — pass an array:

"responseMapping": [
{ "expression": "results[0].maturityState", "attribute": "state" },
{ "expression": "results[0].owner", "attribute": "owner" },
{ "expression": "results[0].modifiedDate", "attribute": "modified" }
]

JSONata expressions can transform values, not just extract them:

{ "expression": "$uppercase(results[0].maturityState)", "attribute": "stateLabel" }

When responseMapping is defined, refreshBehavior is ignored — the row re-renders directly from the updated graph data.

Open with app (column-level)​

You may also set launchApp on an individual column for a single-app left-click launch (no menu). The right-click Open With menu is configured via context menus / the openWith command as shown above.

Selecting an entry invokes the platform-provided handler (the same one the OOTB Compass uses), so the chosen app opens via TransientWidget with the row's object as context.

launchApp — direct left-click launch​

launchApp (configured under column.settings) makes the column's main link open the row object directly in a pre-configured OOTB app in a single click, instead of navigating within the widget. It takes precedence over href on the same column.

For launch behavior, use the array form:

"name": {
"label": "Name",
"data": "name",
"iconSelect": "",
"settings": {
"launchApp": [
{
"renderer": "nameHyperlink",
"mappings": [
{
"app": "ENOPSTE_AP",
"condition": { "node": "[type='VPMReference']" }
},
{
"app": "ENOLCMI_AP",
"condition": { "node": "[type='Change Action']" }
},
{
"app": "ENOLCMI_AP"
}
]
},
{
"renderer": "iconhyperlink",
"mappings": [
{
"app": "ENOPSTE_AP",
"iconSettings": {
"name": "Info",
"strokeWidth": 2,
"size": 21,
"color": "#368ec4"
},
"condition": { "node": "[type='VPMReference'][state='FROZEN']" }
},
{
"app": "X3DPLAW_AP",
"iconSettings": {
"name": "box",
"strokeWidth": 2,
"size": 21,
"color": "#368ec4"
},
"condition": { "node": "[state='RELEASED']" }
},
{
"app": "ENOLCMI_AP",
"iconSettings": {
"name": "Recycle",
"strokeWidth": 2,
"size": 21,
"color": "#f39c12"
}
}
]
}
]
}
}

When no app resolves for a row's object type and the column also defines an href, the link falls back to the normal in-widget navigation.

The rendered link shows a hand (pointer) cursor on hover and a tooltip built from mappings[].label (falling back to the app id).

Out-of-the-box app image (imageSettings)​

For an iconhyperlink mapping you can render the app's out-of-the-box image instead of a lucide icon by providing imageSettings. When imageSettings resolves to a URL it takes precedence over iconSettings.

{
"app": "ENXENG_AP",
"label": "Engineering Release",
"imageSettings": {
"image": "widget/images/MyApps/ENXENG_AP_AppIcon.svg",
"baseURL": "${app.urls.myapps}",
"alt": "Engineering Release",
"size": 21
}
}
  • image accepts both absolute URLs (https://…, //…, data:…) and relative paths.
  • A relative image is joined onto the resolved baseURL.
  • baseURL may be a literal URL or a ${propertyKey} macro. A macro is resolved against PlatformAPI.getAllApplicationConfigurations() — for example ${app.urls.myapps} resolves to that property's value (e.g. https://…/enovia). Unknown keys resolve to an empty string.
Property NameDescriptionData TypeRequiredExample
rendererRenderer name for a launchApp array entry (for example nameHyperlink or iconhyperlink).stringyes"nameHyperlink"
mappings[].appOOTB app id launched when this mapping matches.stringyes"ENOPSTE_AP"
mappings[].labelTooltip text shown on hover. Falls back to the app id.stringno"Engineering Release"
mappings[].conditionOptional object with node/edge selector condition. If omitted, mapping is always eligible.objectno{"node":"[type='VPMReference']"}
mappings[].iconSettingsLucide icon config for iconhyperlink mappings. Required unless imageSettings is provided.objectconditional{ "name": "Info", "size": 21 }
mappings[].imageSettingsOOTB image config for iconhyperlink mappings. Takes precedence over iconSettings.objectconditional{ "image": "…", "baseURL": "${app.urls.myapps}" }
mappings[].imageSettings.imageAbsolute URL or path relative to baseURL.stringyes (within imageSettings)"widget/images/MyApps/ENXENG_AP_AppIcon.svg"
mappings[].imageSettings.baseURLLiteral base URL or ${propertyKey} macro resolved via PlatformAPI.getAllApplicationConfigurations(). Used only for relative image values.stringno"${app.urls.myapps}"
mappings[].imageSettings.altAlt text for the image (also used as tooltip fallback).stringno"Engineering Release"
mappings[].imageSettings.sizeImage width/height in pixels.numberno21
mappings[].typeOptional metadata only. Not used by launch selection logic.stringno"VPMReference"

Settings properties​

Prop NameDescriptionData TypeRequiredExample
colorMappedColumnReference to a column name that will have color mapping applied.stringno"priority"
multiDraggableAllows selecting multiple rows for drag-and-drop. The related column data is dragged together.booleannotrue
onTableRowDropEnableEnables a drop zone on top of the table for supporting drag-and-drop connections.booleannotrue
hideAncestorValuesOnFilterIn a tree table, a parent row stays visible while a column filter is active when one of its children matches, even if the parent itself does not. By default the table empties, on that parent, the filtered column and the multi-value columns lined up with it (for example the whole Derived Outputs group under a Format = DWG filter), so it no longer lists values the filter excluded. This matches what the filtered download commands include. Only columns that list related objects are emptied: columns about the row itself, such as Title, Name or Type, always render, even when the filter is on one of them. A filtered column the parent itself passed also still renders. Set to false to keep showing all of the parent's values. Defaults to true.booleannofalse
avoidColumnServiceRecallReuses data already present in the data store (graph) instead of re-calling column level and expand services when a row is collapsed and expanded again. Explicit refresh actions and row edits still refetch. Defaults to false.booleannotrue
paginationEnableif set false then pagination disabled for table.booleanno"paginationEnable": false
paginationConfigControl selectable pagination sizes and the default usedobjectno"paginationConfig":{ "pagination": true, "itemsPerPage":[25,50,100], "defaultItemsPerPage": 25 }

Expand properties​

Expand setting defines how rows or nodes are expanded in a structure table. For expanding node in some cases a service call is needed to fetch the data. Dataset is used to navigate to or from the node / row to get child nodes.

Prop NameDescriptionData TypeRequiredExample
datasetsDefines which datasets to call to navigate from row or node to get child nodes.array stringyes"expand": { "services": [ "physicalProductService" ], "datasets": [ "ups1Level" ] },
servicesIn case data is not yet present in data store (graph) services are used to load data on expandRow that is getting expanded as used as contextId while calling servicearray stringno"expand": { "services": [ "physicalProductService" ], "datasets": [ "ups1Level" ] },
expandRootNodesOnLoadSet to true for making default expand enable for level 1booleanno"expand": { "services": [ "physicalProductService" ], "datasets": [ "ups1Level" ], "expandRootNodesOnLoad": true }

Advanced table implementations​

The table component allows advanced implementations such as custom rendering or data calculations using the plugin architecture. Learn more about plugins in Plugin code extensions.