Skip to content

Configuring Parent Tree View

Parent Tree View is a deliberate Table Surface contract. Runtime users do not switch it on ad hoc. The configured surface may be the entity default, in which case every table host that follows the default renders the hierarchy.

The parent field must be:

  • active and stored directly on the primary table;
  • Reference, scalar (AllowMultiple = false);
  • owned by the same entity definition;
  • targeted at that same entity definition;
  • covered by a valid, ready, parent-leading PostgreSQL BTREE index.

The Configuration API returns structurally eligible fields even when an index is missing, with Availability = MissingBtreeIndex. Such an option is visible but cannot be saved.

  1. Create a scalar Reference field such as Parent that targets the same Entity Definition.
  2. In Entity Explorer, verify its automatic index in the Schema tab’s Indexes panel. Package-owned schema instead requires an EF model and package migration update.
  3. Open the existing default Table Surface, or create a separate custom one.
  4. In its Behavior tab, open Table presentation, choose Tree View, and select Parent.
  5. Optionally choose a Group sort field and direction; leaving the default sorts every sibling set by Display name ascending.
  6. If it is not default, assign the custom surface through Entity List page MainTableSelectors or another supported table selector.
  7. When hierarchical reference selection is needed, assign that surface to a persisted Reference form item whose input is Lookup.
  8. Save, reload the editor, and verify the selected parent field.

Tree View is allowed on the default Table Surface, and a configured Tree surface can be promoted to default. The mutation is atomic and is rejected if any persisted List/LongList form item follows the default or explicitly selects that Tree surface. Convert the blocking item to Lookup or choose a Flat table.

All routes are relative to the target installation’s workspace API host. Never guess ids, keys, or enum values. Read the installed Configuration OpenAPI and options first:

GET /api/workspace/admin/entity-definitions/{definitionId}/ui/table-surfaces/configuration/options

Find a TreeViewParentFields item with Availability equal to the installed OpenAPI enum member for Ready; copy its id and key. Create a surface (or use the current default):

POST /api/workspace/admin/entity-definitions/{definitionId}/ui/table-surfaces
Content-Type: application/json
{
"Name": "Requests by parent",
"Key": "parent_tree",
"IsDefault": true
}

Read the current Table configuration, preserve the properties you intend to keep, and replace it:

PUT /api/workspace/admin/entity-definitions/{definitionId}/ui/table-surfaces/parent_tree/configuration
Content-Type: application/json
{
"AfterCreateNavigation": 0,
"AfterUpdateNavigation": 0,
"Actions": [],
"Columns": [],
"ProjectionColumns": [],
"RowRules": [],
"FilterItems": [],
"SortItems": [],
"DefaultSort": [],
"TreeView": {
"ParentFieldDefinitionId": "<copy from TreeViewParentFields>",
"ParentFieldKey": "Parent",
"SortFieldDefinitionId": "<optional, copy from TreeViewSortFields>",
"SortFieldKey": "Priority",
"SortDirection": 1
}
}

Numeric values above are illustrative defaults; copy enum names/values from the installation’s OpenAPI. Both parent id and key are required and must identify the same field. The sort members are optional: id and key must identify the same sortable primary-table field from TreeViewSortFields, and omitting them keeps the Display name default. SortDirection may be sent alone to flip the Display name ordering.

To return the surface to Flat presentation, send the same complete replacement document with "TreeView": null.

Tree sibling ordering is owned by the Tree View configuration, not by the surface DefaultSort:

  1. an explicit runtime sort sent with the request wins;
  2. otherwise the configured group sort field and direction apply;
  3. otherwise siblings order by Display name ascending.

The ordering applies independently to every sibling set — roots against roots, children of one parent against each other — and never moves a child out of its parent branch. In the runtime grid, the header of the hierarchy column toggles the group sort between ascending and descending. On mobile, the Sorting sheet shows that same effective group sort and direction even when the field is not also listed as an ordinary table sort item.

Field access still applies to group sorting. If the current user cannot query the configured group-sort field, Moltaro hides that field’s identity and safely falls back to Display name ascending instead of making the Tree View fail.

Use the Entity List page configuration endpoint to add a CustomKey selector for parent_tree. At runtime the selected member is exposed as EntityListPageRuntime.MainTableSelector. A role-specific selector may choose Tree while the fallback/default selector remains Flat.

For a persisted Reference form item, set its effective ReferenceInputType to Lookup and add the Tree surface to LookupTableSelectors. The backend rejects the same selector on List, LongList, a non-Reference item, or another form control.

Dynamic Reference fields receive an automatic BTREE index. Eligibility is checked by physical shape, not an automatic name: the parent column must be the first key, the index must be valid and ready, and expression or partial indexes do not qualify.

For unusually wide branches, an additional composite (Parent, frequently-used-sort-field) index can improve sibling ordering, but it does not replace the mandatory parent-leading index.

Package-owned entities must ship a parent-leading index through their owning schema migration. Package apply rejects Tree metadata when the installed physical schema lacks that index; the dynamic automatic-index path does not apply to package-owned schema. NetPackage surface authoring and migration APIs are an internal module/package boundary and are intentionally not part of the public Net Operation Project SDK.

Export stores:

TableConfiguration:
TreeView:
ParentFieldKey: Parent
SortFieldKey: Priority
SortDirection: Desc

Import resolves the keys in the destination definition and writes local field ids. A missing key, wrong target, or non-Lookup selector is a plan/apply error; no Flat fallback is substituted. A default Tree surface round-trips. SortFieldKey and SortDirection are optional and default to Display name ascending.

HostTree View
Data Explorer through Entity List page selectorSupported
Generic full Reference picker, default or explicit table keySupported
Persisted Reference Lookup form itemSupported
List / LongList reference controlRejected
Direct table/bootstrapSupported
Details related tableSupported
Details/Drawer relation blockSupported
  1. GET the Table Surface configuration and compare both parent id and key.
  2. GET the surface catalog/default row or Entity List page configuration and verify the effective selector.
  3. For a persisted picker, GET the Form Surface and verify Lookup plus its selector.
  4. Bootstrap each affected host; a Tree response has Page = null, non-null TreePage, and non-null Model.TreeView.
  5. Load one child page with the returned surface id/revision. Related hosts also echo their opaque ContextRevision.
  6. Repeat as an ordinary reader to verify effective roots and visible counts.