Product
Category
Stock
Price
The rules — the tabbed-data page
- The tab shell is the tabs standard unchanged: pills in the card header, panes as plain card-body content. Putting a lister or a form in a pane changes NOTHING about how it is built — this page exists to show exactly that.
- A pane with a full data list is the data-list composition unchanged: toolbar with the panel toggle left and the ONE
.btn-primaryright, filters in the collapsiblelister-panel— search on top, then the filter fields, thenhr, then order + page size, Reset up top. SAME filters, SAME search button everywhere — every tabbed list in an app reads identically. - The minimal variant is the compact composition: search + order in the toolbar, the optional header row, no panel — for panes where the list IS the whole story and a filter panel would be noise.
- Several synced listers, one page: give each its own
urlPrefix(u-/p-here — the prefix is concatenated literally:u-page,p-search) so URL sync never collides. The OPEN TAB itself stays un-synced — the tabs standard: a tab that must deep-link wants to be a page. - Hidden tabs never fetch: a lister outside the active pane gets
autoload: false(here: thelister-autoloadattribute) and loads ONCE on its tab’s firstshown.bs.tab— data the user never opens is never requested. - Side info about the list — pending invitations, hidden-row counts, totals — goes in the lister’s NOTICE STRIP:
[lister-notice]above the rows, a.lister-notice-label+.lister-notice-chipvalues, filled fromlister:loaded. The extras ride the SAME payload as the rows (atypical payloads — never a second fetch), and:emptymeans the strip does not exist — nothing to show needs no page logic. When the info is something AWAITING the user (the pending invitations here), the tab may carry the.badge-countpill from the same payload — the tab-pill law. Page errors/warnings are NOT notices: they stay alerts above the lister. - Form panes follow the settings standard: each pane is its OWN form with its OWN submit — one giant form across tabs stays forbidden. In a real app each form rides former.
- Everything else comes straight from the source patterns when a tabbed list needs it: bulk selection from the data-list page, create/edit in the offcanvas on former (shown here), delete through
g.confirm(shown here).