From 14944211ec0871dc84a7fffe8deddc500fd3898a Mon Sep 17 00:00:00 2001 From: idhanth <109756003+idhanth@users.noreply.github.com> Date: Tue, 29 Sep 2026 16:59:22 -0400 Subject: [PATCH 1/2] fix(portal): keep HAR detail panel in view when selecting lower rows (#740) Co-Authored-By: Claude Opus 5.5 --- .../components/HarNetworkViewer.stories.tsx | 59 +++++++++++++++++++ .../src/components/HarNetworkViewer.tsx | 2 +- 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 apps/portal/src/components/HarNetworkViewer.stories.tsx diff --git a/apps/portal/src/components/HarNetworkViewer.stories.tsx b/apps/portal/src/components/HarNetworkViewer.stories.tsx new file mode 100644 index 000000000..af77e622a --- /dev/null +++ b/apps/portal/src/components/HarNetworkViewer.stories.tsx @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { http, HttpResponse } from "msw"; +import { HarNetworkViewer } from "./HarNetworkViewer"; + +const base = new Date("2026-06-21T12:00:00Z").getTime(); +const methods = ["GET", "POST", "GET", "PUT", "GET", "DELETE"]; + +// Enough rows that the table is much taller than the viewport, plus a large +// JSON body so the detail panel's own content has to scroll. +const sampleHar = { + log: { + entries: Array.from({ length: 60 }, (_, i) => ({ + startedDateTime: new Date(base + i * 250).toISOString(), + time: 40 + ((i * 37) % 900), + request: { + method: methods[i % methods.length], + url: `https://api.example.com/v1/items/${i}?page=${i % 5}`, + headers: [ + { name: "accept", value: "application/json" }, + { name: "user-agent", value: "scope-worker/1.0" }, + ], + ...(i % 2 === 1 && { + postData: { mimeType: "application/json", text: JSON.stringify({ id: i, name: `item-${i}` }) }, + }), + }, + response: { + status: i % 13 === 0 ? 500 : i % 7 === 0 ? 404 : 200, + statusText: i % 13 === 0 ? "Internal Server Error" : i % 7 === 0 ? "Not Found" : "OK", + headers: Array.from({ length: 12 }, (_, h) => ({ name: `x-header-${h}`, value: `value-${i}-${h}` })), + content: { + size: 512 + i * 128, + mimeType: "application/json", + text: JSON.stringify({ id: i, items: Array.from({ length: 40 }, (_, n) => ({ n, label: `row ${n}` })) }), + }, + }, + })), + }, +}; + +const harHandler = http.get("*/api/v1/requests/:id/har", () => HttpResponse.json(sampleHar)); + +const meta = { + component: HarNetworkViewer, + tags: ["ai-generated", "needs-work"], + parameters: { + msw: { handlers: [harHandler] }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +/** Scroll down and select a lower row: the detail panel should stay in view. */ +export const LongList: Story = { + args: { runId: "demo-run" }, +}; diff --git a/apps/portal/src/components/HarNetworkViewer.tsx b/apps/portal/src/components/HarNetworkViewer.tsx index 9ca527ad4..baa7144dc 100644 --- a/apps/portal/src/components/HarNetworkViewer.tsx +++ b/apps/portal/src/components/HarNetworkViewer.tsx @@ -329,7 +329,7 @@ function DetailPanel({ entry, onClose }: { entry: HarEntry; onClose: () => void const responseBody = decodeBody(entry.response.content); return ( -
+
{/* Panel header */}
From 723a2b52f8164570f73f60bc3efe9064cd1412f6 Mon Sep 17 00:00:00 2001 From: idhanth <109756003+idhanth@users.noreply.github.com> Date: Thu, 1 Oct 2026 17:14:47 -0400 Subject: [PATCH 2/2] fix(portal): add bottom border to HAR detail panel and app-header stand-in to story (#740) Co-Authored-By: Claude Opus 5.5 --- .../src/components/HarNetworkViewer.stories.tsx | 15 +++++++++++++++ apps/portal/src/components/HarNetworkViewer.tsx | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/portal/src/components/HarNetworkViewer.stories.tsx b/apps/portal/src/components/HarNetworkViewer.stories.tsx index af77e622a..b280e342e 100644 --- a/apps/portal/src/components/HarNetworkViewer.stories.tsx +++ b/apps/portal/src/components/HarNetworkViewer.stories.tsx @@ -46,8 +46,23 @@ const meta = { component: HarNetworkViewer, tags: ["ai-generated", "needs-work"], parameters: { + layout: "fullscreen", msw: { handlers: [harHandler] }, }, + // Stand-in for the portal's sticky 3rem app header (see Layout.tsx), so the + // detail panel's sticky offset renders the way it does in the portal. + decorators: [ + (Story) => ( + <> +
+ App header +
+
+ +
+ + ), + ], } satisfies Meta; export default meta; diff --git a/apps/portal/src/components/HarNetworkViewer.tsx b/apps/portal/src/components/HarNetworkViewer.tsx index baa7144dc..315d41fe5 100644 --- a/apps/portal/src/components/HarNetworkViewer.tsx +++ b/apps/portal/src/components/HarNetworkViewer.tsx @@ -329,7 +329,7 @@ function DetailPanel({ entry, onClose }: { entry: HarEntry; onClose: () => void const responseBody = decodeBody(entry.response.content); return ( -
+
{/* Panel header */}