TGrid definitions, sessions, and queries
View as MarkdownIdentity
Section titled “Identity”TGrid and table-grid exports come from @sapporta/frontend. Standalone
runtime primitives come from @sapporta/grid.
Definition and lifecycle
Section titled “Definition and lifecycle”defineTGrid()declares schema-table levels, parent relationships, query ownership, interaction configuration, and typed column builders.useTGridSession()creates a session after React commit and disposes it on unmount. It returnsnulluntil the session exists.createTGridSession()creates a session for tests and non-React hosts. Its owner must calldispose().TGridrenders a configured session.TableRouteandSchemaTableGridViewconnect standard table routes.useSchemaTableGrid()exposes the session when an application composition needs schema-derived defaults plus active-row or activation behavior.
Table-aware clients preserve Sapporta query syntax, lookups, row saves, auth, record navigation, CSV export, and URL query state.
sessionRef
Section titled “sessionRef”TableGridView and SchemaTableGridView accept:
sessionRef?: React.Ref<TGridSession<RowsByLevel, AppServices>>Use it when another component needs to inspect or control the live session without replacing the standard table UI—for example, to reload rows, observe session state, coordinate selection or expansion, or reveal a deep-linked row.
The view owns and disposes the session. The ref is set after creation and
cleared to null when the session is replaced or released, so callback-ref
subscriptions must clean up on null. The parameter is also available through
TablePageGridOptions and TableGridOptionsByTable. useTableGrid() and
useSchemaTableGrid() omit it because their returned binding already contains
session.
Standard-page columns
Section titled “Standard-page columns”SchemaTableGridView derives its columns from the table schema and supplies the
whole table page: URL query state, filters, search, sort, pagination, CSV export,
lookup labels, record routes, the toolbar, and New record. Its columns prop
replaces that derived list for the root level, so a page can hide, reorder,
restyle, or add columns without rebuilding the page as a defineTGrid
definition. useSchemaTableGrid and defineSchemaTGrid take the same value, and
TablePage takes it through gridOptions.
type SchemaTableColumns<AppServices = unknown> = TGridLevelColumns< SchemaTableRowsByLevel, AppServices, string>;The value is the spec list or builder callback a defineTGrid level’s columns
takes, built with columns.table(), columns.client(), and
columns.remainingTable(). remainingTable() fills the gaps in schema order, so
a page names only the columns it changes. The value is checked against the table
when the grid builds, not when the grid is declared, and a new identity rebuilds
the grid, so keep it in a module constant or useMemo. Child levels,
fixedFilters, search, and CSV export are unchanged, and other views of the
table still show every column.
expandTGridColumnSpecs is exported for an application that compiles the same
value itself: it returns the visible columns, in order, with every name checked
against the table.
Change the standard page’s columns
walks through the prop with worked examples.
Query and loaded-row session APIs
Section titled “Query and loaded-row session APIs”TGridSession exposes:
getVisibleRows(levelId?, path?)andgetLoadedRow(rowKey, levelId?, path?)for rows already loaded into the Grid;getQueryState(levelId?)for host-owned query state;reloadRows(),setLevelSort(),setLevelFilter(), andsetLevelPage()for path-specific table controls;csvExportUrl(levelId?)for the current fixed filters, visible filters, search, and sort; andlookups,lookupForColumn, application services, and level metadata for custom cells and editors.
Loaded-row reads are not database queries. Use generated table reads, public table read functions and options, or an application endpoint when the row may not be loaded on the current page.
Host-owned query state supplies visible controls and URL state. Source-owned
query state belongs to a relationship source. fixedFilters affect row loads
and CSV exports but are not editable filter state. Row loads send a level’s
parent-row constraint and fixedFilters as
fixed conditions, and
the user’s filters and search as filter conditions and q. CSV exports send
all of them as filter conditions. Client query constraints do not enforce
authorization.
Tree levels
Section titled “Tree levels”A level whose table declares meta.tree shows its rows as one indented tree.
The level’s tree option adjusts that:
type TGridLevelTreeConfig = false | Partial<TableTree>;- Leave
treeout to follow the table’s declared tree. tree: falseshows a tree table as a flat, paged list, for example inside a picker.- An object overrides single fields of the declared tree:
parentColumn,column,defaultExpanded, ormatchContext. - A table without
meta.treecan opt in by namingparentColumn. The level then builds the tree in the browser, and a search returns only the matching rows, because the server walks only a tree the table declares.
A tree level declares no childLevels; defineTGrid() throws when it does, and
when parentColumn is not a column of the table. The hierarchy is shown in the
declared column when the level shows it, otherwise in the card title column,
otherwise in the first column. session.levelInfoById[level].tree is the
resolved TableTree with the column actually used, or null for a flat level.
A tree level reads every row in one request so it can build the whole tree: the
first page at MAX_PAGE_SIZE (1,000) rows. TGridLevelInfo.pagination is
"all" for a tree level and "pages" for a flat one. Query state,
setLevelPage(), URL state, and useTableLevelPager() follow it, so a custom
page built from the table hooks shows a tree on one page.
When the table declares the same tree, each row load sends the level’s
matchContext as the tree mode. A filter or search then keeps each match’s
ancestors, and by default its subtree, inside the level’s fixed conditions.
useTGridSourceStatus(session).treeResult reports the last load as a
TGridTreeResult:
matchCount: rows that match the filter or search themselves, ornullwhen neither is active;loadedRowCount: rows the load returned;truncated:truewhen the table holds more rows than one load returns, so the tree may be missing rows.
treeResult is null for a flat level and before the first load.