diff --git a/ui/src/components/IssueChatComposerHandoffPreview.test.ts b/ui/src/components/IssueChatComposerHandoffPreview.test.ts new file mode 100644 index 0000000000..d18383a6fa --- /dev/null +++ b/ui/src/components/IssueChatComposerHandoffPreview.test.ts @@ -0,0 +1,32 @@ +import { describe, expect, it } from "vitest"; +import { computeComposerHandoffPreview } from "../lib/interrupt-handoff"; +import { shouldRenderComposerHandoffPreview } from "./IssueChatThread"; + +describe("shouldRenderComposerHandoffPreview", () => { + it("skips the spacer wrapper when the preview is empty", () => { + const preview = computeComposerHandoffPreview({ + reassignTarget: "agent:agent-claude", + currentAssigneeValue: "agent:agent-claude", + hasActiveRun: true, + bodyHasAgentMention: false, + plainNameCandidate: null, + }); + + expect(preview.kind).toBe("none"); + expect(shouldRenderComposerHandoffPreview("Wake Claude", preview)).toBe(false); + }); + + it("renders the spacer wrapper only when body text and a visible preview are present", () => { + const preview = computeComposerHandoffPreview({ + reassignTarget: "agent:agent-qa", + currentAssigneeValue: "agent:agent-claude", + hasActiveRun: true, + bodyHasAgentMention: false, + plainNameCandidate: null, + }); + + expect(preview.kind).not.toBe("none"); + expect(shouldRenderComposerHandoffPreview("Wake QA", preview)).toBe(true); + expect(shouldRenderComposerHandoffPreview(" ", preview)).toBe(false); + }); +}); diff --git a/ui/src/components/IssueChatThread.tsx b/ui/src/components/IssueChatThread.tsx index 263c99be46..5ddf41d185 100644 --- a/ui/src/components/IssueChatThread.tsx +++ b/ui/src/components/IssueChatThread.tsx @@ -120,6 +120,7 @@ import { computeComposerHandoffPreview, extractAgentMentionIds, findPlainAgentNameCandidate, + type ComposerHandoffPreview, type HandoffAgentMention, } from "../lib/interrupt-handoff"; import { restoreSubmittedCommentDraft } from "../lib/comment-submit-draft"; @@ -316,6 +317,10 @@ interface CommentReassignment { assigneeUserId: string | null; } +export function shouldRenderComposerHandoffPreview(body: string, preview: ComposerHandoffPreview): boolean { + return Boolean(body.trim()) && preview.kind !== "none"; +} + export interface IssueChatComposerHandle { focus: () => void; restoreDraft: (submittedBody: string) => void; @@ -3840,8 +3845,10 @@ const IssueChatComposer = forwardRef ) : null} - {body.trim() ? ( - + {shouldRenderComposerHandoffPreview(body, handoffPreview) ? ( +
+ +
) : null}