Browse Source

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 <[email protected]>
Murilo Pires 7 months ago
parent
commit
1b12108172

+ 1 - 3
webview-ui/src/components/chat/TaskActions.tsx

@@ -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)}
 				/>
 			)}

+ 42 - 4
webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx

@@ -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()
 		})
 	})
 })