fix: enable export, share, and copy buttons during API operations (#5324) (#5849)

* feat: add Issue Fixer Orchestrator mode

* fix: allow export task history while API is active (#5324)

- Add exportAlwaysEnabled prop to TaskActions component
- Export button remains enabled when exportAlwaysEnabled is true
- Other action buttons still respect buttonsDisabled state
- Add tests to verify the new behavior

This fixes the regression where users couldn't export task history
during API operations, which is a common debugging workflow.

* fix: simplify export button to always be enabled

The export functionality is not impacted by the model streaming state,
so the button should always be enabled. Removed the unnecessary
exportAlwaysEnabled prop and simplified the implementation.

- Remove exportAlwaysEnabled prop from TaskActions
- Remove disabled attribute from export button entirely
- Update TaskHeader to remove exportAlwaysEnabled prop usage
- Update tests to reflect that export is always enabled

* fix: enable export, share, and copy buttons during API operations

- Export, share, and copy buttons now remain enabled when API is active
- Delete button still respects buttonsDisabled state for safety
- Removed unnecessary exportAlwaysEnabled prop
- Updated tests to reflect new behavior

---------

Co-authored-by: Daniel Riccio <ricciodaniel98@gmail.com>
This commit is contained in:
Murilo Pires 2025-07-19 20:25:17 -03:00 • committed by GitHub
parent 37300ef0c5
commit 1b12108172
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 43 additions and 7 deletions

View file

@ -23,18 +23,16 @@ export const TaskActions = ({ item, buttonsDisabled }: TaskActionsProps) => {
return (
<div className="flex flex-row gap-1">
<ShareButton item={item} disabled={buttonsDisabled} />
<ShareButton item={item} disabled={false} />
<IconButton
iconClass="codicon-desktop-download"
title={t("chat:task.export")}
disabled={buttonsDisabled}
onClick={() => vscode.postMessage({ type: "exportCurrentTask" })}
/>
{item?.task && (
<IconButton
iconClass={showCopyFeedback ? "codicon-check" : "codicon-copy"}
title={t("history:copyPrompt")}
disabled={buttonsDisabled}
onClick={(e) => copyWithFeedback(item.task, e)}
/>
)}

View file

@ -371,16 +371,54 @@ describe("TaskActions", () => {
})
describe("Button States", () => {
it("disables buttons when buttonsDisabled is true", () => {
it("keeps share, export, and copy buttons enabled but disables delete button when buttonsDisabled is true", () => {
render(<TaskActions item={mockItem} buttonsDisabled={true} />)
// Find button by its icon class
// Find buttons by their labels/icons
const buttons = screen.getAllByRole("button")
const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link"))
const exportButton = screen.getByLabelText("Export task history")
const copyButton = buttons.find((btn) => btn.querySelector(".codicon-copy"))
const deleteButton = screen.getByLabelText("Delete Task (Shift + Click to skip confirmation)")
expect(shareButton).toBeDisabled()
expect(exportButton).toBeDisabled()
// Share, export, and copy buttons should be enabled regardless of buttonsDisabled
expect(shareButton).not.toBeDisabled()
expect(exportButton).not.toBeDisabled()
expect(copyButton).not.toBeDisabled()
// Delete button should respect buttonsDisabled
expect(deleteButton).toBeDisabled()
})
it("share, export, and copy buttons are always enabled while delete button respects buttonsDisabled state", () => {
// Test with buttonsDisabled = false
const { rerender } = render(<TaskActions item={mockItem} buttonsDisabled={false} />)
let buttons = screen.getAllByRole("button")
let shareButton = buttons.find((btn) => btn.querySelector(".codicon-link"))
let exportButton = screen.getByLabelText("Export task history")
let copyButton = buttons.find((btn) => btn.querySelector(".codicon-copy"))
let deleteButton = screen.getByLabelText("Delete Task (Shift + Click to skip confirmation)")
expect(shareButton).not.toBeDisabled()
expect(exportButton).not.toBeDisabled()
expect(copyButton).not.toBeDisabled()
expect(deleteButton).not.toBeDisabled()
// Test with buttonsDisabled = true
rerender(<TaskActions item={mockItem} buttonsDisabled={true} />)
buttons = screen.getAllByRole("button")
shareButton = buttons.find((btn) => btn.querySelector(".codicon-link"))
exportButton = screen.getByLabelText("Export task history")
copyButton = buttons.find((btn) => btn.querySelector(".codicon-copy"))
deleteButton = screen.getByLabelText("Delete Task (Shift + Click to skip confirmation)")
// Share, export, and copy remain enabled
expect(shareButton).not.toBeDisabled()
expect(exportButton).not.toBeDisabled()
expect(copyButton).not.toBeDisabled()
// Delete button is disabled
expect(deleteButton).toBeDisabled()
})
})
})