From 85edc88a6d49d05aa7a623a24ecc8ca3d7410c18 Mon Sep 17 00:00:00 2001 From: nntrivi2001 Date: Tue, 3 Nov 2026 09:07:06 +0700 Subject: [PATCH] fix(status-bar): running / need-you count only the viewer's own sessions An admin's status bar and the Dashboard's Needs-you strip counted every user's waiting sessions; both now ask GET /api/sessions with mine=1, like Today's spend already did. --- client/src/components/NeedsYouStrip.tsx | 5 +++-- client/src/components/StatusBar.tsx | 7 ++++--- client/src/components/__tests__/StatusBar.test.tsx | 3 +++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/client/src/components/NeedsYouStrip.tsx b/client/src/components/NeedsYouStrip.tsx index a614c229..7f52d3b3 100644 --- a/client/src/components/NeedsYouStrip.tsx +++ b/client/src/components/NeedsYouStrip.tsx @@ -1,7 +1,8 @@ /** * @file NeedsYouStrip.tsx * @description The Dashboard's pinned "Needs you" strip: every active session - * blocked on the user (`awaiting_input_since`), each linking straight to its + * of the viewer's OWN blocked on them (`awaiting_input_since`, `mine=1` — an + * admin's lists no other user's), each linking straight to its * workspace pane (or replay), else its analysis page. Renders nothing while no * session is waiting. `compact` is the one-line form shown above Analytics. * @author Nguyễn Ngọc Trí Vĩ @@ -27,7 +28,7 @@ export function NeedsYouStrip({ compact = false }: { compact?: boolean }) { const load = useCallback(() => { api.sessions - .list({ awaiting: true, limit: 20 }) + .list({ awaiting: true, limit: 20, mine: true }) .then((r) => { setSessions(r.sessions); setTotal(r.total); diff --git a/client/src/components/StatusBar.tsx b/client/src/components/StatusBar.tsx index d5b85609..9a5144b2 100644 --- a/client/src/components/StatusBar.tsx +++ b/client/src/components/StatusBar.tsx @@ -4,7 +4,8 @@ * which the sidebar owns and which also carries the update check), the version * — with a green dot while a newer release is out —, how many SESSIONS are * running and how many need the user (`GET /api/sessions?status=active` and - * `?awaiting=1` — the Dashboard's Needs-you rule —, re-read on session + * `?awaiting=1` — the Dashboard's Needs-you rule —, both `&mine=1`: the user's + * OWN sessions even for an admin —, re-read on session * messages), and today's spend — `GET /api/pricing/cost?date=&mine=1`, the * user's OWN spend even for an admin — and, on the * Workspace page, the open workspace's total (`?lane=` on the same call: the @@ -388,11 +389,11 @@ export function StatusBar({ const loadCounts = useCallback(() => { api.sessions - .list({ status: "active", limit: 1 }) + .list({ status: "active", limit: 1, mine: true }) .then((r) => setActive(r.total)) .catch(() => undefined); api.sessions - .list({ awaiting: true, limit: 1 }) + .list({ awaiting: true, limit: 1, mine: true }) .then((r) => setNeedYou(r.total)) .catch(() => undefined); }, []); diff --git a/client/src/components/__tests__/StatusBar.test.tsx b/client/src/components/__tests__/StatusBar.test.tsx index e10e2aea..4401911b 100644 --- a/client/src/components/__tests__/StatusBar.test.tsx +++ b/client/src/components/__tests__/StatusBar.test.tsx @@ -183,6 +183,9 @@ describe("StatusBar", () => { ); await screen.findByText("1 need you"); expect(screen.getByTestId("status-bar-counts").textContent).toBe("2 running · 1 need you"); + // The user's OWN sessions, even for an admin who sees every user's rows. + for (const [p] of vi.mocked(api.sessions.list).mock.calls) + expect(p).toMatchObject({ mine: true }); await user.click(conn); expect(onConnectionClick).toHaveBeenCalled(); // Polite live region: the connection and who is waiting, nothing that ticks.