Skip to content

feat(sessions): Scrollable & collapsible queued-messages dock#2904

Open
arthurdedeus wants to merge 1 commit into
mainfrom
posthog-code/queue-overflow-collapse
Open

feat(sessions): Scrollable & collapsible queued-messages dock#2904
arthurdedeus wants to merge 1 commit into
mainfrom
posthog-code/queue-overflow-collapse

Conversation

@arthurdedeus

Copy link
Copy Markdown

Problem

While the agent is running, follow-up messages you submit get queued in a dock pinned above the composer. That dock had no height cap, scroll, or collapse — so with several long messages it grew unbounded, pushing the composer down, cropping the input at the bottom, and hiding the conversation above.

Before

Before — a long queue pushes the composer down and crops the input

Changes

  • Overflow — the queued-messages dock is now height-capped (max-h-[30vh]) and scrolls internally, so a long queue never pushes the composer off-screen. Added shrink-0 to the composer block in SessionView so the input is never compressed below its (now bounded) height; the flex-1 conversation thread yields the space instead.
  • Collapse — a header row (N queued + caret) toggles the queue open/closed, backed by new per-task queueCollapsedByTaskId view-state in sessionViewStore (ephemeral, defaults to expanded, and survives the dock unmounting between turns). The live count stays visible while collapsed.
  • Reuses the existing in-repo collapse pattern — @radix-ui/react-collapsible + phosphor carets, as in ProgressGroupView/SidebarSection — and the max-h … overflow-y-auto scroll idiom. The per-message Steer / Return to editor / Discard actions are unchanged.

After — expanded (scrolls instead of growing past the composer)

After — expanded, scrollable queue with 12 messages, input fully visible

After — collapsed

After — collapsed queue, composer fully visible

Testing

  • New QueuedMessagesDock.test.tsx — default-expanded shows every message with a count, the overflow classes are present, the header toggle collapses/expands the list (count persists), and an empty queue renders nothing.
  • turbo typecheck, Biome lint, and the sessions component suite (100 tests) all pass.
  • Manually verified in the running app (screenshots above).

Created with PostHog Code

A long queue of follow-ups no longer pushes the composer off-screen or crops
it: the dock is height-capped and scrolls internally, and a header toggle
collapses it. Adds per-task collapse view-state in sessionViewStore.

Generated-By: PostHog Code
Task-Id: 36c7f9ac-946a-403b-8b7f-c2dd5e3f66fd
@github-actions

Copy link
Copy Markdown

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit d5e98e0.

@arthurdedeus arthurdedeus requested a review from a team June 24, 2026 14:45
@greptile-apps

greptile-apps Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "feat(sessions): Make the queued-messages..." | Re-trigger Greptile

Comment on lines +83 to +109
queuedState.messages = [];
const { container } = render(<QueuedMessagesDock taskId="task-empty" />);
expect(container).toBeEmptyDOMElement();
});

it("is expanded by default and shows every queued message with a count", () => {
queuedState.messages = TWO_MESSAGES;
renderDock("task-expanded");

expect(screen.getByText("first queued message")).toBeInTheDocument();
expect(screen.getByText("second queued message")).toBeInTheDocument();
expect(screen.getByText("2 queued")).toBeInTheDocument();
expect(
screen.getByRole("button", { name: "Collapse queued messages" }),
).toHaveAttribute("aria-expanded", "true");
});

it("caps the list height and scrolls so it can't push the composer down", () => {
queuedState.messages = TWO_MESSAGES;
const { container } = renderDock("task-scroll");

const scroller = container.querySelector(".overflow-y-auto");
expect(scroller).not.toBeNull();
expect(scroller?.classList.contains("max-h-[30vh]")).toBe(true);
});

it("collapses and expands the list when the header is toggled", () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Prefer parameterised tests for repeated render-and-assert cases

Tests 2 ("is expanded by default…"), 3 ("caps the list height…"), and 1 ("renders nothing…") all share the same shape: configure queuedState.messages, call renderDock, assert output. Combining them — and any future per-message-count assertions — into a single it.each table would satisfy the team's parameterised-test preference and make adding new message-count cases trivial without duplicating the render call.

Context Used: Do not attempt to comment on incorrect alphabetica... (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@arthurdedeus arthurdedeus self-assigned this Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant