Settings UI
The Settings page (gear icon in the header, visible to users with the settings:read permission) is the in-app editor for every per-section TOML file. Each config type has a dedicated builder — a schema-driven form generated from the Pydantic models that the backend uses to load the file. A raw Monaco editor sits on every tab as an escape hatch when a builder's form doesn't expose the field you need.
Every save writes the TOML on disk, then triggers a server-side reload — the change is live in the same browser tab without a restart.
At a glance
The builder column on the left is shown collapsed; each entry opens a detail panel on the right (the screenshot shows the Pools builder).
The builders
The Settings page exposes nine builders plus the technical dashboard and the raw TOML escape hatch:
| Tab | Edits | Permission |
|---|---|---|
| Pools | connectors.toml → [pools.*] blocks — JDBC URLs, dialects, pool sizes, credentials. | settings:pools |
| Connectors | connectors.toml → [connectors.*] blocks — SQL queries, HTTP endpoints, API auth. | settings:connectors |
| Dictionary | dictionary.toml — column metadata: labels, formats, enums, lookups, validation. | settings:dictionary |
| Menus | menus.toml — sidebar trees per app, folders, leaves and permission gates. | settings:menus |
| Screens | screens.toml — grids, dialogs, tabs, per-field conditions, audit columns. | settings:screens |
| Dashboards | dashboards.toml — stat / bar / line / pie / grid layouts. | settings:dashboards |
| Charts | charts.toml — Recharts wrapper config referenced by dashboards. | settings:charts |
| Jobs | plugins/*/jobs.toml — Nomaflow job catalogue per app. | settings:jobs |
| Technical | Read-only — live pool stats, record locks, in-flight job runs, recent socket events. | settings:technical |
| Raw TOML | A Monaco editor per file. Loads the file as-is, saves it back. Last-resort path when a builder lacks a field. | settings:raw |
The permission codes are the canonical strings used by the role engine — see Authentication → Roles & permissions for how to grant them.
How a builder works
Every builder follows the same shape:
- List view — every entry of the underlying TOML section as a row.
- Detail panel — the entry as a schema-driven form (one field per Pydantic attribute) plus secondary tabs when the model has nested objects.
- Validation — every input is checked against the Pydantic model; an invalid value highlights the field in red and disables the Save button.
- Test (SQL / HTTP / API only) — runs the query or endpoint against the live pool and shows the first 50 rows.
- Save & reload — writes the TOML on disk and triggers a server-side reload. The success toast carries the affected file path.
Live preview of nested fields
For configs with nested rows (a screen's columns, a menu's leaves, a job's steps), the detail panel uses a drag-and-drop list with inline editors. The TOML order is preserved exactly as the operator arranges it — the framework does not re-sort entries on save.
Inline references
A connector's Pool field is a dropdown of the pools currently defined. A screen's Connector field lists every connector. A menu leaf's Screen field lists every screen of the selected app. Removing a referenced entry is refused — the builder reports which configs still point at it, with a link to each.
Raw TOML editor
The Raw TOML tab opens a Monaco editor on the underlying file. Syntax errors are highlighted live; the Save button stays disabled until the file parses. The editor is intentionally minimal — no rename helper, no validation against the Pydantic models — because its purpose is to unblock an operator when a builder lacks the exact field needed.
A confirmation dialog appears when saving raw TOML after a builder edit was made in the same session: the raw save would overwrite the builder's diff. Pick Keep builder changes to abort the raw save, or Use raw content to discard the builder edits and persist the raw text.
Save semantics
| Step | Effect |
|---|---|
| Click Save & reload in a builder | Pydantic model is re-validated. On success, the TOML is rewritten on disk through tomlkit (so comments are preserved on entries that already had them). |
| Server-side reload | POST /admin/reload is invoked with the file scope — only the affected registry is rebuilt. Live HTTP requests in flight keep their current state; new requests use the reloaded config. |
| UI refresh | The Settings page re-fetches the parsed config; any other tab open on the same model (e.g. the Connectors catalogue page) refreshes through a Socket.IO broadcast. |
For the exact reload contract — what reloads, what is left in-flight, what falls back to a restart — see Hot-reload.
Technical dashboard
The Technical tab is read-only and surfaces what the framework is doing right now:
| Panel | Content |
|---|---|
| Pool stats | Per-pool: open connections, idle, in-use, max, average checkout time. Refreshes every 2 s over Socket.IO. |
| Record locks | Active locks taken by the screen engine (one row per locked (connector, key) pair). |
| Job runs | Last 50 Nomaflow runs with their state and elapsed time. |
| Socket events | Tail of recent server-pushed events (lock acquired/released, config reloaded, job step transitioned). |
The page is restricted to users carrying settings:technical and is meant for diagnostics — no actions are exposed.
Backed by a REST surface
Every builder talks to a small set of /admin/config/* endpoints. They are documented under REST API reference → Admin config and are usable from curl for scripting:
| Endpoint | Purpose |
|---|---|
GET /admin/config/<section>/parsed | Return the parsed TOML as JSON. |
PUT /admin/config/<section>/parsed | Replace the parsed TOML — server re-serialises with comment preservation. |
POST /admin/config/<section>/raw | Replace the raw TOML text. |
POST /admin/config/connectors/{name}/test-sql | Execute a single SQL query and return its first rows. |
POST /admin/config/api/test | Execute an HTTP endpoint and return the response. |
POST /admin/config/rename | Rename an entity across every TOML file that references it. |
POST /admin/reload | Force a global reload (no file change). |
Tips & best practices
- Edit one section at a time. A Save & reload swaps just the affected registry — a multi-section change can leave the system in a transient state where one config is up to date and another isn't.
- Use the Raw TOML escape hatch sparingly. If you reach for it often, file an issue — a builder gap is worth fixing on the framework side.
- Run Test before Save on a SQL or HTTP connector. The framework rejects the Save if the connection-string parser fails, but it lets through a query that the database refuses at execution time. The Test button catches that earlier.
- Restrict the Raw TOML permission tightly. Operators who only need to edit a connector do not need to be able to overwrite the whole file.
- Keep
git statusclean. Every Settings save lands as a diff inliberty-apps; commit with a clear message so the rollback path is obvious.