[data-reveal]{opacity:1!important;transform:none!important}
AntelopeJS DMS
DocumentationTable sources and tenant gates

Table sources and tenant gates

Table views over a module's own route, and table views that stay readable behind a tenant access gate.

A table view usually reads a data controller. These two cases differ: a table view over a module's own route, and a table view that stays readable while a tenant access gate denies the tenant.

Tables over a module's route

typescript
TableView.fromSource(options: TableViewSourceOptions): ComponentBuilder<TableViewOptionsSerialized>;

A read-only table view with no data controller (tableViewFromSource). TableViewSourceOptions takes columns (a record of TableViewSourceColumn, a @Column's options plus sortable), fetchUrl (its {{params.X}} / {{query.X}} tokens are filled from the page URL, percent-encoded; the table and its tab counters list again when they change and request nothing while one has no value), fetchRowUrl? (a route answering one row by id, {{row.id}} its percent-encoded id, with the same tokens: a deep link to a row the table does not list opens through it; serialized on TableViewSourceSerialized), rowIdKey?, periodScope? (the id of a PeriodSelector: every request carries its from, to, preset and comparison, the table lists again when the period changes, and nothing is requested until the selector is on the page), capabilities? (TableViewSourceCapabilities: search, sort, paginate, filter), queryParamFilters? (URL query parameters sent to the route as hidden filter_<field> filters), custom row actions and buttons only, and the presentation options of a table view (caption, layout, pagination, tabs, quickFilters, displays, card, emptyStates, footer texts and legend…). The route answers { results, total } and is sent the part of the list query its capabilities name, nothing else; the browser does the rest over the rows it answered, except that a paging route's rows are neither searched nor sorted by the browser. Registration runs the checks of TableView() that apply (page size, display ids, tab targets) and throws when tabs, quick filters or queryParamFilters lack capabilities.filter, or when a key they, labelKey, card.fields or expandable name is not a column, or when expandable sets lazyLoad (a source has no get route), or when fetchRowUrl lacks {{row.id}}; it warns about a quick filter on a column with no values to pick. There is no export, realtime nor footer summary.

Reach a table behind a tenant gate

bypassTenantAccessGate is the table-view mirror of the guard option of the same name. Reserve it for tables that must stay readable while a gate denies the tenant, such as the invoices on the billing page of a suspended tenant, so it can regularize its situation. Permission checks still apply.

Data routes are registered against the controller, not against a page, so the opt-out is controller-level and latched: once any TableView() call on a controller declares it, the controller's routes bypass the gate wherever they are rendered. A later registration of the same controller without the flag cannot re-gate them, and gets a warning saying so. Two consequences worth designing around:

  • Declaring the flag on a controller opens its routes for every table view built on it, including one mounted on an ordinary page.
  • Actions that carry no permission id, such as a plain list on a component that was never mounted, are then served to any member of a denied tenant. That is the escape hatch working as intended, so keep every action of a flagged controller stamped with a permission.