diff --git a/webview-ui/src/components/chat/ShareButton.tsx b/webview-ui/src/components/chat/ShareButton.tsx index 20442ba76b..7c90e72039 100644 --- a/webview-ui/src/components/chat/ShareButton.tsx +++ b/webview-ui/src/components/chat/ShareButton.tsx @@ -35,20 +35,32 @@ export const ShareButton = ({ item, disabled = false }: ShareButtonProps) => { const { t } = useTranslation() const { sharingEnabled, cloudIsAuthenticated, cloudUserInfo } = useExtensionState() const wasUnauthenticatedRef = useRef(false) + const initiatedAuthFromThisButtonRef = useRef(false) // Track authentication state changes to auto-open popover after login useEffect(() => { if (!cloudIsAuthenticated || !sharingEnabled) { wasUnauthenticatedRef.current = true } else if (wasUnauthenticatedRef.current && cloudIsAuthenticated && sharingEnabled) { - // User just authenticated, send telemetry, close modal, and open the popover - telemetryClient.capture(TelemetryEventName.ACCOUNT_CONNECT_SUCCESS) - setConnectModalOpen(false) - setShareDropdownOpen(true) + // Only open dropdown if auth was initiated from this button + if (initiatedAuthFromThisButtonRef.current) { + // User just authenticated from this share button, send telemetry, close modal, and open the popover + telemetryClient.capture(TelemetryEventName.ACCOUNT_CONNECT_SUCCESS) + setConnectModalOpen(false) + setShareDropdownOpen(true) + initiatedAuthFromThisButtonRef.current = false // Reset the flag + } wasUnauthenticatedRef.current = false } }, [cloudIsAuthenticated, sharingEnabled]) + // Cleanup effect to reset flag on unmount + useEffect(() => { + return () => { + initiatedAuthFromThisButtonRef.current = false + } + }, []) + // Listen for share success messages from the extension useEffect(() => { const handleMessage = (event: MessageEvent) => { @@ -92,6 +104,8 @@ export const ShareButton = ({ item, disabled = false }: ShareButtonProps) => { // Send telemetry for connect to cloud action telemetryClient.capture(TelemetryEventName.SHARE_CONNECT_TO_CLOUD_CLICKED) + // Mark that authentication was initiated from this button + initiatedAuthFromThisButtonRef.current = true vscode.postMessage({ type: "rooCloudSignIn" }) setShareDropdownOpen(false) setConnectModalOpen(false) diff --git a/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx b/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx index 2d9ea0cac1..5db6287747 100644 --- a/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/TaskActions.spec.tsx @@ -265,7 +265,7 @@ describe("TaskActions", () => { expect(screen.queryByText("Connect to Cloud")).not.toBeInTheDocument() }) - it("automatically opens popover when user becomes authenticated", () => { + it("does not automatically open popover when user becomes authenticated from elsewhere", () => { // Start with unauthenticated state mockUseExtensionState.mockReturnValue({ sharingEnabled: false, @@ -277,7 +277,7 @@ describe("TaskActions", () => { // Verify popover is not open initially expect(screen.queryByText("Share with Organization")).not.toBeInTheDocument() - // Simulate user becoming authenticated + // Simulate user becoming authenticated (e.g., from AccountView) mockUseExtensionState.mockReturnValue({ sharingEnabled: true, cloudIsAuthenticated: true, @@ -288,7 +288,47 @@ describe("TaskActions", () => { rerender() - // Verify popover automatically opens and shows sharing options + // Verify popover does NOT automatically open when auth happens from elsewhere + expect(screen.queryByText("Share with Organization")).not.toBeInTheDocument() + expect(screen.queryByText("Share Publicly")).not.toBeInTheDocument() + }) + + it("automatically opens popover when user authenticates from share button", () => { + // Start with unauthenticated state + mockUseExtensionState.mockReturnValue({ + sharingEnabled: false, + cloudIsAuthenticated: false, + } as any) + + const { rerender } = render() + + // Click share button to open connect modal + const buttons = screen.getAllByRole("button") + const shareButton = buttons.find((btn) => btn.querySelector(".codicon-link")) + expect(shareButton).toBeDefined() + fireEvent.click(shareButton!) + + // Click connect button to initiate authentication + const connectButton = screen.getByText("Connect") + fireEvent.click(connectButton) + + // Verify rooCloudSignIn message was sent + expect(mockPostMessage).toHaveBeenCalledWith({ + type: "rooCloudSignIn", + }) + + // Simulate user becoming authenticated after clicking connect from share button + mockUseExtensionState.mockReturnValue({ + sharingEnabled: true, + cloudIsAuthenticated: true, + cloudUserInfo: { + organizationName: "Test Organization", + }, + } as any) + + rerender() + + // Verify popover automatically opens when auth was initiated from share button expect(screen.getByText("Share with Organization")).toBeInTheDocument() expect(screen.getByText("Share Publicly")).toBeInTheDocument() })