Shared application shell for operator surfaces — the chrome wrapping both
MailglassAdmin.OperatorLive (overview/deliveries) and MailglassAdmin.InboundLive
(inbound records). The operator screens mount in the SAME operator live_session
(one Operator.Mount + Auth gate). Preview can appear as a configured sibling
nav link, but it remains a separate route/live-session boundary.
Provides:
- a shared topbar plus persistent sidebar that navigates BETWEEN surfaces
(Health / Preview / Deliveries / Inbound) — navigation, not filtering.
The Inbound item is conditionally
omitted via
inbound_available?(the sameOptionalDeps.MailglassInboundgate the router uses to decide whether to emit the/inboundroute), so an operator without the inbound package never sees a dead link. - a shell-owned theme picker. Theme persists as an admin preference cookie, so Deliveries↔Inbound navigation and refreshes keep the same chrome without adding app preference state to URLs.
Nav links reset to each surface's base path (no delivery_id/inbound_id,
no stale filters): switching surfaces is a fresh question, and inheriting a
selected id across surfaces is the classic sidebar-nav footgun.
This is internal UI — not part of the stable router/auth contract.
Summary
Functions
True when the resolved theme selection is dark.
Whether the inbound surface is present — the SAME gate the router uses to
decide whether to emit the /inbound route. Centralized here so the nav and
the route never disagree.
Renders the orientation strip for an operator surface — a persistent, symptom-first guidance panel that appears when no record is selected. Each surface has frozen per-surface copy keyed on the most common operator questions for that surface.
Builds the target for setting the theme picker value through the HTTP
persistence seam while preserving unrelated query params in return_to.
Renders the operator shell around a surface's body (passed as the inner block).
Derives the {deliveries, inbound} nav paths from a screen's base_path,
carrying only the shared ?tenant_id= scope across surfaces. active tells
us which surface we're on so we can recover the operator root (the inbound
screen's base_path has a trailing /inbound to strip).
Builds a same-surface tenant switch path from the current URL.
Resolves the shell's three-choice picker state from the persisted preference
cookie. URL ?theme= is legacy input and is normalized before rendering.
Builds the push_patch target for the theme toggle: flips the theme param on
the CURRENT url, preserving every other filter/selection param.
Functions
True when the resolved theme selection is dark.
Whether the inbound surface is present — the SAME gate the router uses to
decide whether to emit the /inbound route. Centralized here so the nav and
the route never disagree.
Renders the orientation strip for an operator surface — a persistent, symptom-first guidance panel that appears when no record is selected. Each surface has frozen per-surface copy keyed on the most common operator questions for that surface.
Placed after defp flash_region/1 as the last function component in the module.
No motion classes — born token-clean.
Attributes
surface(:atom) (required) - Must be one of:deliveries,:inbound, or:preview.
Builds the target for setting the theme picker value through the HTTP
persistence seam while preserving unrelated query params in return_to.
The system choice removes the explicit theme query key.
Renders the operator shell around a surface's body (passed as the inner block).
Attributes
active(:atom) (required) - Must be one of:overview,:deliveries, or:inbound.preview_path(:string) - Defaults tonil.overview_path(:string) (required)deliveries_path(:string) (required)inbound_path(:string) (required)inbound_available?(:boolean) - Defaults tofalse.dark_chrome(:boolean) - Defaults tofalse.theme_choice(:atom) - Defaults to:system. Must be one of:system,:light, or:dark.title(:string) (required)subtitle(:string) - Defaults tonil.flash(:map) - Defaults to%{}.
Slots
inner_block(required)
Derives the {deliveries, inbound} nav paths from a screen's base_path,
carrying only the shared ?tenant_id= scope across surfaces. active tells
us which surface we're on so we can recover the operator root (the inbound
screen's base_path has a trailing /inbound to strip).
Only tenant_id is carried across surfaces — it is the shared scoping
dimension. Surface-specific filters (delivery vs inbound status sets) are
intentionally left behind, since they don't translate between surfaces.
Attributes
state(:atom) (required) - Must be one of:select_required, or:none.tenant_options(:list) - Defaults to[].current_uri(:string) (required)
Builds a same-surface tenant switch path from the current URL.
Tenant switches preserve compatible filters and theme while dropping selected record ids that cannot safely carry across tenants.
Resolves the shell's three-choice picker state from the persisted preference
cookie. URL ?theme= is legacy input and is normalized before rendering.
Builds the push_patch target for the theme toggle: flips the theme param on
the CURRENT url, preserving every other filter/selection param.