List Views
The List Views editor is the configuration page for the four spec-driven list pages: Invoices, Integration Errors, E-Reporting and Processing Log. One JSON spec per view drives the column shape on each page — labels, type, format, alignment, width, default sort and the filter-row allow-list — and is editable here without touching code.
A second concept lives next to the spec: the column catalog. Each view ships a catalog of every column the underlying tables can produce — the catalog is the source of truth for what is addressable, the spec picks a subset and presents it. The + Add column picker is just a filtered view of the catalog.
At a glance
View selector
A pill bar at the top of the page switches between the four views currently driven by a spec:
| View | Page driven |
|---|---|
| Invoices | Invoices — view.invoices. |
| Integration Errors | Integration Errors — view.integration-errors. |
| E-Reporting | E-Reporting — view.ereporting. |
| Processing Log | Processing Log — view.processing-log. |
Only one view at a time is loaded into the editor. Switching views does not lose unsaved changes on the previous view as long as the page stays open; Save writes the active card only.
A small badge next to the view name tells the operator whether the active spec comes from the bundled JAR default (default) or from an entry stored on db-nomaubl (override):
- default — no
view.<name>property exists ondb-nomaubl. The bundled JSON inconfig/list-views/view.<name>.jsonis what the page renders. Saving from the editor writes a property and switches the badge tooverride. - override — a property has been stored. The editor reads the stored value, the page reads the stored value, the bundled default is ignored.
Column rows
Each card carries a table of the columns currently in the spec. One row per column.
| Column | Description |
|---|---|
| ⠿ (drag handle) | Drag to reorder. The order in the editor is the order the column appears in the grid. |
| Name | The spec column name — must match a column in the view's catalog. Read-only on existing rows (the name is the join key with the catalog); editable only when adding via the picker. |
| Label EN / Label FR | The labels shown in the grid header. Label FR is used when the active locale starts with fr, otherwise Label EN. Both fields are free-form. |
| Type | string / number / date / datetime. Drives sorting and cell alignment defaults. |
| Format | Optional renderer: date / datetime / amount / percent / badge. Applied on top of the type. |
| Width | Pixel width passed to the table's <colgroup>. Columns without a width share the leftover horizontal space. |
| Visible | Master toggle. Off = the column is in the spec but hidden in the grid (still queryable). |
| Filter | Allow-list for the Advanced Filters panel. Off = no filter chip is offered for this column. |
| ⌫ (remove) | Drops the column from the spec. The catalog entry is untouched — re-adding it later seeds the same shape. |
The default sort lives on the spec but is set elsewhere (today, by editing the bundled JSON or the stored property directly; a UI toggle is planned for a future release). Each view ships a sensible default.
+ Add column
The button below the row list opens the catalog picker — a searchable list of every catalog entry the current spec does not already contain. Each entry shows:
| Field | What it carries |
|---|---|
| Name | The catalog column name — same value the spec stores. |
| Label | The default English label suggested by the catalog. The French label is derived from the catalog's labelFr if present; both labels can be edited after the column lands in the spec. |
| Type | STRING / NUMBER / DATE / JDE_DATE / JDE_DATETIME. Drives the spec row's default type. JDE-specific dates carry a built-in decoder (Julian or composite UPMJ+UPMT). |
Picking an entry inserts a new row at the end of the table seeded with the catalog defaults. Click Save to commit; the column appears in the page on its next render.
The catalog itself is server-side and is not editable from the UI. Adding a truly new column (one the back-end does not know how to project) requires a code change on the Java handler.
Defaults row
Above the column rows, each view card carries a Defaults row with the per-view settings that apply outside the column shape.
| Field | Description |
|---|---|
| Page size | Initial page size for the in-grid TanStack paginator. Persists as spec.defaultPageSize. Default: 50. |
| Max rows (2026.05.12) | Hard cap on the slice loaded by a single Run. The four spec-driven views now operate in hybrid client-side mode: each Run loads one capped slice from the server and TanStack paginates / sorts / filters within that slice — no roundtrip while typing in the per-column filter row. Persists as spec.maxRows. Default: 5000. |
When the slice cap is hit during a Run, the page toolbar shows a translated X / Y rows notice next to the Run button — a hint that the operator should narrow the date range or the Advanced Filters to get the most relevant slice. The notice is informational; the page keeps working.
Advanced Filters panel
The spec's filter: true allow-list seeds a second UI on the destination page: the Advanced Filters panel — a collapsible panel keyed by spec column name with per-column operator pickers (contains, equals, ≠, <, ≤, >, ≥, between, empty, not empty). The panel emits a draft state; an explicit Run button commits it as appliedFilters so typing does not spam the back-end.
The list of operators offered per column depends on the catalog entry's filter behaviour:
Catalog filterKind | Operators offered |
|---|---|
exact | equals, ≠, empty, not empty. |
LIKE | contains, equals, ≠, empty, not empty. |
inList | equals (multi-pick — the catalog splits comma-separated buckets into an IN (?,?,?,?,?) clause). |
between | <, ≤, >, ≥, between. Applies to numeric and date columns. |
Marking a column Filter = off in the spec keeps it visible in the grid but removes its chip from the panel; useful for read-only fields the operator does not need to query.
refList columns — multi-select picker (2026.05.13)
A column can be bound to a reference list — either a regulated one from Reference Lists (statuses, currencies, country codes, …) or an operator-defined one from Custom Lists. Setting refList: <list-name> on the column spec is all that is needed: cell renderer, per-column filter dropdown and Advanced Filters multi-select picker switch on automatically.
When the catalog or the spec declares a column as a reference list (refList: …) — the statuses picker on Invoices, the eReporting statuses on E-Reporting, any custom list — the Advanced Filters panel and the per-column filter row both render a multi-select picker instead of a single dropdown. Each row in the picker is a toggle (code — label), the trigger shows N selected past the inline cap, and a ✕ button on the right resets the selection in one click without opening the popover.
The multi-select selection is encoded as comma-joined in OpFilter.a (e.g. 200,210,9907); on the server side, the catalog's filterInList flag splits it into an IN (?,?,?,?,?) clause, so picking three statuses really does return the union — not a LIKE over the joined string.
The between operator on a date / number / text column widens the column to fit both operand inputs (BETWEEN_COL_WIDTH = 340px) so the two fields render side by side rather than truncating. Switching back to a single-operand operator snaps the column to its spec width on the next render.
Schema reference
The spec file looks like this (excerpt):
{
"name": "view.invoices",
"defaultSort": [{"column": "creationDate", "direction": "desc"}],
"columns": [
{
"name": "statusCode",
"label": "Status",
"labelFr": "Statut",
"type": "string",
"format": "badge",
"align": "left",
"width": 90,
"visible": true,
"filter": true
},
{
"name": "customerName",
"label": "Customer",
"labelFr": "Client",
"type": "string",
"width": 180,
"visible": true,
"filter": true
}
]
}
The name joins with the catalog entry that has a matching key; everything else on the row is presentation. Saving from the editor writes the same shape under db-nomaubl.view.<name>. Resetting the property — easiest done via Configuration → System → Global while it carries the JSON properties — falls the page back to the bundled default and switches the badge to default.
Tips & best practices
- Start with the bundled default. Each view ships a curated default; modify only when an operator-specific need surfaces. The
overridebadge is the operator's signal that the spec drifted from the shipped configuration. - Use the catalog before requesting code changes. When a column the operator wants is already in the catalog (e.g.
logBusinessUnit,logDueDate),+ Add columnsolves it in a few clicks. Reach for a code change only when the column is not in the catalog. - Keep the filter allow-list small. Marking every column
filter: trueclutters the Advanced Filters panel — limit the allow-list to the columns operators actually query. - Set widths on the columns that benefit from them. Status badges, dates, codes have natural widths; long strings should be left without a width so they take whatever room is left.
widthis also the column's CSSmin-width— a too-large value cramps the rest of the grid. - Hidden ≠ removed. Setting
Visible = offkeeps the column queryable by the Advanced Filters panel. Use it for technical fields the operator filters on but does not need to read.