From 87e4c2da46cba3e7b3b9c3ce617d3e0ee952cbbc Mon Sep 17 00:00:00 2001 From: Test User Date: Wed, 1 Apr 2026 19:30:42 -0700 Subject: [PATCH 1/3] feat(web-ui): /sessions/[id] detail page (#509) - New page wiring SplitPane + AgentChatPanel + AgentTerminal - Header: back link, short session ID, state badge, cost, End Session button - Active sessions: SplitPane with chat (45%) + terminal (55%), per-session storageKey - Ended sessions: read-only AgentChatPanel with history, no terminal, ended banner - Loading skeleton and error states (404 session-not-found + generic) - Error feedback when End Session fails - AgentChatPanel: readOnly + initialMessages props for ended session view - sessionsApi: getOne() and getMessages() endpoints - 19 unit tests covering all acceptance criteria --- .../sessions/SessionDetailPage.test.tsx | 309 ++++++++++++++++++ web-ui/src/app/sessions/[id]/page.tsx | 215 +++++++++++- .../components/sessions/AgentChatPanel.tsx | 24 +- web-ui/src/lib/api.ts | 34 ++ 4 files changed, 560 insertions(+), 22 deletions(-) create mode 100644 web-ui/src/__tests__/components/sessions/SessionDetailPage.test.tsx diff --git a/web-ui/src/__tests__/components/sessions/SessionDetailPage.test.tsx b/web-ui/src/__tests__/components/sessions/SessionDetailPage.test.tsx new file mode 100644 index 00000000..58a5ab80 --- /dev/null +++ b/web-ui/src/__tests__/components/sessions/SessionDetailPage.test.tsx @@ -0,0 +1,309 @@ +'use client'; + +import { render, screen, fireEvent, waitFor } from '@testing-library/react'; +import { useParams, useRouter } from 'next/navigation'; +import useSWR from 'swr'; +import SessionDetailPage from '@/app/sessions/[id]/page'; +import { sessionsApi } from '@/lib/api'; +import type { Session } from '@/types'; + +// ── Mocks ──────────────────────────────────────────────────────────────── + +jest.mock('next/navigation', () => ({ + useParams: jest.fn(), + useRouter: jest.fn(), +})); + +jest.mock('swr'); + +jest.mock('@/lib/api', () => ({ + sessionsApi: { + getOne: jest.fn(), + end: jest.fn(), + getMessages: jest.fn(), + }, +})); + +jest.mock('@/components/sessions/AgentChatPanel', () => ({ + AgentChatPanel: ({ + sessionId, + readOnly, + }: { + sessionId: string; + readOnly?: boolean; + }) => ( +
+ {!readOnly &&