fix(ui): stop the Lens setup steps scrolling sideways and drop the preview footer

The step headers bleed 8px for their hover background, so the steps
column pads by the same amount. The preview footer repeated the sample
count; only the bar for clearing saved hand-picked runs remains.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Yujong Lee 2026-10-04 20:22:21 -07:00
parent fcf977b522
commit 34baeb834f
3 changed files with 11 additions and 30 deletions

View file

@ -391,7 +391,6 @@ it("appends the next preview page as the list scrolls near its end, then stops a
});
renderWithProviders(<InvestigationSetup mode="edit" initial={settings} onClose={vi.fn()} onSave={vi.fn()} />);
expect(await screen.findByText("Run one")).toBeVisible();
expect(screen.getByText(/Showing 1 of 2/)).toBeVisible();
expect(screen.getByText("100% of 2")).toBeVisible();
const nextPageCalls = () =>
proxy.post.mock.calls.filter(([, options]) => (options?.body as { cursor: string }).cursor === "next");
@ -403,7 +402,6 @@ it("appends the next preview page as the list scrolls near its end, then stops a
act(() => finishSecondPage());
expect(await screen.findByText("Run two")).toBeVisible();
expect(screen.getByText("Run one")).toBeVisible();
expect(screen.queryByText(/Showing/)).not.toBeInTheDocument();
expect(screen.queryByTestId("preview-placeholder")).not.toBeInTheDocument();
act(() => mockAllIsIntersecting(true));
expect(nextPageCalls()).toHaveLength(1);

View file

@ -199,7 +199,7 @@ function SetupEditor({
aria-label="Investigation setup"
current={step}
onOpen={setStep}
className="lg:-m-1 lg:max-h-full lg:overflow-y-auto lg:p-1"
className="lg:-mx-2 lg:-my-1 lg:max-h-full lg:overflow-y-auto lg:px-2 lg:py-1"
>
<SetupStep id="activity" heading="Activity" description="Which runs to review" summary={<ActivitySummary />}>
<ScopeFields {...activity.scope} />

View file

@ -20,35 +20,18 @@ const noSetup = () => {};
/** The preview can hold hundreds of rows; it re-renders only when its rows or paging change, not on every keystroke. */
const PreviewTable = memo(AgentTracesTable);
type PreviewFooterProps = ComponentProps<"div"> & Pick<MatchingPreview, "page" | "selection">;
/** Selection count and a way to undo manual picks; hidden while every match is simply going to be analyzed. */
function PreviewFooter({ page, selection, className, ...props }: PreviewFooterProps) {
const partial = page.eligible != null && page.executions.length < page.eligible;
const count = selection?.count ?? page.selected;
const picked = selection?.ids.length ?? 0;
const everything = count === page.eligible && !partial && picked === 0;
if (page.eligible == null || everything) return null;
/** Runs saved by hand on an older investigation; picks are no longer made here, only cleared. */
function PickedRuns({ selection }: { selection: PreviewSelection }) {
const picked = selection.ids.length;
if (picked === 0) return null;
return (
<div
data-slot="preview-footer"
className={cn("flex flex-wrap items-center justify-between gap-3 border-t bg-muted/30 px-4 py-2", className)}
{...props}
>
<div className="flex items-center justify-between gap-3 border-t bg-muted/30 px-4 py-2">
<p className="text-xs tabular-nums text-muted-foreground">
{count.toLocaleString()} selected for analysis
{partial && (
<>
{" "}
· Showing {page.executions.length.toLocaleString()} of {page.eligible.toLocaleString()}
</>
)}
{selection.count.toLocaleString()} selected for analysis
</p>
{selection && picked > 0 && (
<Button variant="ghost" size="xs" onClick={selection.clear}>
Clear {picked} selected runs
</Button>
)}
<Button variant="ghost" size="xs" onClick={selection.clear}>
Clear {picked} selected runs
</Button>
</div>
);
}
@ -110,7 +93,7 @@ export function MatchingActivityPreview({
/>
</div>
)}
{shown && <PreviewFooter page={page} selection={selection} />}
{shown && selection && <PickedRuns selection={selection} />}
</section>
);
}