Class PageBuilder
Page's content: an optional header, a grid of dashboard
widgets, and freeform PageComponent blocks. Widgets reuse the same
builder as UiLayoutBuilder.widget(...), so the full widget config
(type, entity, calendar/kanban/chart options) is available here.
Rendered order is header → widget grid → components.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final classPreset view for an embeddedlist(Class, Consumer)— initial filter selections, a base feed constraint, a group-by column and date granularity, and a sort.static final classBuilds onePageRow: a sequence ofPageBuilder.RowBuilder.col(java.lang.String, java.util.function.Consumer<su.onno.ui.PageBuilder>)calls. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionactions(String heading, Consumer<ActionSpec> configurer) Add a section of action buttons — each runs an обработка-style server handler (or routes the client) when clicked.aside()The right-rail sub-builder, ornullif the page composed noaside(...).aside(Consumer<PageBuilder> configurer) Compose a right rail beside the main content — a narrow side column for stats, filters, or a summary that sits next to a list rather than stacked above it.bare()Drop the page header entirely — shorthand forheader(false).Add adiv-customextension block (chart, kanban, ...).header(boolean show) Show or hide the page header — the title/subtitle row the framework renders above the content.Embed the full interactive list of a catalog/document — the same surface as its own route, with the New button, custom action buttons, search/sort and rows that open a detail beside the page.list(Class<?> entity, Consumer<PageBuilder.ListDefaults> configurer) Embed an entity list opened on a default view — preset filter selections, grouping, sorting, and/or a base feed constraint.pageAction(String key) The page action with this key, ornullif the page declares none.The page's action-button handlers, in declaration order (resolved by key on post-back).row(Consumer<PageBuilder.RowBuilder> configurer) Add a multi-column layout band — the general layout primitive.rows()The explicit layout rows composed withrow(...), in declaration order.booleanWhether the renderer should emit the header row (title/subtitle).subtitle()Add a freeform text block.title()Add a dashboard widget; returns the widget builder for further config.widgets()
-
Constructor Details
-
PageBuilder
public PageBuilder()
-
-
Method Details
-
title
-
subtitle
-
header
Show or hide the page header — the title/subtitle row the framework renders above the content. On by default. Hide it for a page that supplies its own heading (a hero widget, a custom banner) or a chrome-less surface.bare()is the shorthand forheader(false). -
bare
Drop the page header entirely — shorthand forheader(false). -
widget
Add a dashboard widget; returns the widget builder for further config. -
text
Add a freeform text block. -
actions
Add a section of action buttons — each runs an обработка-style server handler (or routes the client) when clicked. Reuses the sameActionSpecDSL as entity actions, but the buttons live on the page itself rather than a list toolbar, so triggering backend logic is a first-class page primitive:b.actions("Reports", a -> { a.action("createDrafts").label("Create draft reports").icon("file-plus") .handler(ctx -> { reports.createDrafts(); return ActionResult.refresh(ActionToast.success("Drafts created")); }); a.action("postPending").label("Post pending drafts").icon("send") .handler(ctx -> { reports.postPending(); return ActionResult.toast(ActionToast.success("Posted")); }); });A button's server handler runs only for an authenticated user. Because a page action has no entity to gate on, declare
.roles("MANAGER")to restrict who may run (and see) it; without roles, any authenticated user may run it and the handler enforces its own finer authorization viactx.user(). -
custom
Add adiv-customextension block (chart, kanban, ...). -
aside
Compose a right rail beside the main content — a narrow side column for stats, filters, or a summary that sits next to a list rather than stacked above it. The rail takes the same block DSL as the page itself (widget,text,constants,custom), so you can drop stat tiles to the right of a list surface:b.list(Order.class); // main b.aside(a -> { a.widget("Open").type("count").document(Order.class).config("filter", "open = true"); a.widget("Revenue").type("metric").document(Order.class).config("metric", "sum")...; });Desktop lays the rail out to the right of the main content (which flexes to fill the rest); mobile stacks it below. Repeated calls extend the same rail. Widgets in the rail always stack one-per-row (it is a narrow column). A nested
aside(...)inside the rail is ignored. -
row
Add a multi-column layout band — the general layout primitive. Split the page into columns of any width and compose any block in each; nest further rows inside a column for arbitrary structure. Columns lay out side by side on desktop and stack on mobile.b.row(r -> { r.col("2/3", c -> c.list(Order.class)); // main r.col("1/3", c -> { // side c.widget("Open").type("count").document(Order.class).config("filter", "open = true"); c.widget("Revenue").type("metric").document(Order.class) .config("metric", "sum").config("metricField", "total"); }); });Rows render after the page's own widget grid and freeform blocks, in the order added. A column is itself a full
PageBuilder, so it takes every block method (and furtherrow(...)calls). -
list
Embed the full interactive list of a catalog/document — the same surface as its own route, with the New button, custom action buttons, search/sort and rows that open a detail beside the page. Lets a page (e.g. Settings) manage reference data inline.entityis the catalog or document class. -
list
Embed an entity list opened on a default view — preset filter selections, grouping, sorting, and/or a base feed constraint. The viewer can still change the selected filters, grouping, and sort; onlyPageBuilder.ListDefaults.filter(String)is a permanent feed constraint. Reuses the samecol op valuefilter grammar as dashboard widgets:b.list(Order.class, v -> v.filter("open = true") .defaultFirstFilterOption("assignedTo") .groupBy("created_at", DateGranularity.DAY) .sort("_date", true)); // newest first -
title
-
subtitle
-
showHeader
public boolean showHeader()Whether the renderer should emit the header row (title/subtitle). -
aside
The right-rail sub-builder, ornullif the page composed noaside(...). -
rows
The explicit layout rows composed withrow(...), in declaration order. -
widgets
-
components
-
pageActions
The page's action-button handlers, in declaration order (resolved by key on post-back). -
pageAction
The page action with this key, ornullif the page declares none.
-