MailglassAdmin.Components (MailglassAdmin v1.5.0)

Copy Markdown View Source

Brand-book-aligned shared UI atoms used throughout mailglass_admin.

Components

  • icon/1 — Heroicon via the vendored heroicons.js Tailwind plugin (Phoenix 1.8 installer convention). Classes matching the pattern hero-<name> are resolved at build time into inline SVG.
  • logo/1 — mailglass wordmark served from priv/static/mailglass-logo.svg via MailglassAdmin.Controllers.Assets.
  • flash/1 — toast-style flash message for LiveReload + success notifications. Brand-voice: no "Oops!", no "Uh oh!"; specific and composed per brand book §5.
  • badge/1 — sidebar status badge with two variants: :warning (preview_props/0 raised) and :stub (no preview_props defined).

Brand voice enforcement

Copy throughout these atoms follows the 05-UI-SPEC Copywriting Contract: clear, exact, confident, warm, technical — "a thoughtful maintainer." Banned phrases ("Oops", "Whoops", "Uh oh", "Something went wrong") never appear in this module; the voice test greps the rendered HTML to enforce the floor.

Boundary classification: submodule auto-classifies into the MailglassAdmin root boundary declared in lib/mailglass_admin.ex; classify_to: is reserved for mix tasks and protocol implementations and is not used here.

Summary

Functions

Sidebar status badge. Two variants

Renders a brand-voice flash message in a daisyUI toast wrapper.

Renders a Heroicon via the vendored heroicons.js Tailwind plugin.

Renders the mailglass logo. The src is relative so the browser resolves it against the current document URL — the logo is served by MailglassAdmin.Controllers.Assets at <mount>/logo.svg.

Masks the local/domain halves of an already-split email address. Public so the inbound components can mask address-shaped values that are pre-split.

Masks a recipient email for operator display (PII minimization, the design contract).

Masks a single value: keeps the first grapheme, stars the rest. Public so other admin surfaces reuse the one masking primitive rather than reinventing it.

Normalizes inbound @outcomes singular atoms to the canonical past-tense atoms expected by status_badge/1. The mailglass_inbound @outcomes schema (locked 1.0 contract) is never modified; normalization is admin-side only.

Unified delivery, inbound, and timeline status badge. Renders an outline Heroicon (decorative, aria-hidden) and a text label inside a daisyUI badge container.

Functions

badge(assigns)

(since 0.1.0)

Sidebar status badge. Two variants:

  • :warning — preview_props/0 raised; shows an exclamation-triangle Heroicon + the literal copy "Error" (per 05-UI-SPEC Badge section).
  • :stub — mailable has no preview_props/0 defined; shows the "—" glyph in Slate (secondary) color.

Attributes

  • variant (:atom) (required) - Must be one of :warning, or :stub.

flash(assigns)

(since 0.1.0)

Renders a brand-voice flash message in a daisyUI toast wrapper.

Used for LiveReload notifications ("Reloaded: {file}") and other transient signals. Includes role="status" + aria-live="polite" per the 05-UI-SPEC Accessibility Interactions contract.

Attributes

  • kind (:atom) - Defaults to :info. Must be one of :info, :success, :warning, or :error.
  • message (:string) (required)

icon(assigns)

(since 0.1.0)

Renders a Heroicon via the vendored heroicons.js Tailwind plugin.

The plugin resolves classes matching hero-<name> into inline SVG at build time. Usage: <.icon name="hero-envelope" class="w-5 h-5" />.

Attributes

  • name (:string) (required)
  • class (:any) - Defaults to nil.

logo(assigns)

(since 0.1.0)

Renders the mailglass logo. The src is relative so the browser resolves it against the current document URL — the logo is served by MailglassAdmin.Controllers.Assets at <mount>/logo.svg.

Attributes

  • class (:any) - Defaults to nil.

mask_email(local, domain)

(since 0.2.0)
@spec mask_email(String.t(), String.t()) :: String.t()

Masks the local/domain halves of an already-split email address. Public so the inbound components can mask address-shaped values that are pre-split.

mask_recipient(recipient)

(since 0.2.0)
@spec mask_recipient(String.t() | nil) :: String.t()

Masks a recipient email for operator display (PII minimization, the design contract).

The ONE audited masking definition in the admin package: both MailglassAdmin.Operator.DeliveriesList (outbound) and the this milestone phase inbound components call this so there is never a second, drifting copy. Keeps the first grapheme of each segment and stars the rest, preserving the email shape:

mask_recipient("alice@example.com") #=> "a****@e******.com"
mask_recipient(nil)                 #=> "Unavailable"

mask_value(value)

(since 0.2.0)
@spec mask_value(String.t()) :: String.t()

Masks a single value: keeps the first grapheme, stars the rest. Public so other admin surfaces reuse the one masking primitive rather than reinventing it.

normalize_inbound_outcome(atom)

(since 1.5.0)
@spec normalize_inbound_outcome(atom() | nil) :: atom() | nil

Normalizes inbound @outcomes singular atoms to the canonical past-tense atoms expected by status_badge/1. The mailglass_inbound @outcomes schema (locked 1.0 contract) is never modified; normalization is admin-side only.

Maps: :accept:accepted, :reject:rejected, :bounce:bounced. All other atoms (including nil) pass through unchanged.

status_badge(assigns)

(since 1.5.0)

Unified delivery, inbound, and timeline status badge. Renders an outline Heroicon (decorative, aria-hidden) and a text label inside a daisyUI badge container.

The base badge class is always emitted by this component — call sites must NOT prepend 'badge' or 'badge badge-sm'. Use size: :sm (default) for list rows; size: :md for detail headers.

Attributes

  • status (:atom) (required) - Must be one of :dispatched, :queued, :sent, :delivered, :deferred, :bounced, :failed, :rejected, :complained, :unsubscribed, :opened, :clicked, :autoresponded, :unknown, :accepted, :no_match, :ignore, :failed_ingest, :webhook_replay_requested, :webhook_replay_succeeded, :webhook_replay_failed, or :reconciled.
  • size (:atom) - Defaults to :sm. Must be one of :sm, or :md.