Skip to main content

Screens — overview

A screen in Liberty is the page a user sees: a table of rows, optional filters, optional add/edit dialog, optional actions, optional row context menu. One screen = one <base>_get query + (optionally) <base>_put / <base>_post / <base>_delete for writes + a dialog form on top.

The page that manages screens is Settings → Screens. This overview maps it; the next pages walk through each task.


The Screens page at a glance

Settings · Screenscrmnomajdenomasx1+ Add screens for a connectorDiscardSave🔎 Filter screens…customersCustomers · 2 tabs · 9 fields · 3 actionsread_query=customers_get✎ Rename⎘ Clone🗑dealsDeals pipeline · 1 tab · 6 fields · row menuread_query=deals_get✎ Rename⎘ Clone🗑+ Add screen (lands at the top of the list)

Three regions:

RegionWhat it carries
Top scope barOne chip per app (a connector that has a menu). Click a chip → its screens load below. The + Add screens for a connector button registers a brand-new connector under the Screens namespace. Discard / Save on the right commit or revert page-wide edits.
Filter barA search input for the screen list. Visible when the selected app has more than a handful of screens.
Screen listOne card per screen, vertical scroll. Each card shows the id, label, read query, tab count, field count and per-card actions: Rename, Clone, Delete. Clicking a card opens the Screen Designer modal.

The Screen Designer modal

Clicking a card opens a near-fullscreen modal hosting the ScreenEditor. The header has Maximize / Restore (default fullscreen), Cancel and Save — Save commits just this screen's edits and closes; Cancel prompts on unsaved changes.

Inside the modal, seven tabs organise everything:

Screen Designer · crm.customersGeneralQueriesColumnsDialogActionsRow menuExportTab content
TabCarries
GeneralIdentity, connector override, audit table, row cap, key columns, behaviour flags (auto-load, editable, uploadable), grouping, treeview, default chart, row-click behaviour.
QueriesThe four CRUD query references — read (required), update, insert, delete. Picker is fed from the connector's queries list.
ColumnsOne row per column hint — labels, formats, defaults, dictionary references, filtering, edit rules. Click a column to drill into its full editor.
DialogThe Visual Builder — a three-column Figma-style canvas (Palette / Canvas / Inspector) where you drag fields onto tabs. Optional — a screen without a dialog still works as a read-only / grid-edit table.
ActionsThree groups: Dialog hooks (on_load / on_save / on_cancel), Toolbar (buttons above the table), Row hooks (on_insert / on_update / on_delete).
Row menuRight-click context menu actions on a row.
ExportMulti-sheet xlsx export configuration — optional.

The next pages of this section walk through each tab as a separate task.


What a screen carries

The schema's top-level fields, grouped by purpose:

GroupFields
Identityid, label, description, connector (blank = the app's own connector)
Read queryread_query (required), auto_load, max_rows, key_columns
Write queriesupdate_query, insert_query, delete_query
Editing & displaycolumns, editable, uploadable, initial_group_by, treeview, chart_id
Auditaudit_table (e.g. AUD_USERS — mirrors writes with AUD_ACTION / AUD_USER / AUD_DATE)
Formdialog (optional — the form on top of the table)
Actions / hooksactions (toolbar), row_menu (right-click), on_insert / on_update / on_delete (row hooks)
Row-click targetrow_click_screen + row_click_connector + row_click_binds (open a sibling screen as a dialog) OR row_click_route (open a SPA route)
Exportexport (workbook xlsx config)

Screen kinds — by what's set

There's no kind discriminator; you get different screen shapes by which fields you fill in:

Filled inBehaviour
read_query onlyRead-only grid. The user sees rows; no edit, no add.
read_query + editable = trueInline grid editing — the user edits cells in place, the grid's Save button writes back. Requires update_query.
read_query + dialogGrid + dialog. The user adds/edits rows through the form. Requires the matching insert_query / update_query.
read_query + row_click_screenMaster/detail. Clicking a row opens a sibling screen's dialog narrowed to that row.
read_query + row_click_routeMaster/page. Clicking a row navigates to a SPA route — escape hatch for hand-written React pages (live-streamed logs, multi-source merges).
Any of the above + treeviewTree view toggle in addition to the default Table / Chart toggles. Parent/child columns build a recursive node tree.

The same screen can layer several: a screen with dialog AND row_click_route opens the route on click (route wins), and the dialog is reached only via the toolbar's + Add button.


Permissions — gated by the read query

The screen itself does not have its own permission string. A user can see a screen when they have the permission to run its read query:

sql:<connector>:<read_query>

So a screen customers on connector crm with read_query = customers_get is visible to anyone with sql:crm:customers_get. Granting sql:crm:* opens every query on the connector — and therefore every screen that uses it.

The same logic applies to writes: the dialog's Save and the grid's Save succeed only when the user has sql:<connector>:<update_query> / <insert_query> / <delete_query>. A user with read but no write permission sees the grid but no + Add button and gets a read-only dialog.


Save and reload

The Screens page's Save button writes the whole screens.toml (the [screens] table is replaced wholesale) and triggers a hot reload. The status banner reports which apps were touched.

The hot reload means no process restart — a new screen is callable immediately at /screen/<app>/<id>, and the menu picks it up if a menu entry points at it.


What you actually do — quick map

GoalRead
Wire a fresh screen to a _get query and see the grid.Create a screen from a query.
Configure columns — labels, formats, defaults, filtering.Columns.
Build the add/edit dialog with the visual designer.Dialog builder.
Make fields appear / be required / be locked under specific conditions.Conditional fields.
Add toolbar buttons, row menus and lifecycle hooks.Actions and lifecycle.
Embed a child-record form or a related-rows grid in a tab.Nested tabs.

What's next