MailglassAdmin.Operator.Shell (MailglassAdmin v2.3.0)

Copy Markdown View Source

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 same OptionalDeps.MailglassInbound gate the router uses to decide whether to emit the /inbound route), 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

dark_chrome?(params, cookie \\ nil)

True when the resolved theme selection is dark.

inbound_available?()

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.

orientation_strip(assigns)

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.

set_theme_path(uri, theme)

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.

shell(assigns)

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 to nil.
  • overview_path (:string) (required)
  • deliveries_path (:string) (required)
  • inbound_path (:string) (required)
  • inbound_available? (:boolean) - Defaults to false.
  • dark_chrome (:boolean) - Defaults to false.
  • theme_choice (:atom) - Defaults to :system. Must be one of :system, :light, or :dark.
  • title (:string) (required)
  • subtitle (:string) - Defaults to nil.
  • flash (:map) - Defaults to %{}.

Slots

  • inner_block (required)

surface_paths(base_path, active, dark_chrome, tenant_id \\ nil)

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.

tenant_selector(assigns)

Attributes

  • state (:atom) (required) - Must be one of :select_required, or :none.
  • tenant_options (:list) - Defaults to [].
  • current_uri (:string) (required)

tenant_switch_path(uri, tenant_id)

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.

theme_choice(params, cookie \\ nil)

Resolves the shell's three-choice picker state from the persisted preference cookie. URL ?theme= is legacy input and is normalized before rendering.

toggle_theme_path(uri, currently_dark?)

Builds the push_patch target for the theme toggle: flips the theme param on the CURRENT url, preserving every other filter/selection param.