Custom Lists
A Custom List is an operator-defined reference list — a code → labelFr / labelEn table managed outside the regulated catalogs in Reference Lists. Its job is to power a grid: assign a custom list to a column in the List Views editor and the column gets a dropdown filter, a multi-select picker in Advanced Filters, and a code — label cell renderer — all automatically, without any code change.
Each list can be edited row by row, or synced from a connector (API or SQL) when the source of truth lives in an external system. Same query / endpoint can power several lists by feeding different parameters per list.
At a glance
List selector
The page lists every custom list defined on the platform. Pick one to edit; + New list above the row table creates a new entry seeded with an empty row.
| Field | Description |
|---|---|
| List | Dropdown of every custom list (name). The name is the identifier that the List Views editor references — picking a list here is editing it, picking the same name in a column spec under List Views binds the column to it. |
| + New list | Creates a new list. A Name prompt asks for the identifier; that name is what column specs will reference. |
| Save | Writes the active list. Switching to another list before saving discards unsaved edits. |
Rows
The row table is the canonical content of the list. One row per entry, three columns.
| Column | Description |
|---|---|
| Code | The stored value — what the column cell holds in the grid (e.g. PAR, MCU0070, 01). |
| Label FR | French label rendered next to the code in the picker and in the cell (code — label). Required. |
| Label EN | English label rendered when the active locale starts with English. Optional — when empty, the FR label is reused. |
| ⌫ | Removes the row. |
+ Add row at the bottom appends a new empty row. Rows are sorted alphabetically by code in dropdowns and pickers; the editor preserves the order in which rows were added so the operator can reorder them by hand.
Sync source
A custom list can be backed by an external system instead of being edited by hand. The Sync source (optional) group sits below the row table. Pick an API connector or a SQL connector, pick an endpoint / query, then map the response fields to the list's three columns.
| Field | Description |
|---|---|
| Connector | Dropdown of every api-connector and sql-connector template defined on the platform. Picking one limits the next field to that connector's targets. |
| Endpoint / Query | Dropdown of the connector's endpoints (API) or queries (SQL). Disabled until a connector is picked. |
| Code field | Column name (SQL) or JSON key (API) the sync reads as each row's code. Required. |
| Label FR field | Column / key for the French label. Required. |
| Label EN field | Column / key for the English label. Optional. |
| List path (API only) | Dotted path to the array inside the JSON body. Supports data.items and items[0] segments. Empty when the body is already a JSON array. |
| Parameters | Per-list key / value pairs sent to the connector as fixed values (no placeholder substitution). The same query can power several lists by saving different values per list; defaults from the endpoint definition apply when a field is left blank. |
| Sync now | Calls the connector, walks the response, builds the row set, and replaces the rows in place. A translated banner reports Synced N row(s) from connector · endpoint on success, or the underlying error on failure. |
The sync config lives on the same list template under sync.connector, sync.endpoint, sync.codeField, sync.labelFrField, sync.labelEnField, sync.listPath and sync.params. List consumers (cell renderer, Advanced Filters dropdown, per-column filter row) never see those keys as entries — they are filtered out of parseRefOptions.
A Sync now does not auto-save; it only rebuilds the row table. Click Save to persist the synced rows.
Using a custom list in a grid
A custom list is wired to a grid through the List Views editor. On the column row, set the refList field to the list's name:
{
"name": "logBusinessUnit",
"label": "Business unit",
"labelFr": "Unité d'activité",
"type": "string",
"refList": "business-units",
"width": 150,
"visible": true,
"filter": true
}
Effects on the grid:
- Cell renderer — instead of the raw code, each cell shows
code — label(FR or EN depending on the locale). Empty values stay blank. - Per-column filter row — the text input is replaced by a searchable dropdown populated from the list's rows. Each entry is
code — label. - Advanced Filters multi-select picker — the list seeds the multi-select picker. Picking several entries issues an
IN (?,?,?)clause on the server.
No code change is needed — adding a row to the list, syncing it from a connector, or renaming a label refreshes the grid on the next render.
REST endpoints
The list editor and the grid consumers share the same back-end:
| Method | Path | Purpose |
|---|---|---|
GET | /api/ref-lists | Returns every defined list with its rows. The grid loads this once per session and caches the result; the editor invalidates the cache on save. |
GET | /api/ref-lists/{name} | Returns one list with its rows + the sync config when present. |
PUT | /api/ref-lists/{name} | Writes the list. Body: { name, rows: [...], sync: {...} or null }. |
POST | /api/ref-lists/{name}/sync | Triggers the sync. Returns the rebuilt row set on success, the underlying connector error on failure. |
Tips & best practices
- Pick a stable name. The list's name is what column specs reference under
refList. Renaming a list later breaks every column spec that points to it — better to delete and recreate under the new name once the column specs have been updated. - Keep the FR label populated. The cell renderer falls back to the FR label when the active locale is FR; an empty FR label surfaces the raw code in the grid, which is rarely what an operator wants.
- One connector query, many lists. When several lists share the same back-end query (e.g. active business units for company 00070 vs. active business units for company 00080), save the query once on a SQL or API connector and feed different Parameters per list. The endpoint defaults fill in the rest.
- Sync replaces, it does not merge. A Sync now removes every existing row before inserting the new ones. Manual edits made between two syncs are lost — when manual overrides matter, keep the list either manual or fully synced, not both.
- Hidden columns can still be filtered. A column bound to a custom list can be marked
visible: falsein the spec and still surface in Advanced Filters — useful for technical fields likelogBusinessUnitthat operators want to filter on but not display.