Files
mxaccessgw/docs/DashboardInterfaceDesign.md
Joseph Doherty e80f3c70b6 docs: cover admin dashboard actions + API key Delete
Update the design docs so they match the implemented Admin-only
dashboard surface. GatewayDashboardDesign now documents the Close
session / Kill worker controls and the new Delete action on revoked
API keys, plus the ConfirmDialog gate for every destructive action.
Sessions.md adds the SessionManager.KillWorkerAsync entry alongside
CloseSessionAsync and explains the immediate-kill semantics. Authentication.md adds the IApiKeyAdminStore.DeleteAsync write path
and the dashboard-delete-key audit event. DashboardInterfaceDesign
drops the "read-only until admin workflows have a separate design"
line in favor of the confirm-before-act invariant.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 07:35:25 -04:00

10 KiB

Dashboard Interface Design

This guide describes the visual and interaction patterns used by the MXAccess Gateway dashboard so the same interface style can be reused in other operations-focused projects.

Design Goal

The dashboard is an operational interface, not a landing page. It prioritizes fast scanning, low visual noise, and stable layouts while live data changes. The design uses Bootstrap for common behavior and a small local stylesheet for project identity, spacing, and status presentation.

Use this style for applications where users repeatedly check system state, compare rows, inspect details, and diagnose faults. Avoid promotional layouts, large hero areas, decorative imagery, or oversized cards that reduce data density.

Visual Language

The interface uses a quiet, work-focused visual system:

  • A light gray page background separates the application shell from white data surfaces.
  • White cards and sections carry the actual operational content.
  • Borders define structure more often than shadows.
  • Accent color is reserved for metric values and important numeric signals.
  • Bootstrap status badges provide state color without custom status art.
  • Tables remain compact and responsive so long identifiers and timestamps stay readable.

The resulting page should look like a control surface: restrained, predictable, and dense enough for repeated use.

Layout Structure

Every page follows the same structure:

  1. A top navigation bar with the product or service name on the left.
  2. A full-width container-fluid content area.
  3. A page header with the page title, short context text, and optional status badge.
  4. Metric cards when a page has top-level numeric state.
  5. Bordered content sections for tables, details, faults, or empty states.

The shell does not use a sidebar. A horizontal navigation bar is enough for the current page count and keeps the content width available for tables.

<div class="dashboard-shell">
  <nav class="navbar navbar-expand-lg bg-body border-bottom dashboard-navbar">
    <!-- brand, page links, sign-out action -->
  </nav>
  <main class="container-fluid dashboard-content">
    <!-- page header, metric grid, sections -->
  </main>
</div>

Color Tokens

Use a small token set and let Bootstrap provide the rest. The current dashboard uses these local tokens:

:root {
  --mxgw-surface: #f7f8fa;
  --mxgw-border: #d8dee6;
  --mxgw-ink-muted: #667085;
  --mxgw-accent: #146c64;
}
Token Purpose
--mxgw-surface Page background behind all content.
--mxgw-border Borders on cards, tables, sections, and empty states.
--mxgw-ink-muted Secondary labels, details, and empty-state text.
--mxgw-accent Metric values and important numeric summaries.

Keep the palette small. Add new colors only when they encode state or improve readability. Prefer Bootstrap badge classes for states such as ready, closing, closed, and faulted.

Typography

Typography stays compact and consistent:

  • Page headings use 1.35rem, weight 650, and normal letter spacing.
  • Section headings use the same size as page headings when they introduce a table or details group.
  • Metric labels use uppercase text at .78rem and weight 650.
  • Metric values use 1.7rem, weight 700, and the accent color.
  • Body and table text inherit Bootstrap defaults for readability.

Do not scale text with viewport width. Long values use overflow-wrap: anywhere so session IDs, paths, and fault messages do not break the layout.

Spacing And Shape

The dashboard uses modest spacing:

  • Page content has 1.25rem padding on desktop and .75rem on small screens.
  • Metric grids use .75rem gaps.
  • Content sections start with a top border and 1rem top padding.
  • Cards and empty states use Bootstrap's small radius shape, .375rem.
  • Metric cards have no shadow.

This keeps information grouped without turning each section into a decorative panel. Use cards for repeated metric summaries, login forms, and individual items. Use unframed sections with a top border for page-level groups.

Navigation

Navigation is a Bootstrap responsive navbar. It includes:

  • Brand text for the service name.
  • Short page labels: Overview, Sessions, Workers, Events, Settings.
  • Active route styling through NavLink.
  • A right-aligned sign-out button when authentication is enabled.

Keep navigation labels short. Operational users should be able to predict what each page contains without reading explanatory copy.

Page Headers

Each page starts with a dashboard-page-header:

  • The title is the primary anchor.
  • A single secondary line gives timestamp, row count, or configuration context.
  • A status badge appears on the right when the page has an overall state.

On narrow screens, the header stacks vertically. This prevents long context text or status badges from overlapping the title.

<div class="dashboard-page-header">
  <div>
    <h1>Overview</h1>
    <div class="text-secondary">Generated 2026-04-27 17:30:00</div>
  </div>
  <span class="badge text-bg-success">Healthy</span>
</div>

Metric Cards

Metric cards summarize numeric state at the top of overview and diagnostic pages. They use Bootstrap cards with a local metric-card class:

  • Label: uppercase, muted, compact.
  • Value: large enough to scan, accent colored, wraps safely.
  • Detail: optional muted text for version, rate context, or explanatory state.

Use auto-fit CSS grid tracks so the cards fill available width without custom breakpoints:

.metric-grid {
  display: grid;
  gap: .75rem;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
}

.metric-grid.compact {
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
}

Metrics should be formatted before rendering. Counts use thousands separators, durations use stable units, and missing values render as -.

Tables

Tables are the main information surface. Use Bootstrap table table-sm with a local dashboard-table class:

  • table-sm keeps rows dense.
  • align-middle improves status badge alignment.
  • table-responsive wraps every table that can exceed the viewport.
  • Header cells use weight 650 and no wrapping.
  • Body cells allow wrapping so identifiers, paths, and messages stay visible.
  • Detail tables reserve a fixed header width.

Use code formatting for machine identifiers such as session IDs, file paths, and protocol values. Link rows only where navigation is useful; avoid making entire rows clickable when a single identifier link is clearer.

Status Badges

Status uses Bootstrap badge classes with a small mapping layer:

State Badge class
Ready, Healthy text-bg-success
Creating, StartingWorker, WaitingForPipe, InitializingWorker, Closing text-bg-info
Closed text-bg-secondary
Faulted text-bg-danger
Unknown state text-bg-light text-dark border

Keep status text literal. Operators benefit from seeing the same state names that appear in logs and APIs.

Empty And Loading States

Empty states are explicit and quiet. They use a white background, dashed border, small radius, muted text, and one sentence:

<div class="empty-state">No worker processes are attached.</div>

Loading states use the same component shape. Avoid spinners for snapshot pages that update on a timer; a stable text placeholder is less distracting.

Detail Pages

Detail pages use stacked sections instead of nested cards:

  • The page header identifies the selected entity.
  • The first section shows entity metadata in a two-column details table.
  • Additional sections show related runtime state, such as worker metadata.
  • Missing entities render a single section with a concise not-found message.

This structure keeps details comparable across pages and avoids card nesting.

Responsive Behavior

The dashboard uses one small-screen breakpoint:

@media (max-width: 700px) {
  .dashboard-content {
    padding: .75rem;
  }

  .dashboard-page-header {
    align-items: flex-start;
    flex-direction: column;
  }

  .details-table th {
    width: 9rem;
  }
}

Do not hide important columns by default. Use horizontal table scrolling for dense operational data, and reserve column hiding for data that is clearly duplicative.

Data Formatting

Use a small display helper instead of formatting inline in every component. The helper should provide consistent rendering for:

  • empty text as -,
  • counts with thousands separators,
  • dates and times in a consistent local or configured format,
  • durations in stable units,
  • metric lookup by name and dimension.

Centralizing formatting prevents visual drift between overview cards, tables, and detail pages.

Security And Redaction

The interface is read-only unless an explicit administrative action is designed. It should not display secrets or raw credential-bearing values.

Apply redaction before values reach Razor components. The UI treats redacted values as normal display text; it does not need to know why a value is hidden. This keeps security policy in the dashboard projection layer rather than in markup.

Replication Checklist

Use this checklist when applying the design to another project:

  • Define four local tokens: surface, border, muted ink, and accent.
  • Use a Bootstrap top navbar with short route labels.
  • Keep page content inside a full-width fluid container.
  • Start every page with the same header structure.
  • Put primary numeric state in metric-grid cards.
  • Put detailed runtime state in compact responsive tables.
  • Use status badges mapped from real domain states.
  • Use dashed bordered empty states for loading and no-data cases.
  • Use top-bordered sections for page groups instead of nested cards.
  • Centralize formatting and redaction outside Razor markup.
  • Hide every destructive admin affordance from viewers; render it only for the Admin role and re-check the role server-side on every invocation.
  • Route every destructive action (Close session, Kill worker, Rotate / Revoke / Delete API key) through the shared ConfirmDialog component so the operator always gets one explicit confirmation step before the call reaches the service.