Skip to main content

Phoenix UI Polish

The web UI got a consistent, responsive look and feel: a shared page layout, readable screens for dense operational work, accessible controls, clear feedback, toast notifications, mobile navigation, and saved light, dark, and colour palette preferences. The original plan is in the design record.

What changed for users​

Operators can work through the device, alert, report, script, and policy pages on desktop or phone. Focus, the current page, loading, errors, and dialogs are always clearly visible. Tabs, sortable columns, navigation, filters, and theme controls work from the keyboard and tell assistive technology which item is selected, sorted, current, or pressed.

How it fits in​

Shared layouts and core components define how controls look and behave, instead of each page styling itself. Every modal moves focus inside when it opens, keeps Tab within the dialog, and returns focus to the control that opened it when it closes. Irreversible deletes ask for confirmation in the shared confirm_modal dialog, which opens on Cancel; reversible actions use the browser's confirm prompt. Device and script tabs share the Tablist hook. Pages sit in ui-page-shell under a header title, and tables use the shared table component, whose sortable columns render sort_header buttons. The device list keeps its own table because its header cell holds the select-all checkbox; it still uses sort_header. The theme choice is handled in the browser, while LiveView keeps the state of each workflow on the server.

Running it​

The UI stays usable at narrow widths and when zoomed. Icons and other assets are bundled with the app, so nothing is loaded from a CDN at runtime.

Differences from the design​

The light and dark toggle grew into a choice of eleven colour palettes, offered in the sidebar and in Settings so small screens without the sidebar can reach them, each with light and dark modes: Coherent Current (the default), nine alternatives, and High Contrast. Each palette's primary colour matches its name, such as green for Mineral Glass and blue for Electric Fjord. Every palette meets WCAG AA contrast, and High Contrast targets AAA. Settings adds an optional highlight colour (teal, deep blue, cyan, green, amber, or magenta) that replaces the palette's primary and accent and passes AA on every palette; High Contrast ignores it. The palette and highlight lists live in NixstasisWeb.Theme, and each non-default palette or highlight overrides the theme tokens in assets/css/app.css. The Noto Sans font is bundled with the app like the icons.

Not included​

The UI is still Phoenix LiveView; there is no separate frontend application.

Tests​

  • packages/server/test/nixstasis_web/components/core_components_test.exs: how shared controls render and respond.
  • packages/server/test/nixstasis_web/controllers/layout_test.exs: the page layout.
  • packages/server/test/nixstasis_web/live/*_live_test.exs: responsive layouts and dialogs on each page.