-
Notifications
You must be signed in to change notification settings - Fork 154
feat(webview): surface condense button and context progress bar in collapsed task header #680
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
6953336
ff85f67
a7c6163
037baa9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "zoo-code": patch | ||
| --- | ||
|
|
||
| Surface the manual context compaction button and linear context window progress bar on the right side of the collapsed task header. |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,6 +1,6 @@ | ||||||
| import { memo, useRef, useState, useMemo } from "react" | ||||||
| import { useTranslation } from "react-i18next" | ||||||
| import { ChevronUp, ChevronDown, HardDriveDownload, HardDriveUpload, FoldVertical, ArrowLeft } from "lucide-react" | ||||||
| import { ChevronUp, ChevronDown, HardDriveDownload, HardDriveUpload, ListChevronsDownUp, ArrowLeft } from "lucide-react" | ||||||
| import prettyBytes from "pretty-bytes" | ||||||
|
|
||||||
| import type { ClineMessage } from "@roo-code/types" | ||||||
|
|
@@ -81,7 +81,7 @@ const TaskHeader = ({ | |||||
| const condenseButton = ( | ||||||
| <LucideIconButton | ||||||
| title={t("chat:task.condenseContext")} | ||||||
| icon={FoldVertical} | ||||||
| icon={ListChevronsDownUp} | ||||||
| disabled={buttonsDisabled} | ||||||
| onClick={() => currentTaskItem && handleCondenseContext(currentTaskItem.id)} | ||||||
| /> | ||||||
|
|
@@ -274,6 +274,14 @@ const TaskHeader = ({ | |||||
| </> | ||||||
| )} | ||||||
| </div> | ||||||
| <div className="flex items-center gap-1 ml-8 w-60 min-w-[120px] shrink"> | ||||||
| <ContextWindowProgress | ||||||
| contextWindow={contextWindow} | ||||||
| contextTokens={contextTokens || 0} | ||||||
| maxTokens={maxTokens || undefined} | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| /> | ||||||
| {condenseButton} | ||||||
| </div> | ||||||
| </div> | ||||||
| )} | ||||||
| {/* Expanded state: Show task text and images */} | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -133,15 +133,22 @@ describe("TaskHeader", () => { | |
| expect(screen.queryByText(/\$/)).not.toBeInTheDocument() | ||
| }) | ||
|
|
||
| it("should render the condense context button in the collapsed state", () => { | ||
| renderTaskHeader() | ||
| // Button is visible without expanding the task header | ||
| const buttons = screen.getAllByRole("button") | ||
| const condenseButton = buttons.find((button) => button.querySelector("svg.lucide-list-chevrons-down-up")) | ||
| expect(condenseButton).toBeDefined() | ||
| expect(condenseButton?.querySelector("svg")).toBeInTheDocument() | ||
| }) | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| it("should render the condense context button when expanded", () => { | ||
| renderTaskHeader() | ||
| // First click to expand the task header | ||
| const taskHeader = screen.getByText("Test task") | ||
| fireEvent.click(taskHeader) | ||
|
|
||
| // Now find the condense button in the expanded state | ||
| const buttons = screen.getAllByRole("button") | ||
| const condenseButton = buttons.find((button) => button.querySelector("svg.lucide-fold-vertical")) | ||
| const condenseButton = buttons.find((button) => button.querySelector("svg.lucide-list-chevrons-down-up")) | ||
| expect(condenseButton).toBeDefined() | ||
| expect(condenseButton?.querySelector("svg")).toBeInTheDocument() | ||
| }) | ||
|
|
@@ -150,13 +157,9 @@ describe("TaskHeader", () => { | |
| const handleCondenseContext = vi.fn() | ||
| renderTaskHeader({ handleCondenseContext }) | ||
|
|
||
| // First click to expand the task header | ||
| const taskHeader = screen.getByText("Test task") | ||
| fireEvent.click(taskHeader) | ||
|
|
||
| // Find the button that contains the FoldVertical icon | ||
| // Button is clickable in collapsed state without expanding first | ||
| const buttons = screen.getAllByRole("button") | ||
| const condenseButton = buttons.find((button) => button.querySelector("svg.lucide-fold-vertical")) | ||
| const condenseButton = buttons.find((button) => button.querySelector("svg.lucide-list-chevrons-down-up")) | ||
| expect(condenseButton).toBeDefined() | ||
| fireEvent.click(condenseButton!) | ||
| expect(handleCondenseContext).toHaveBeenCalledWith("test-task-id") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test verifies the handler fires, but not that clicking the button doesn't expand the header — which is the core UX promise of surfacing it in the collapsed state. Could we add an assertion like |
||
|
|
@@ -166,13 +169,9 @@ describe("TaskHeader", () => { | |
| const handleCondenseContext = vi.fn() | ||
| renderTaskHeader({ buttonsDisabled: true, handleCondenseContext }) | ||
|
|
||
| // First click to expand the task header | ||
| const taskHeader = screen.getByText("Test task") | ||
| fireEvent.click(taskHeader) | ||
|
|
||
| // Find the button that contains the FoldVertical icon | ||
| // Button is disabled in collapsed state without expanding first | ||
| const buttons = screen.getAllByRole("button") | ||
| const condenseButton = buttons.find((button) => button.querySelector("svg.lucide-fold-vertical")) | ||
| const condenseButton = buttons.find((button) => button.querySelector("svg.lucide-list-chevrons-down-up")) | ||
| expect(condenseButton).toBeDefined() | ||
| expect(condenseButton).toBeDisabled() | ||
| fireEvent.click(condenseButton!) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This div relies on the ancestor div (line 177) for
stopPropagation. TheContextWindowProgressbar inside renders plain<div>elements — not<button>s — so it's not covered by thee.target.closest("button")early-return guard either. If this div ever moves outside that ancestor during a refactor, clicking the progress bar would silently start toggling the header.Worth adding its own guard?