feat(ux): Tier 3 security-adjacent UX (presentational only)

- secrets: revealed value gets a copy-to-clipboard with feedback,
  auto re-hides after 30s, re-hides on window blur, and the timer is
  cleared on unmount (no change to revealSecret or RLS)
- permissions matrix: a view-only notice when the viewer is not admin,
  and a per-checkbox aria-label so the grid is usable non-visually
- OpsAclEditor: pills are now aria-pressed toggles with a visible
  check when selected and a success toast on save

No server action, RLS, or permission logic changed.
This commit is contained in:
Moheeb Zara
2026-05-16 14:13:11 -07:00
parent a1ea92a71c
commit b7461f07fd
3 changed files with 63 additions and 5 deletions
@@ -60,6 +60,14 @@ export function PermissionsPanel({ isAdmin, customRoles, rolePerms }: Props) {
<span className="font-sans text-xs text-muted-foreground">holds all permissions (implicit, locked)</span>
</div>
{!isAdmin && (
<div className="mb-4 rounded border border-border bg-muted/40 px-3 py-2" role="status">
<p className="font-sans text-xs text-muted-foreground">
View only. Only an admin can change permissions.
</p>
</div>
)}
<div className="overflow-x-auto">
<table className="w-full border-collapse">
<thead>
@@ -118,6 +126,7 @@ function PermGroup({
<input
type="checkbox"
disabled={!isAdmin}
aria-label={`${p.label} for ${s.label}`}
checked={grants[s.key]?.has(p.code) ?? false}
onChange={e => onToggle(s.key, p.code, e.target.checked)}
/>