feat(dashboard): GuruConnect v2 Sessions view (pass 2)
All checks were successful
All checks were successful
Active-sessions table with consent-state badges, viewer-token Join, and disconnect, built on the v2 session API and existing UI primitives. - Sessions table: machine, mode (managed/attended), consent badge (granted/pending+pulse/denied/not_required), viewers, started, duration, status. Sticky header, skeleton load, empty/error states. - Join action mints a session-scoped viewer token (POST /api/sessions/:id/viewer-token) and reveals it with the /ws/viewer relay URL and copy buttons. The static viewer.html is intentionally not targeted: it sends the raw login JWT, which the v2 viewer plane rejects. In-dashboard web viewer ships in a later pass. - Authz split mirrors the server mint gate: admin or control permission gets Control; view permission gets View only; neither hides the action. Server remains authoritative; the minted token carries the signed access claim. - Disconnect via confirm dialog (DELETE /api/sessions/:id), invalidates the sessions query. List polls every 8s so consent transitions surface. Passed Code Review (no blockers) and local gates (tsc/lint/build green). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -111,3 +111,19 @@ export function CopyIcon(props: IconProps) {
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function JoinIcon(props: IconProps) {
|
||||
return (
|
||||
<svg {...base(props)}>
|
||||
<path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4M10 17l5-5-5-5M15 12H3" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function StopIcon(props: IconProps) {
|
||||
return (
|
||||
<svg {...base(props)}>
|
||||
<rect x="5" y="5" width="14" height="14" rx="2" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user