Skip to main content

Columns


Columns​

Columns are defined separately on widget level to allow reuse over multiple tables.

Table columns should match the available graph data delivered by the service (e.g., title, state, owner). To get the correct data, use the exact property names from the node's data. Data preview is a good tool to find available node data. Columns can use datasets to display data from related nodes.

"columnExample" : {
"label": "Title",
"data": "title"
}
More examples
"columnsExamples": {
"title" : {
"label": "Title",
"data": "title",
"sticky": true,
"width": 150
},
"related_tasks" : {
"label": "Tasks",
"iconSelect": "typeicon || type_icon_url || icon",
"data": {
"datasets": [
"relatedTasks"
],
"select": "title"
},
"services": [
"relatedTasks"
],
"settings": {
"usesAlternateOid": true,
"dragAllAtOnce": true
},
"groupHeader": "Related"
},
"percentComplete" : {
"data": "percentComplete",
"label": "%",
"settings": {
"cellRenderer": "AUTO_COLOR_RENDERER",
"cellRendererProps": {
"customColorMappings": [
{
"range": {
"upperLimit": 10,
"inclusive": false
},
"color": "red"
},
]
}
}
},
"weight_rollup" : {
"label": "Weight Rollup",
"loadingLabel": "Calculating Rollup...",
"width": 110,
"settings": {
"dependantOnService": "physicalProductServiceRollup",
"datahandler": "rollup",
"cellRenderer": "rollup",
"edgeStatement": "[type='VPMInstance']",
"nodeStatement": "[type='VPMReference']"
},
"data": "ds6wg:XP_VPMReference_Ext.Weight"
}
}

Column properties​

Below is the list of properties supported by column. Each property is annotated with its data type, optionality, description, and an example where applicable.

tip

The column type jsonata is flexible and secure low-code format for generating complex cell content, the format allows configuration without deploying custom code (e.g. rollup values).

See: JSONata column type

tip

The cellRenderer HANDLEBARS_TEMPLATE_RENDERER is a flexible and secure (full sanitation applies to the template output) low-code format for rendering cell values, the format allows configuration without deploying custom code (e.g. progress bar)

See: Handlebar templates and CellRendererProps.template

Property NameDescriptionData TypeRequiredExample
dataData select configuration. Supports simple key, array of keys/selectors, object selector, or JSONata expression when type is jsonata. By default every key's value is collected; set settings.selectFirstValidData true to instead use only the first non-empty key (fallback order), useful for multi-key lists like ["state", "stateNLS"].string / array string / objectno"title"
["state", "stateNLS"]
{"select": "title", "datasets": ["issueData"]}
"$count(context)"
datahandlerAdvanced/custom data processing configuration. Built-in handler currently supported by schema is rollup.objectno{"name": "rollup"}
dataTypeData type used to decide the column's filter operator set. Distinct from type (the cell renderer type). Recognized values: text/string/boolean → text operators; number/integer/float → number operators; date/datetime → date operators. Defaults to text. See Column filtering.stringno"string"
colorFormatterApplies badge-style coloring to rendered cell values (not the full table cell). Supports a value-to-color map object with optional default fallback.objectno{"default": "#f2f2f2", "Released": "#86efac", "Frozen": "#fecaca"}
editIn-cell edit configuration. Supports services, optional editSelect, and postUpdateNodeSelect for additional node field updates. See In-cell editing.objectno{"services": ["editProduct"], "editSelect": "partNumber"}
editableSet true for in-cell editing. Cells fed by a dataset are edited one value at a time. See In-cell editing.booleannotrue
filterEnables/disables column-level filtering (default true).booleannofalse
filterModeWhich filter surface the column's Filter Column popup offers: "condition" (default) the operator/condition builder, "value" a checkbox list of the column's distinct values, or "both". See Column filtering.stringno"both"
groupHeaderWill be displayed above all columns with the same group header.stringno"Scope Engineering Item"
hrefA component name reference to navigate into as the user clicks the link.stringno"CRs_Details_Navigate"
hyperlinkURL template where {{value}} is replaced by the resolved cell value.stringno"https://example.com/issue/{{value}}"
iconSelectA data key for the icon URL e.g., 'typeIcon'. Accepts a ||-separated fallback list — the first key with a value wins.stringno"typeicon || type_icon_url || icon"
imageSettingsA fixed image rendered before the cell text on every row of the column. Takes precedence over iconSelect. Same shape as the launch-app block - see imageSettings.objectno{"image": "/images/icons/part.svg", "alt": "Part", "size": 22}
labelWill be presented in the table header to the user.stringno"Title"
loadingLabelWhat to display in the cell while loading service and processing datahandler.stringno"Loading..."
rangesAllowed values for select-like editing scenarios.array stringno["Yes", "No"]
servicesService key references to execute before rendering cell values. Use service keys only (no extension-qualified *.json.* form).array stringno["scopeEngItem"]
settingsRendering/formatting behavior container (for example cellRenderer, cellRendererProps, dateFormatOptions, style options).objectno{"cellRenderer": "AUTO_COLOR_RENDERER"}
sortTypeCustom sort behavior key for the column.stringno"alphanumeric"
stickySticks the column to the left.booleannotrue (for title)
tooltipHover text for the column header. When omitted, the header keeps showing its own label. Cells are unaffected — cell hover text comes from the cell value, and per-icon hover text from valueIconMappings[].tooltip / iconSettings.tooltip.stringno"Open Test Panel"
typeBuilt-in column types (typically shorthand for renderer and other settings). Enum: text, select, person, date, textarea, dropbox, dynamic, jsonata.stringno"person"
valueFormatterCustom value formatter object. Can be used for value presentation such as relative date/time formatting.objectno{"name": "currency", "valueFormatterProps": {"currency": "USD"}}
visibleControls if the column is visible.booleannotrue
widthForces a fixed column width in pixels.integerno150

Data​

Below sub elements define how column.data should be configured

Property NameDescriptionData TypeRequiredExample
datasetsDataset definition name references.array stringno["issueData"]
isEdgeControls if to select data from nodes or edges in dataset.booleannotrue
nodeConditionCytoscape selector that scopes where this select is valid. Do not combine with datasets in the same selector object.stringno"[type='Issue']"
selectA data key e.g., 'title' for advanced selection within data object.stringno"title"

DataHandler​

Below sub elements define how column.datahandler should be configured

Property NameDescriptionData TypeRequiredExample
datahandlerPropsAdditional options for custom datahandler.objectno{ "edgeStatement": "[type='cost']" }
nameHandler name which is same as register in custom resource plugin rollup.stringyes"rollup"

DatahandlerProps​

Below sub elements define how column column.datahandler.datahandlerProps should be configured

Property NameDescriptionData TypeRequiredExample
edgeStatementUsed with the 'rollup' cellRenderer/dataHandler to define how to expand the graph for rollup calculation. A data filtering selector (where clause). See Cytoscape Selectors. Macros: {{contextId}}.stringno"[type='relatesTo']"
nodeStatementUsed with the 'rollup' cellRenderer/dataHandler to define how to expand the graph for rollup calculation. A data filtering selector (where clause). See Cytoscape Selectors. Macros: {{contextId}}.stringno"[type='Issue']"

Settings​

Below sub elements define how column.settings should be configured

Property NameDescriptionData TypeRequiredExample
cellRendererCell renderer key. Built-ins include AUTO_COLOR_RENDERER, PERSON_RENDERER, ICON_RENDERER, rollup, HANDLEBARS_TEMPLATE_RENDERER, FILE_MENU_RENDERER, and MATURITY_LIFECYCLE_RENDERER (custom keys also allowed).stringno"HANDLEBARS_TEMPLATE_RENDERER"
cellRendererPropsRenderer options (for example customColorMappings, customIconMappings, template, strictVariables).objectno{"template": "<div>{{value}}</div>"}
dateFormatOptionsAdditional date formatting options.objectno{ "locale": "en-US", "options": { "year": "numeric", "month": "long", "day": "numeric" } }
dependantOnServiceService key that this column depends on for data/behavior updates.stringno"fetchAllIssues"
dragAllAtOnceDrag all related column data together in one go, if multiple rows are selected includes related column data too.booleannotrue
headerRendererCustom renderer key for the column header.stringno"HANDLEBARS_TEMPLATE_RENDERER"
headerRendererPropsProps to pass into the header renderer (for example template, strictVariables).objectno{"template": "<span>{{header}}</span>"}
includeBlankValueWhen true, keeps empty values in dataset/multi-value results so each related object still renders a placeholder line and values stay aligned across columns.booleannotrue
selectFirstValidDataWhen true, iterate the column's data keys in order and use only the first non-empty value (fallback order — "if the first has a value, stop and return it; otherwise try the next"). When false/absent (default), every key's value is collected as before. Useful for multi-key lists like ["state", "stateNLS"].booleannotrue
renderAsMultiValueTODO (purpose unclear in schema; possibly for multi-value rendering).booleannotrue
showFullNameUsed with the built-in person renderer to control if to display the full name (true is default, false display full name in tooltip only).booleannofalse
styleCellCSS styles for the data cell.objectno{"whiteSpace": "nowrap"}
styleCellValueApplies styling by using any CSS. Style is applied on cell value.objectno{"fontWeight": "bold"}
styleHeaderCSS styles for the header cell.objectno{"fontWeight": "600"}
usesAlternateOidIf true, makes the data represented by the dataset draggable (single or multi value depending on dragAllAtOnce).booleannotrue

CellRenderer​

Built in column.settings.cellRenderer

Cell RendererDescriptionExample
AUTO_COLOR_RENDERERThis cell renderer generates the colored back ground for the cell value, based on the actual text value. It is useful for column which have fixed ranges like states, priority. It gives a more visually appealing cell with back ground and text color in contrast. It also supports addition properties via cellRendererPropsSame text will generate same back ground color"settings": { "cellRenderer": "AUTO_COLOR_RENDERER", "cellRendererProps": { "customColorMappings": [ { "range": { "upperLimit": 10, "inclusive": false }, "color": "red" }, ] } }
HANDLEBARS_TEMPLATE_RENDERERRenders custom HTML-like output from a Handlebars template. For cell rendering, configure settings.cellRendererProps.template; for header rendering, configure settings.headerRendererProps.template. If omitted, default templates are {{value}} (cell) and {{header}} (header)."settings": { "cellRenderer": "HANDLEBARS_TEMPLATE_RENDERER", "cellRendererProps": { "template": "<span>{{displayValue}}</span>", "strictVariables": true } }
ICON_RENDERERThis cell renderer is used to show icons instead of plan text value. For example in case of priority or severity, icons can be shown instead of text value. These icons will be based on mapping between value and corresponding icon. Additional cellRendererProps is used to define the mapping."severity" : { "label": "Severity", "data": "severity", "settings": { "cellRenderer": "ICON_RENDERER", "cellRendererProps": { "customIconMappings": [ { "value": "Low", "icon": "level-low-icon", "color": "green" }, { "value": "High", "icon": "level-high-icon", "color": "red" }, { "value": "Medium", "icon": "levelmedium-icon", "color": "orange" } ] } } },
PERSON_RENDERERThis cell renderer generates the colored back ground for the person name together along with rounded initials box for quick identification.Same person name will generate same back ground color and initials box"owner" : { "label": "Owner", "type": "person", "data": "owner.user", "settings": { "cellRenderer": "PERSON_RENDERER", "cellRendererProps": { "showFullName": true } } }
FILE_MENU_RENDERERRenders a per-file action toolbar for each file node associated with a row. Displays upload, download, view, edit, lock/unlock, update, and delete icon buttons. The view button opens a PDF or image viewer directly in the browser. The visible button set changes based on the file's locked state. File nodes are sourced from the column's valuesWithSelect data (populated via datasets). Built-in services are auto-injected and can be overridden per consumer config. See File Menu Renderer."files": { "label": "Files", "data": { "datasets": ["documentsData"], "select": "title" }, "settings": { "cellRenderer": "FILE_MENU_RENDERER", "cellRendererProps": { "icons": { "add": "wux-ui-3ds-upload", "upload": "wux-ui-3ds-upload", "download": "wux-ui-3ds-download", "edit": "wux-ui-3ds-edit", "lock": "wux-ui-3ds-lock", "unlock": "wux-ui-3ds-unlock", "update": "wux-ui-3ds-update", "editUnlock": "wux-ui-3ds-lock-open", "updateUnlock": "wux-ui-3ds-update-unlock", "delete": "wux-ui-3ds-delete", "view": "wux-ui-3ds-eye" } } } }
MATURITY_LIFECYCLE_RENDERERRenders the maturity state as a colored chip (same coloring options as AUTO_COLOR_RENDERER). Clicking the chip opens an in-place lifecycle dialog showing the state graph, with clickable promote/demote transitions for the current state. Services are config-driven (see Maturity Lifecycle Renderer)."maturity_state": { "label": "Maturity State", "data": "state", "settings": { "cellRenderer": "MATURITY_LIFECYCLE_RENDERER", "cellRendererProps": { "fixedColorMappings": { "In Work": { "color": "#007DA3", "textColor": "white" } } } } }

CellRendererProps​

Below sub elements define how column column.settings.cellRendererPropsshould be configured

Property NameDescriptionData TypeRequiredExample
colorizeUsed by ICON_RENDERER to colorize icon output based on cell value.booleannotrue
changeStateServiceUsed by MATURITY_LIFECYCLE_RENDERER. Name of the service that changes maturity state (promote/demote). Defaults to changeMaturityState.stringno"changeMaturityState"
customColorMappingsColor mapping rules used by AUTO_COLOR_RENDERER and MATURITY_LIFECYCLE_RENDERER (value-based and/or range-based).array objectno[ { "color": "#FF0000", "value": "High" }, { "color": "#00AA00", "range": { "lowerLimit": 1, "upperLimit": 10, "inclusive": true } } ]
customIconMappingsValue-to-icon mappings used by ICON_RENDERER. Schema requires at least value and icon per item.array objectno[ { "value": "Open", "icon": "wux-ui-3ds-flag", "iconFamily": "DSFontIcon", "color": "#00FF00" } ]
defaultIconFallback icon used by ICON_RENDERER when no mapping matches.stringno"wux-ui-3ds-flag"
fixedColorMappingsFixed value-to-color map used by AUTO_COLOR_RENDERER and MATURITY_LIFECYCLE_RENDERER.objectno{"High": {"color": "#FF0000", "textColor": "white"}}
iconsIcon configuration object used by FILE_MENU_RENDERER. Maps action keys to CSS icon class names. See Icons.objectno{"add": "wux-ui-3ds-plus"}
stateGraphServiceUsed by MATURITY_LIFECYCLE_RENDERER. Name of the service that returns the maturity state graph (states, transitions, current state). Defaults to getMaturityStateGraph.stringno"getMaturityStateGraph"
strictVariablesControls Handlebars strict mode. Default behavior is true; set to false to allow missing variables without failing rendering.booleannotrue
templateHandlebars template string used by HANDLEBARS_TEMPLATE_RENDERER. For cell templates, context includes value, rawValue, displayValue, and rawObject (when available). See Handlebar templates.stringno"<span>{{displayValue}}</span>"
useFormattedValueIf true, resolve color mappings using formatted value instead of raw value.booleannofalse
valueIconMappingsValue-driven mappings for ICON_RENDERER with optional default/callback/plugin metadata. See ValueIconMappings.array objectno[ { "value": "Open", "icon": "wux-ui-3ds-flag" }, { "default": true, "icon": "wux-ui-3ds-help" } ]
ValueIconMappings​

Below sub elements define how each entry of column.settings.cellRendererProps.valueIconMappings should be configured. Each entry describes one icon.

Property NameDescriptionData TypeRequiredExample
valueCell value this mapping matches. Omit when using default.string number booleanno"Open"
defaultWhen true, used as the fallback mapping if no value-specific mapping matches.booleannotrue
nameLucide icon name.stringno"Info"
iconAlias of name. Also accepts an image URL/path.stringno"Info"
ds-iconHost icon-font class. Used when that font is loaded; otherwise the renderer falls back to the lucide icon from name.stringno"fonticon fonticon-info"
sizeIcon size in pixels (default 21). Applied to both the lucide svg and the icon-font glyph.numberno21
strokeWidthLucide icon stroke width.numberno2
colorIcon color.stringno"#368ec4"
cssInline CSS applied to the icon and its wrapper. Kebab-case keys are converted to camelCase; --* custom properties are kept as-is.objectno{"cursor": "pointer"}
tooltipHover text for this icon only. Shown on the icon and its label, and it wins over the cell's own hover text.stringno"Open Info Panel"
callbackClick handler configuration routed through the table's onIconClickHandler when clickHandler is true.objectno{"clickHandler": true, "actionName": "panel"}
pluginRegistered plugin utility invoked on icon click.stringno"openDetails"
CustomColorMappings​

Below sub elements define how column column.settings.cellRendererProps.customColorMappings should be configured

Property NameDescriptionData TypeRequiredExample
colorThe color. If HEX (e.g., #FF0000) is used for background, a matching foreground color is applied.stringno"#FF0000"
rangeDefines a numeric range to apply color.objectno{ "upperLimit": 100, "lowerLimit": 50, "inclusive": true }
valueThe cell value to map a colour with.stringno"High"
CustomColorMappings.range​

Below sub elements define how column column.settings.cellRendererProps.customColorMappings.range should be configured

Property NameDescriptionData TypeRequiredExample
inclusiveControl if to include the range limit value or not (== vs >=).booleannotrue
lowerLimitThe lower limit numeric range to apply color.numberno50
upperLimitThe upper limit numeric range to apply color.numberno100
CustomIconMappings​

Below sub elements define how column column.settings.cellRendererProps.customIconMappings should be configured

Property NameDescriptionData TypeRequiredExample
colorA colour e.g., #FF0000.stringno"#00FF00"
iconEither a DSFontIcon or Entypo icon key e.g., 'wux-ui-3ds-flag'.stringno"wux-ui-3ds-flag"
iconFamilyThe icon family to use. Enum: DSFontIcon, entypo.stringno"DSFontIcon"
valueThe data value to map.stringno"Open"
Icons​

Below sub elements define how column column.settings.cellRendererProps.icons should be configured for FILE_MENU_RENDERER

Property NameDescriptionData TypeRequiredExample
addIcon class for the row-level upload button. Creates a new file on the document. Shown at the top of the cell regardless of lock state.stringno"wux-ui-3ds-upload"
deleteIcon class for the delete button. Removes the file from the document.stringno"wux-ui-3ds-delete"
downloadIcon class for the download button. Available when the file is not locked.stringno"wux-ui-3ds-download"
editIcon class for the edit button. Downloads the file for editing and automatically locks it. Available when the file is not locked.stringno"wux-ui-3ds-edit"
editUnlockIcon class for the cancel-edit button. Unlocks the file without committing changes. Available when the file is locked.stringno"wux-ui-3ds-lock-open"
lockIcon class for the lock button. Locks the file. Available when the file is not locked.stringno"wux-ui-3ds-lock"
unlockIcon class for the unlock button. Unlocks the file. Available when the file is locked.stringno"wux-ui-3ds-unlock"
updateIcon class for the update button. Opens a file picker to upload a new revision (REVISE). Available when the file is not locked.stringno"wux-ui-3ds-update"
updateUnlockIcon class for the update-and-unlock button. Uploads a new revision and unlocks the file. Available when the file is locked.stringno"wux-ui-3ds-update-unlock"
uploadIcon class for the per-file upload button. Adds a new file to the document.stringno"wux-ui-3ds-upload"
viewIcon class for the view button. Opens the file in an in-browser viewer supporting PDF, image, and text formats. Available for all file states.stringno"wux-ui-3ds-eye"

DateFormatOptions​

Below sub elements define how column.settings.dateFormatOptions should be configured

Property NameDescriptionData TypeRequiredExample
localeLocale for date formatting.stringno"en-US"
optionsOptions for date formatting (year, day, month).objectno{ "year": "numeric", "day": "numeric", "month": "long" }

HeaderRendererProps​

Below sub elements define how column.settings.headerRendererProps should be configured

Property NameDescriptionData TypeRequiredExample
strictVariablesControls Handlebars strict mode for header templates. Default behavior is true; set to false to allow missing variables without failing rendering.booleannotrue
templateHandlebars template string for settings.headerRenderer = "HANDLEBARS_TEMPLATE_RENDERER". Header template context includes header, field, and columnIndex. See Handlebar templates.stringno"<span>{{header}} ({{columnIndex}})</span>"

ValueFormatter​

Below sub elements define how column.valueFormatter should be configured

Property NameDescriptionData TypeRequiredExample
nameFormatter type.stringyes"currency"
valueFormatterPropsAdditional options for custom value formatter.objectno{"currency": "USD"}

Details​

Column filtering​

Right-clicking a column header opens the column context menu with, among other actions, Filter Column. Selecting it opens an advanced filter popup for that column. Column-level filtering can be turned off per column with filter: false.

The popup's controls are driven by two column properties:

  • dataType — decides which operator set the filter offers:

    • text (text / string / boolean, or omitted): Contains, Does not contain, Equals to, Does not equal to, Starts with, Ends with, Is empty, Is not empty.
    • number (number / integer / float): Greater Than, Less Than, Greater Than Equal To, Less Than Equal To, Equals to, Does not equal to, Is empty, Is not empty.
    • date (date / datetime): Date Equal, Before, On or Before, After, On or After, Between (date pickers), Is empty, Is not empty.

    dataType is intentionally separate from type (which selects the cell renderer, e.g. person). If dataType is omitted the filter falls back to type/columnType, then defaults to text.

  • filterMode — picks which filter surface the popup offers:

    • "condition" (default, also when omitted): only the operator/condition builder. Multiple conditions are combined with All (AND) / Any (OR).
    • "value": only a checkbox list of the column's distinct values ("Filter by Values"), with a search box and select-all. Best for columns with a small, known value set (state, type, unit).
    • "both": both of the above, as two collapsible sections. Exactly one section is expanded at a time — selecting one collapses the other — and the two filters are combined with AND.

    The Reset button in the popup is disabled while there is nothing to clear, and only clears the popup's own fields: the table is not touched until OK, so Reset followed by Cancel leaves any existing filter in place.

"maturity_state": {
"label": "Maturity State",
"data": "state",
"filterMode": "both"
},
"weight": {
"label": "Weight",
"dataType": "number",
"data": "weight"
}
note

Applied filters are session-only (not persisted). Column visibility, width, pin order, and the "Show Column Filters" toggle persist via the table's local storage.

In-cell editing​

A column becomes editable in place with editable: true and an edit block naming the service that saves the change:

{
"label": "Title",
"data": "title",
"editable": true,
"edit": {
"editSelect": "title",
"services": ["editProduct"]
}
}

Double-clicking the cell opens an editor; leaving it saves. The service is called with {{contextId}} set to the object being edited and {{FIELD_VALUE}} set to the typed value, and {{FIELD_IDENTIFIER}} set to the field name.

Which object is edited. For a column bound straight to the row, that is the row's own object. A column fed by a dataset shows one value per related element, and those cells are edited one value at a time: double-clicking a value opens an editor on that value alone, and the service receives the element that value was read from — the related object for a node select, the relationship itself when the select has isEdge: true. Without this, every value in the cell would save against the row.

Field name. {{FIELD_IDENTIFIER}} resolves in this order: edit.editSelect, then the select the edited value came from, then the column's first data.select. Naming editSelect is only necessary when the payload field differs from the displayed one.

What is editable. Hovering an editable target shows a small corner marker: on the cell for a single value, on the individual value for a cell edited value by value.

note

A cell keeps its cell-level behaviour when its values cannot be attributed to individual elements — when one select expands into several displayed values, and for multiSelect and colorFormatter columns. Such a cell shows several values but saves as a whole.

Launch app​

launchApp (configured under column.settings) turns a column's main link into a direct "open with" affordance: clicking the link opens the object straight into a pre-configured OOTB app in a single click, instead of navigating within the widget. This reduces the multi-click path of the right-click Open With menu (which remains available and is unaffected).

When launchApp is set it takes precedence over href on the same column. If no app resolves and the column also has an href, the link falls back to the normal in-widget navigation.

Multiple renderer-specific launch apps​

Configure launchApp as an array when one column needs different launch behavior per renderer (for example, the name hyperlink and an icon hyperlink).

Current contract:

  • launchApp is an array of renderer entries
  • each entry must define renderer and mappings
  • mappings[].app is required
  • mappings[].condition is optional (if omitted, mapping is always eligible)
  • mappings[].iconSettings is required for iconhyperlink mappings unless imageSettings is provided
  • mappings[].imageSettings renders the app's OOTB image and takes precedence over iconSettings
  • mappings[].label is optional and gives a nameHyperlink mapping its hover text (falls back to the app id); an iconhyperlink mapping takes its hover text from iconSettings.tooltip, then mappings[].tooltip
  • type in mapping is optional metadata and not used for matching
  • selector matching supports common maturity aliases (state/current) and case-insensitive equality for those fields
"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"
}
}
]
}
]
}
}
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[].labelHover text for a nameHyperlink mapping's link. Falls back to the app id. Not used for icon/image mappings — those read tooltip.stringno"Engineering Release"
mappings[].tooltipHover text for an iconhyperlink mapping's icon or image, used when iconSettings.tooltip is absent. Not used by nameHyperlink mappings — those read label.stringno"Relationships"
mappings[].conditionOptional object with node/edge selector condition. If omitted, mapping is always eligible.objectno{"node":"[type='VPMReference']"}
mappings[].iconSettingsIcon config. Required for iconhyperlink mappings. See iconSettings. 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[].typeOptional metadata only. Not used by launch selection logic.stringno"VPMReference"
iconSettings​

iconSettings accepts the same icon contract as valueIconMappings, so an iconHyperlink launch icon can use a host icon font, custom CSS and its own hover text.

Property NameDescriptionData TypeRequiredExample
nameLucide icon name.stringno"Info"
ds-iconHost icon-font class. Used when that font is loaded; otherwise the launch icon falls back to the lucide icon from name.stringno"fonticon fonticon-info"
sizeIcon size in pixels. Applied to both the lucide svg and the icon-font glyph.numberno21
strokeWidthLucide icon stroke width.numberno2
colorIcon color.stringno"#368ec4"
cssInline CSS applied to the icon. Kebab-case keys are converted to camelCase.objectno{"cursor": "pointer"}
tooltipHover text for this launch icon only. Falls back to a tooltip set directly on the mapping.stringno"Open Info Panel"

Out-of-the-box app image and tooltip​

The launch link shows a hand (pointer) cursor on hover. A nameHyperlink link takes its tooltip from mappings[].label (falling back to the app id); an iconhyperlink icon or image takes its tooltip from iconSettings.tooltip, then mappings[].tooltip.

For an iconhyperlink mapping you can render the app's out-of-the-box image instead of a lucide icon via imageSettings:

{
"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 absolute URLs (https://…, //…, data:…) and relative paths; a relative path 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} → that property's value). Unknown keys resolve to an empty string.
  • The same imageSettings block is also accepted directly on a column (and on a form field). There it pins one fixed image before the cell text on every row and takes precedence over iconSelect.
Property NameDescriptionData TypeRequiredExample
imageSettings.imageAbsolute URL or path relative to baseURL.stringyes (within imageSettings)"widget/images/MyApps/ENXENG_AP_AppIcon.svg"
imageSettings.baseURLLiteral base URL or ${propertyKey} macro resolved via PlatformAPI.getAllApplicationConfigurations(). Used only for relative image values.stringno"${app.urls.myapps}"
imageSettings.altAlt text for the image (also used as tooltip fallback).stringno"Engineering Release"
imageSettings.sizeImage width/height in pixels.numberno21

Handlebars templates​

The cellRenderer HANDLEBARS_TEMPLATE_RENDERER is a flexible and secure low-code format for rendering cell values, the format allows quick configuration without writing and deploying custom code. Full sanitation applies to the template output.

See https://handlebarsjs.com for more details.

tip

The AI assistant can quickly generate templates for you.

Handlebar example column​

The below % column is using a handlebar template. handlebars.png

Example configuration

"data": "percentComplete",
"label": "%",
"settings": {
"cellRenderer": "HANDLEBARS_TEMPLATE_RENDERER",
"cellRendererProps": {
"template": "<div data-style='{\"width\":\"100%\",\"backgroundColor\":\"#f1f3f5\",\"borderRadius\":\"8px\",\"height\":\"14px\",\"overflow\":\"hidden\"}'><div data-style='{\"width\":\"{{value}}%\",\"height\":\"100%\",\"backgroundColor\":\"{{#if (gte value 80)}}#28a745{{else}}{{#if (gte value 40)}}#f1c40f{{else}}#e74c3c{{/if}}{{/if}}\",\"borderRadius\":\"8px\",\"textAlign\":\"center\",\"fontSize\":\"10px\",\"lineHeight\":\"14px\",\"color\":\"#111\"}'>{{value}}%</div></div>",
"strictVariables": true
}
}

Styling​

The style attribute is sanitized for security reasons. Instead use the data-style attribute with react camelCase styling syntax. Safe style properties only will be included in the resulting html.

Example styling

{
"width": "{{value}}%",
"height": "100%",
"backgroundColor": "{{#if (gte value 80)}}#28a745{{else}}{{#if (gte value 40)}}#f1c40f{{else}}#e74c3c{{/if}}{{/if}}",
"borderRadius": "8px",
"textAlign": "center",
"fontSize": "10px",
"lineHeight": "14px",
"color": "#111"
}

Handlebars input​

Handlebars uses an input object to generate HTML. Handlebars templates look like regular text with embedded Handlebars expressions.

<p>{{value}}</p>

A handlebars expression is a {{, some contents, followed by a }}. When the template is executed, these expressions are replaced with values from an input object.

<p>Some text</p>
ExpressionDescriptionExample configExample result
{{value}}The display value that is rendered by default on plain columns<p>{{value}}</p>Physical Product
{{displayValue}}The display value that is rendered by default on plain columns<p>{{displayValue}}</p>Physical Product
{{rawValue}}The unformatted raw value as selected from the graph<p>{{rawValue}}</p>VPMReference
{{rawObject}}Used in case the cell value outputs an object. To generate complex multi value object output to base the rendering on use a dataHandler or a jsonata column.<p>{{rawObject.assignee}} ({{rawObject.allocation}}%)</p>Tom (50%)
{{<rawObjectProperty>}}Top level raw object keys are accessible directly from the input object.<p>{{assignee}} ({{allocation}}%)</p>Tom (50%)
Strict input​

When strictVariables is true missing input handlebar expressions will return an empty rendering. If you want a relaxed rendering set strictVariables to false and the template will render even with the missing input.

Handlebars helpers​

Available helpers in HANDLEBARS_TEMPLATE_RENDERER templates:

  • eq, ne, gt, gte, lt, lte
  • and, or, not
  • dateNowMS, dateNowISO
  • dateISOToMS, dateToISO
  • dateDayOfWeek, dateMonth, dateYear, dateISOWeek

Example helper usage:

{{#if (gte value 80)}}High{{else}}Normal{{/if}}

JSONata column type​

The column type jsonata is flexible and secure low-code format for generating complex cell content, the format allows configuration without deploying custom code (e.g. rollup values). The JSONata expression is evaluated per row. The column type framework pass a json payload with the full normalized graph data to the JSONata evaluation.

JSON payload format: { context: string[], nodes: object[], edges: object[] } where the context holds local node/edge IDs for the current row/cell and node/edge holds all graph-wide data.

The below Assignee Allocation column is using a jsonata to generate the rollup allocation by assignee for the full child structure. jsonata.png

tip

The JSONata syntax is hard to learn. The built in AI assistant knows the JSON payload format and have access to tools for generating and validating JSONata for you.

See https://docs.jsonata.org for details on JSONata. https://try.jsonata.org is a great tool to try your expressions on payloads.

Examples:


$count(context)


$join(context, ', ')


nodes[id in %.context][0].type


(
$root := $filter(
context,
function($cid) {
$count(
$filter(
nodes,
function($n) {
$n.id = $cid
}
)
) > 0
}
)[0];

$desc := function($ids) {
(
$childEdges := $filter(
edges,
function($e) {
$e.type = 'tasks' and $count($ids[$ = $e.source]) > 0
}
);

$childIds := $distinct($childEdges.target);

$count($childIds) = 0
? []
: $append($childIds, $desc($childIds))
)
};

$allChildIds := $distinct($desc([$root]));

$childNodes := $filter(
nodes,
function($n) {
$count($allChildIds[$ = $n.id]) > 0
}
);

$types := $map(
$childNodes,
function($n) {
$n.type
}
);

$uniqueTypes := $distinct($types);

$join(
$map(
$uniqueTypes,
function($t) {
$t & '(' & $count($filter($types, function($x) { $x = $t })) & ')'
}
),
', '
)
)

File Menu Renderer​

FILE_MENU_RENDERER renders a per-file action toolbar inside a table cell. For each file node associated with the row, it displays a row of icon buttons that invoke document management services (upload, download, view, edit, lock, unlock, update, delete). The button set adapts based on whether the file is currently locked.

Overview​

  • Row-level upload: An optional add icon at the top of the cell lets users attach a new file to the parent document without selecting a specific existing file.
  • Per-file buttons: For each file node, action icons are rendered. Which icons appear depends on the locker field: if the file is not locked the unlocked set is shown; if it is locked the locked set is shown.
  • PDF, image, and text viewer: When the view icon is configured, a view button is shown for each file regardless of lock state. Clicking it opens the file in an in-browser viewer that supports PDF, image formats (PNG, JPG, JPEG, GIF, BMP, WEBP, SVG, ICO, TIF, TIFF), and text formats (TXT, JSON, XML, CSV, LOG, MD, YML, YAML).
  • Indirect (relationship) navigation: The renderer supports files that are directly on the row object or connected via an intermediate object (e.g. product → document → files). When the column data is configured as an array with an isEdge entry, the renderer receives both node properties and edge (relationship) data. Edges with source and target fields are treated as connector nodes — target identifies the file and source overrides the parentContextId used in service calls.

Unlocked file buttons: upload, view, download, edit, lock, update, delete

Locked file buttons: upload, view, editUnlock, unlock, updateUnlock, delete

Data format (valuesWithSelect)​

The renderer reads file nodes from the valuesWithSelect array provided by the table cell. Each element represents one property of one file node:

FieldDescription
idThe file or document node ID. Items without an id are ignored.
selectItemThe property name for this item. Recognised values: title, locker, docTitle, source, target.
displayValue / valueThe value for the property. displayValue takes priority.

Items sharing the same id are grouped into a single file node object. A node with both source and target set is treated as a relationship connector and is excluded from rendering.

selectItem valueDescription
titleFile name shown in the cell label.
docTitleDocument title. If present, used in place of title for display.
lockerWho currently holds the lock, or empty string / absent when not locked.
sourceSource node id for an indirect relationship connector.
targetTarget node id for an indirect relationship connector.

Built-in services​

The following services are automatically available for any column using FILE_MENU_RENDERER. They do not need to be declared in the consumer config. Any of them can be overridden by declaring a service with the same key in the consumer configuration.

Service keyHTTP methodPurpose
checkinTicketPUTObtains an upload ticket. Chains into checkin.
checkinPOSTPerforms the file check-in using the ticket URL. Chains into uploadDocument.
uploadDocumentPUTAttaches the uploaded file to the document. Chains into unLockDocument.
downloadDocumentPUTObtains a download ticket for the file.
editDocumentPUTObtains a download ticket for edit. The renderer automatically calls lockDocument after a successful response.
lockDocumentPOSTLocks the file.
unLockDocumentPOSTUnlocks the file (also used for cancel-edit).
deleteDocumentPUTRemoves the file from the document.

Data configuration​

The column data property controls how the renderer navigates to file objects. It supports two modes:

warning

The renderer requires selected properties from both the file object and its parent document. Depending on the mode:

  • Direct mode — the row object is the parent document, so document properties come from the row's own context (the third data entry without datasets or simply from the row node).
  • Indirect mode — the parent document is an intermediate object (e.g. product → document → file). You must select properties from both the file nodes and include edge data so the renderer can resolve the parent document for service calls.

In 3DEXPERIENCE, note that both the "document" and the "file" object have type = 'Document'. The configurator must understand the data model to distinguish between them — the file is the object connected via the files edge from the parent document.

Direct mode (simple object)​

When data is a plain object, the renderer fetches file nodes directly from the row object's dataset. The dataset navigates from the row object to the file objects in one step.

"data": {
"datasets": ["relatedFiles"],
"select": "id"
}

This is the simplest form — files are expected to be directly connected to the row object. The dataset handles the graph traversal to reach the files.

Example dataset for direct mode:

"datasets": {
"relatedFiles": {
"type": "outgoers",
"statement": "[type='Document']",
"datasets": ["targetFiles"]
},
"targetFiles": {
"type": "expand",
"levels": 1,
"edgeStatement": "[type='files']"
}
}

In this example, relatedFiles first finds outgoing Document nodes, then chains into targetFiles which expands one level along files edges to reach the actual file objects.

Indirect mode (array with isEdge)​

When data is an array, each entry fetches a different aspect of the graph data. This enables navigating to files through an intermediate object (e.g. a row represents a product, the product connects to a document, and the document holds the files).

Each data entry supports:

PropertyDescriptionData TypeRequired
datasetsArray of dataset names to query for this entry.string[]no
selectProperties to select from the matched graph elements. Can be a string or array of strings.string | string[]no
isEdgeWhen true, selects edges (relationships) instead of nodes. Use this to include source and target for navigation.booleanno

The renderer uses the edge data to map each file's target ID back to its parent source ID, overriding the parentContextId in service calls. This ensures file operations (upload, download, lock, etc.) are executed against the correct parent object.

Example — files connected via a targetFiles dataset:

"data": [
{
"datasets": ["targetFiles"],
"select": ["id", "title", "locker", "type"]
},
{
"datasets": ["targetFiles"],
"isEdge": true,
"select": ["source", "target", "type"]
}
]

The first entry selects node properties from the file objects (id, title, lock state, type). The second entry (with isEdge: true) selects edge properties (source, target, type) which the renderer uses to determine which parent document each file belongs to.

A third entry without datasets selects properties from the parent document (the row's own context nodes). These are needed because file operations execute against the parent document:

{
"select": ["id", "title", "name", "type"]
}

Example dataset for indirect mode:

"datasets": {
"documents": {
"type": "nodes",
"applyOnGraph": true,
"statement": "[policy='Document Release']"
},
"targetFiles": {
"type": "expand",
"levels": 1,
"edgeStatement": "[type='files']"
}
}

Here targetFiles expands one level along files edges from the document nodes to reach the file objects. The isEdge data entry captures the edge source (the document) and target (the file), so the renderer knows which document each file belongs to — even though the row object itself is not the document.

tip

Use Data preview to inspect the graph and identify the correct edge types and node properties for your dataset configuration.

Example configurations​

Simple: files directly on the row object​
"files": {
"label": "Files",
"data": {
"datasets": ["relatedFiles"],
"select": "id"
},
"services": ["relatedFiles"],
"settings": {
"enableCache": false,
"cellRenderer": "FILE_MENU_RENDERER",
"cellRendererProps": {
"icons": {
"add": "wux-ui-3ds-upload",
"upload": "wux-ui-3ds-upload",
"view": "wux-ui-3ds-eye",
"download": "wux-ui-3ds-download",
"edit": "wux-ui-3ds-edit",
"lock": "wux-ui-3ds-lock",
"unlock": "wux-ui-3ds-unlock",
"update": "wux-ui-3ds-update",
"editUnlock": "wux-ui-3ds-lock-open",
"updateUnlock": "wux-ui-3ds-update-unlock",
"delete": "wux-ui-3ds-delete"
}
}
}
}

The relatedFiles dataset navigates directly from the row to its file objects. The select: "id" is sufficient — the renderer resolves file metadata from the graph.

Indirect: files via a connected object (e.g. product → document → files)​

Column configuration:

"files": {
"label": "Files",
"data": [
{
"datasets": ["targetFiles"],
"select": ["id", "title", "revision", "locker", "docTitle", "isLocked", "isLatestVersion"]
},
{
"datasets": ["targetFiles"],
"isEdge": true,
"select": ["source", "target", "type"]
},
{
"select": ["id", "title", "name", "type"]
}
],
"services": ["relatedFiles"],
"settings": {
"enableCache": false,
"cellRenderer": "FILE_MENU_RENDERER",
"cellRendererProps": {
"icons": {
"add": "wux-ui-3ds-upload",
"view": "wux-ui-3ds-eye",
"download": "wux-ui-3ds-download",
"edit": "wux-ui-3ds-edit",
"lock": "wux-ui-3ds-lock",
"unlock": "wux-ui-3ds-unlock",
"delete": "wux-ui-3ds-delete"
}
}
}
}

Matching dataset definitions:

"datasets": {
"documents": {
"type": "nodes",
"applyOnGraph": true,
"statement": "[policy='Document Release']"
},
"targetFiles": {
"type": "expand",
"levels": 1,
"edgeStatement": "[type='files']"
}
}

In this configuration:

  • The targetFiles dataset expands one level along files edges from the document to reach the file objects
  • The first data entry fetches file node properties (id, title, lock state, etc.) — these are needed for rendering the file rows and determining button visibility
  • The second entry (with isEdge: true) fetches edge properties that map each file back to its parent document — the source becomes the parentContextId for service calls
  • The third entry (no datasets) selects parent document properties from the row's own context — needed for file operations that execute against the document

File Manager Renderer​

FILE_MANAGER_RENDERER renders the same per-file action toolbar as the File Menu Renderer, but routes file transfers through the TVC File Manager desktop utility (browser extension + native Java application) instead of the browser. Files are downloaded to and uploaded from the user's local file system by the utility, which also supports a full check-out → edit → check-in round trip on the local file.

Overview​

  • Same toolbar and configuration: The renderer is built on top of FILE_MENU_RENDERER. The icon set, locked/unlocked button sets, data format, data configuration (direct and indirect modes) and viewer all work exactly as described for the File Menu Renderer.
  • Utility-driven actions: Only download, edit, upload (and add), update and updateUnlock are handled by the utility. All other actions (view, lock, unlock, editUnlock, delete) use the regular File Menu Renderer flow.
  • No browser file handling: For upload and update, the utility opens a native file dialog and uploads the chosen file itself. The browser never reads the file content.
  • Two deployment modes: The renderer works both against an on-premise TVC Office backend and against 3DEXPERIENCE cloud using out-of-the-box (OOTB) document APIs. The mode is selected automatically from cellRendererProps (see Mode selection).
info

The TVC File Manager browser extension and desktop utility must be installed on the user's machine. If the extension is updated or reloaded while the page is open, the user is asked to reload the page before continuing.

Mode selection​

The mode is determined by whether spaceUrl is set in cellRendererProps. No other mode flag is needed.

ModeWhenHow files are transferred
On-premisespaceUrl is setThe utility is initialised from the TVC Office backend on spaceUrl and handles the whole transfer, including the check-in on the platform.
CloudspaceUrl is not setThe widget obtains download/check-in tickets from the OOTB 3DEXPERIENCE document APIs, the utility transfers the file using the ticket, and the widget then registers the new file or version on the platform.

Cell renderer props​

In addition to the File Menu Renderer icons, the following cellRendererProps are supported:

PropertyDescriptionData TypeRequiredDefault
spaceUrlFull 3DSpace base URL of the TVC Office installation, e.g. https://host/3dspace. Enables on-premise mode. Leave out for cloud mode.stringno
ajaxUrlOn-premise only. Overrides the URL used to fetch the utility's initialisation data. Defaults to {spaceUrl}/tvc-action/json/webExtension/getInitArgs.stringno
useHeliumMainResourcesOn-premise only. When true, fetches the initialisation data from {spaceUrl}/tvc-action/json/heliumCore/getMainPageResources instead of getInitArgs. Ignored when ajaxUrl is set.booleannofalse

Actions​

ActionOn-premiseCloud
downloadThe utility downloads the file.Gets a download ticket (downloadDocument); the utility downloads the file from it.
editThe utility checks out and opens the file.Locks the file (lockDocument), gets a download ticket (editDocument) and the utility opens the file for editing. When the user checks in from the utility, a new version is created and the file is unlocked.
upload / addThe utility checks in a new file.Gets a check-in ticket (checkinTicket); the utility prompts for a file, uploads it, and a new file is created on the document.
updateThe utility uploads a new version.Same as upload, but a new version of the existing file is created. The file stays locked.
updateUnlockThe utility uploads a new version.Same as update, and the file is unlocked afterwards.
All other actionsSame as File Menu Renderer.Same as File Menu Renderer.

When checking in an edited or updated file, the utility asks for a check-in comment, which is stored on the new version. No comment is asked for a new file upload.

While the widget registers the uploaded file on the platform (cloud mode), the row shows a Processing... indicator. The row stays usable while the user is working in the utility (selecting a file or entering a comment).

If the platform rejects the check-in — for example because a new file has the same name as an existing one — the platform's error message is shown in the widget, and the entry in the utility is marked as failed instead of done.

Services (cloud mode)​

In cloud mode the renderer uses the built-in services described under Built-in services, plus finalizeCheckin, which registers the uploaded file or new version on the document:

Service keyHTTP methodPurpose
finalizeCheckinPUTCreates the new file (CREATE) or new version (REVISE) on the document using the upload receipt.
note

The utility-driven actions (download, edit, upload, update, updateUnlock) always call the built-in service definitions and cannot be overridden from the consumer configuration. Overrides still apply to the actions that use the File Menu Renderer flow.

Example configurations​

Cloud​

Same as the File Menu Renderer — only the cellRenderer changes:

"files": {
"label": "Files",
"data": {
"datasets": ["relatedFiles"],
"select": "id"
},
"services": ["relatedFiles"],
"settings": {
"enableCache": false,
"cellRenderer": "FILE_MANAGER_RENDERER",
"cellRendererProps": {
"icons": {
"add": "wux-ui-3ds-upload",
"upload": "wux-ui-3ds-upload",
"view": "wux-ui-3ds-eye",
"download": "wux-ui-3ds-download",
"edit": "wux-ui-3ds-edit",
"lock": "wux-ui-3ds-lock",
"unlock": "wux-ui-3ds-unlock",
"update": "wux-ui-3ds-update",
"editUnlock": "wux-ui-3ds-lock-open",
"updateUnlock": "wux-ui-3ds-update-unlock",
"delete": "wux-ui-3ds-delete"
}
}
}
}
On-premise (TVC Office)​

Add spaceUrl to switch to on-premise mode:

"cellRendererProps": {
"spaceUrl": "https://host/3dspace",
"icons": {
"add": "wux-ui-3ds-upload",
"download": "wux-ui-3ds-download",
"edit": "wux-ui-3ds-edit",
"update": "wux-ui-3ds-update",
"delete": "wux-ui-3ds-delete"
}
}

The indirect data configuration (files via a connected object) is supported in both modes.

Maturity Lifecycle Renderer​

MATURITY_LIFECYCLE_RENDERER displays an object's maturity/lifecycle state as a colored chip in the cell, and lets the user change the state from an in-place dialog — without leaving the table.

Overview​

  • Colored chip: The cell shows the current state using the same coloring options as AUTO_COLOR_RENDERER (fixedColorMappings, customColorMappings, or a hashed fallback).
  • Lifecycle dialog: Clicking the chip opens a modal that renders the maturity graph — every state as a box (ordered by the platform's visuorder, colored by each state's activeColor), connected along the linear path.
  • Promote / demote: Only the current state's immediate transitions are actionable. The next state shows a "Set to …" label under its box (promote); the previous state shows a backward arrow with a "Set to …" label (demote). Clicking a transition calls the change service.
  • Optimistic update: On a successful change, the object's node in the graph is updated (state / maturity_state) and the row re-renders in place — no full row refetch.

Target object​

The renderer acts on this column's object (the state cell's object), resolved from the cell's valuesWithSelect[].id (or the drag payload's objectId) — not the row's objectId. The dialog title uses the object's name taken from the matching graph node's title.