ReviewOS

stacks/ts-cloud

dashboard: accessibility pass + stx hygiene (vanilla JS in templates)

#128
Closed glennmichael123 opened this 2 months ago ·
2 months ago

Accessibility

  • Repeated row buttons have no context — a screen reader hears "Remove, Remove, Remove". Needs aria-label="Remove async function name() { return (await authUser())?.name; }": server/services.stx:64-69 (6 labels × N rows), server/workers.stx:63, server/deployments.stx:104, server/ssh-keys.stx:82, server/team.stx:154, serverless/secrets.stx:92,93, serverless/alarms.stx:107, serverless/queues.stx:98, server/database.stx:112.
  • Confirm input has no accessible name — only placeholder="confirm": partials/op-confirm.stx:3 and the four hand-rolled bars.
  • <label> not associated with its control (no for, not wrapping): server/sites.stx:102-109,158-178, serverless/secrets.stx:118,122, serverless/alarms.stx:132,140, serverless/data.stx:79,83, serverless/functions.stx:151,159,163. The correct pattern already exists in server/team.stx:107, server/database.stx:76, server/firewall.stx:99.
  • No label at all: server/actions.stx:84, serverless.stx:276, server/terminal.stx:57.
  • No scope="col" on any <th> across ~15 tables.
  • No aria-live on streaming/result output (server/terminal.stx:55, every <pre class="action-output">). server/team.stx:131, server/firewall.stx:104, server/ssh-keys.stx:65 already use role="status" correctly.
  • No focus management when the confirm bar appears.

stx hygiene

CLAUDE.md states: "never write vanilla JS (var, document.*, window.*) in stx templates". Violations:

  • server/terminal.stx — document.getElementById('term-out') + manual scrollTop (:15), location.protocol/location.host (:20-21), raw new WebSocket (:21), module-scope mutable let ws = null (:13) outside the signal graph. Would suit a useWebSocket-style composable with scrolling driven by a directive.
  • server/sites.stx:30,54,74 — location.reload() as the state-update mechanism.
  • Raw setInterval in index.stx:133, server/logs.stx:30, serverless/logs.stx:27 (they do clean up on unmount, but the composable layer has an interval primitive).
8 days ago

Roadmap relationship: tracked by #133 under master roadmap #132.

8 days ago

Implemented and pushed to main in a4659eb (fix(ui): improve dashboard accessibility), building on the confirmation/polling work in cbc4c25, eeab6b8, and baa8e51.

Coverage:

  • contextual accessible names for repeated service, worker, deployment, firewall, team, site, secret, alarm, queue, SSH-key, and backup actions
  • associated labels for site, secret, alarm, Aurora, function, command, and terminal controls
  • every dashboard table header now declares scope="col"
  • confirmation and operation/terminal output are named live regions
  • confirmation focus/scroll is owned by useOpConfirm
  • terminal transport moved to a useTerminal composable using the stx WebSocket/ref/effect primitives; the template has no manual DOM, location, socket, or lifecycle plumbing
  • site reloads were replaced by response-backed signal updates
  • overview/server-log/function-log timers use usePolling/useInterval
  • added static accessibility/stx-hygiene regression tests (149 assertions)

Verification: 7 focused UI tests pass and all 46 UI routes build.

Sign in to comment on this issue.