Governed operator lists (organizations, grants, people, billing×4) gain
server-side search, status filters, and 50-row pages with true totals
from count(*) OVER(); state is URL-addressable, out-of-range pages
clamp,
and no-match is distinct from true-empty.
People is the eighth flat sidebar entry: /operator/persons lists persons
newest-joined first (excluding the reserved system person), rows linking
to the existing detail.
Billing gains an operator invoice detail at
/operator/billing/invoices/{invoiceID} reusing the member projection;
open invoices past due present as Overdue (derived, filterable, stored
status untouched); all four views lead with the linked organization and
mute object IDs.
Grants filter over the derived Live/Superseded/Inactive state, the SQL
HAVING predicate pinned to the Go derivation by test. Embedded lists
(org composite ledger, Tier changes) adopt the shared controls under
namespaced params with sibling-state-preserving URLs and scoped htmx
swaps that hold the viewport.
Review corrections: blocked ladder Delete renders disabled with tooltip
and mutations fire toasts; collapse triggers paint their open state;
sections use outside headings; plan topology drops the orphan-product
check; domains policy collapses behind a disclosure.
38 lines
2.1 KiB
HTML
38 lines
2.1 KiB
HTML
{{/* operator_billing.html
|
|
MPA wrapper for the four billing sub-views. Dispatched from
|
|
/operator/billing/{accounts,subscriptions,invoices,payments} by
|
|
GetBillingXPage handlers in operator_pages.go. The section navigates
|
|
itself: the pill row below is the four views' navigation
|
|
(operator-billing-views: "Billing views are navigated in-page";
|
|
maintainer 2026-08-23 — the sidebar holds one flat Billing entry, no
|
|
children). .ActiveSection drives both the active pill and the page's
|
|
IAPosition (operator_pages.go). The wrapper also carries the shared
|
|
recency stamp and Stripe Sync legend, then delegates to
|
|
.InnerTemplate / .InnerData via renderBody (template func registered
|
|
in NewOperatorPartialsHandler).
|
|
*/}}
|
|
<h1 class="h2 mb-3">Billing</h1>
|
|
|
|
<ul class="nav nav-pills mb-3">
|
|
<li class="nav-item"><a class="nav-link {{ if eq .ActiveSection "accounts" }}active{{ end }}" href="{{ routeURL "/operator/billing/accounts" }}">Accounts</a></li>
|
|
<li class="nav-item"><a class="nav-link {{ if eq .ActiveSection "subscriptions" }}active{{ end }}" href="{{ routeURL "/operator/billing/subscriptions" }}">Subscriptions</a></li>
|
|
<li class="nav-item"><a class="nav-link {{ if eq .ActiveSection "invoices" }}active{{ end }}" href="{{ routeURL "/operator/billing/invoices" }}">Invoices</a></li>
|
|
<li class="nav-item"><a class="nav-link {{ if eq .ActiveSection "payments" }}active{{ end }}" href="{{ routeURL "/operator/billing/payments" }}">Payments</a></li>
|
|
</ul>
|
|
|
|
{{/* Projection recency, trimmed to the fact (maintainer 2026-08-23: the
|
|
projection mechanics were obvious and removable). The Stripe Sync
|
|
legend that used to sit here as an always-on banner now lives as a
|
|
help-icon tooltip on each view's "Stripe Sync" column header
|
|
(operator-billing-views: "Stripe sync vocabulary is defined where it
|
|
appears", revised to the dense-surface tooltip pattern). */}}
|
|
<p class="text-muted small mb-3">
|
|
{{ if .NoEventsProcessed }}
|
|
No billing events have been received yet.
|
|
{{ else }}
|
|
Last updated at {{ .DataAsOf }}.
|
|
{{ end }}
|
|
</p>
|
|
|
|
{{ renderBody .InnerTemplate .InnerData }}
|