Files
design-system/docs/superpowers/specs/2026-03-18-admin-redesign.md
hsiegeln 4526d4c7ef docs: add admin section redesign spec
Based on 3-expert UX/UI review: fixes critical --bg-base bug,
migrates AuditLog to DataTable, replaces admin nav with Tabs,
reworks user creation with provider-aware flow, adds password
management, toast feedback, and accessibility improvements.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 23:33:37 +01:00

8.1 KiB

Admin Section Redesign Spec

Date: 2026-03-18 Scope: UX/UI consistency overhaul of AuditLog, OidcConfig, UserManagement admin pages

Overview

Three expert reviews identified critical bugs, consistency gaps, and usability issues in the admin section. This spec covers all changes organized by priority tier.


Tier 1: Critical Bugs

1.1 Replace nonexistent --bg-base token

--bg-base is referenced 3 times but does not exist in tokens.css. Dark mode is broken.

Files:

  • Admin.module.css line 6: .adminNav
  • UserManagement.module.css lines 13, 19: .listPane, .detailPane

Fix: Replace all var(--bg-base) with var(--bg-surface).

1.2 Change AuditEvent id to string

DataTable requires T extends { id: string }. Current AuditEvent.id is number.

Files:

  • auditMocks.ts: change id: number to id: string, update all IDs to 'audit-1', 'audit-2', etc.
  • AuditLog.tsx: update expandedId state from number | null to string | null

Tier 2: High-Impact Consistency

2.1 Replace admin nav with Tabs composite

The hand-rolled admin nav in Admin.tsx lacks ARIA roles and has subtle color differences from the Tabs composite.

Fix: Replace the custom <nav> block with:

<Tabs
  tabs={[
    { label: 'User Management', value: '/admin/rbac' },
    { label: 'Audit Log', value: '/admin/audit' },
    { label: 'OIDC', value: '/admin/oidc' },
  ]}
  active={location.pathname}
  onChange={(path) => navigate(path)}
/>

Delete .adminNav, .adminTab, .adminTabActive from Admin.module.css.

2.2 Remove duplicate page titles

Breadcrumb + active tab + h2 heading all show the same label. Remove the h2.

Files:

  • AuditLog.tsx: remove the .header div with <h2>Audit Log</h2>. Move the event count badge into a toolbar row.
  • OidcConfig.tsx: remove the .header div with <h2>. Keep Save/Test buttons in a compact toolbar row below the tabs.

Delete .header, .title CSS from both AuditLog.module.css and OidcConfig.module.css.

2.3 Migrate AuditLog to DataTable

Replace the hand-built <table> with the DataTable composite.

Column definitions:

  • Timestamp: render with MonoText, width '170px'
  • User: render with bold text
  • Category: render with Badge color="auto"
  • Action: plain text
  • Target: render with ellipsis style
  • Result: render with Badge color={row.result === 'SUCCESS' ? 'success' : 'error'}

Features to enable:

  • sortable on Timestamp, User, Category, Result columns
  • rowAccent={(row) => row.result === 'FAILURE' ? 'error' : undefined} — red left-border on failures
  • expandedContent={(row) => <detail block with IP, user agent, CodeBlock>}
  • pageSize={10}
  • flush prop (table sits inside a card wrapper)

Card wrapper: Wrap DataTable in a section with background: var(--bg-surface), border: 1px solid var(--border-subtle), border-radius: var(--radius-lg), box-shadow: var(--shadow-card). Add a header row with title + event count badge, matching Dashboard's .tableSection pattern.

Delete from AuditLog.module.css: .tableWrap, .table, .th, .row, .td, .userCell, .target, .empty, .detailRow, .detailCell, .detailGrid, .detailField, .detailLabel, .detailValue, .detailJson. Also remove the separate Pagination import — DataTable handles pagination internally.

2.4 Fix content padding

Admin.module.css .adminContent: change padding: 20px to padding: 20px 24px 40px.

2.5 Center OIDC form

OidcConfig.module.css .page: add margin: 0 auto to center the 640px max-width form.

2.6 Replace inline style

UserManagement.tsx line 20: replace style={{ marginTop: 16 }} with a CSS class .tabContent { margin-top: 16px; } in UserManagement.module.css.


Tier 3: Usability Improvements

3.1 Add toast notifications to RBAC mutations

Import useToast into UsersTab.tsx, GroupsTab.tsx, RolesTab.tsx. Fire toasts on:

  • Create user/group/role: variant: 'success'
  • Delete user/group/role: variant: 'warning'
  • Role assigned/removed: variant: 'success'
  • Group added/removed: variant: 'success'

3.2 Rework user creation form

Replace the flat inline form with a provider-aware two-step form.

Form structure:

  1. Provider selection — RadioGroup with "Local" and "OIDC" options. Default: "Local".
  2. Fields (always shown): Username (required), Display name (optional), Email (optional)
  3. Fields (Local only): Password (required)
  4. OIDC info callout: When OIDC selected, show an InfoCallout: "OIDC users authenticate via the configured identity provider. Pre-register to assign roles/groups before their first login."

Components used: RadioGroup + RadioItem (existing primitive), Input, InfoCallout (existing primitive), Button.

Create handler: Set provider based on RadioGroup selection. Only validate password when provider is 'local'.

The form should use the existing inline pattern (appears at the top of the list pane), but use a proper card-like treatment (the existing .createForm background is fine).

3.3 Add password management to user detail pane

Add a "Security" section (using SectionHeader) in the user detail pane, below the metadata grid.

For local users:

  • Show "Password: ••••••••" with a "Reset password" Button
  • Clicking "Reset password" reveals an inline form: Input (type=password, placeholder "New password") + Cancel/Set buttons
  • Setting fires a success toast: "Password updated"

For OIDC users:

  • Show "Authentication: OIDC ({provider})"
  • Show InfoCallout: "Password managed by the identity provider."
  • No password reset option

3.4 Add ConfirmDialog to cascading removals

When removing a group from a user (which may strip inherited roles), show a confirmation dialog if the group grants roles.

When removing a role from a group (which affects all members), show a confirmation dialog.

Direct role removal from a user does not need confirmation (low risk).

3.5 Make entity list items keyboard accessible

Add to each .entityItem div:

  • role="option"
  • tabIndex={0}
  • aria-selected={selectedId === item.id}
  • onKeyDown: Enter/Space to select, ArrowUp/ArrowDown to navigate

Add role="listbox" and aria-label to each .entityList container.

3.6 Add expand/collapse affordance to AuditLog

After DataTable migration (2.3), add a first column with a chevron indicator (> / v) that rotates when the row is expanded. Width: '40px'. This makes the expandable row pattern discoverable.

3.7 Add duplicate name validation

Before creating, check for existing names:

  • Users: users.some(u => u.username === newUsername.trim())
  • Groups: groups.some(g => g.name.toLowerCase() === newName.trim().toLowerCase())
  • Roles: roles.some(r => r.name === newName.trim().toUpperCase())

Show inline error using state + red text below the name field. Disable Create button.

3.8 Partial FilterBar migration for AuditLog

After DataTable migration, use FilterBar for search + category filters:

  • Search input maps to FilterBar's built-in search
  • Categories (INFRA, AUTH, USER_MGMT, CONFIG) become FilterPill toggles
  • Keep DateRangePicker and user filter Input alongside FilterBar in a row

3.9 Add empty-search states to entity lists

When search returns no results in Users/Groups/Roles lists, show centered muted text: "No users match your search" (etc.) inside the .entityList area.


Tier 4: Polish

4.1 Replace lock emoji with Badge

RolesTab.tsx: replace 🔒 with <Badge label="system" color="auto" variant="outlined" />.

4.2 Fix split-pane border radius

UserManagement.module.css: change border-radius: var(--radius-md) to var(--radius-lg) on .splitPane, .listPane, .detailPane.

4.3 Add shadow to split-pane

UserManagement.module.css: add box-shadow: var(--shadow-card) to .splitPane.


Out of Scope

  • Replacing split-pane with DataTable+DetailPanel (not appropriate for dense editing)
  • EventFeed as alternative audit view (future enhancement)
  • Tabs inside user detail pane (not needed until more sections are added)
  • FilterBar extension to support DateRangePicker slots (separate design system ticket)