{% extends "brickwork/shell/app.html" %} {% comment %} A dense purchase-order / shipment index: many rows, sticky headers, bulk actions over a selection. COPY THIS FILE into your project and edit it. It is not on the template loader path, so you cannot extend it (ADR-056). What your view must supply: po_columns / po_rows the table's columns and pre-rendered rows po_page a page of items (a Django Page from Paginator) filter_form your own filter form (the bar renders its fields) nav_items / nav_active as in app/list.html The counts, headings and copy below are typed into the template, which is where you change them. A dense list is a list whose rows are WORK IN MOTION, not a soft archive: purchase orders waiting to ship, shipments waiting to clear customs, lines somebody still owes an answer on. Density is the point: sticky headers keep column labels in view while the reader scrolls a long page, and selectable rows feed one shared bulk form so "Mark shipped" and "Hold" act on the same checkboxes the table renders. On status: build each status cell as a rendered {% templatetag openblock %} bw_badge {% templatetag closeblock %} in your view, so the state reaches the reader as a word ("Awaiting stock", "In transit", "Cleared") and not as a colour. The badge variants (neutral, info, success, warning, danger) tint that word; they never replace it. The bulk actions bar and the table share ONE form, so the checkboxes the table renders are the inputs the bar's buttons submit. Read them server-side with request.POST.getlist("selected"). The live "n selected" count is an Alpine enhancement; with JavaScript off the bar still submits the checked rows. States: the table's loading/empty/row-link/selected states and its sortable-column ascending/descending/unsorted states (see _data_table.html's own header); pagination rendered/absent (a single page renders no controls); the bulk bar's own empty/populated selection count, which is populated by Alpine and empty without it. Accessibility: inherits shell/app.html's skip link, sidebar/drawer nav and page-header region; every status reading is a badge whose label carries the meaning in words, never colour alone, and each row's checkbox carries a visually-hidden label naming its row. Covered by the archetype harness's full gate sweep (render, axe WCAG 2.2 AA, no horizontal overflow, light/dark distinctness, skip-link first-tab-stop with JS disabled) at every W0.1 breakpoint, both themes. Responsive: no breakpoint switch of its own; inherits shell/app.html's sidebar-to-drawer collapse at --bw-breakpoint-md (48rem). The optional stat row (bw-stat-grid) reflows continuously with an auto-fit grid; the composed table carries unconditional horizontal scroll (responsive="scroll", the default) at every width. {% endcomment %} {% load brickwork_components brickwork_interactions brickwork_nav %} {% block page_title %}Purchase orders - Northwind{% endblock %} {% block sidebar %}{% bw_nav nav_items nav_active %}{% endblock %} {% block sidebar_mobile %}{% bw_nav nav_items nav_active %}{% endblock %} {% block brand_wordmark %}Northwind{% endblock %} {% block page_header %} {% include "brickwork/components/_page_header.html" with title="Purchase orders" description="Open POs and outbound shipments. Oldest promised date first, so nothing misses a sailing unseen." %} {% endblock %} {% block page_actions %} {% bw_button "Export CSV" variant="secondary" icon="download" href="/purchase-orders/export/" %} {% bw_button "New purchase order" variant="primary" icon="plus" href="/purchase-orders/new/" %} {% endblock %} {% block content %}