diff --git a/src/renderer/src/components/right-sidebar/SourceControl.hosted-review-header-link.test.tsx b/src/renderer/src/components/right-sidebar/SourceControl.hosted-review-header-link.test.tsx new file mode 100644 index 00000000000..194221a48e4 --- /dev/null +++ b/src/renderer/src/components/right-sidebar/SourceControl.hosted-review-header-link.test.tsx @@ -0,0 +1,60 @@ +import React from 'react' +import { renderToStaticMarkup } from 'react-dom/server' +import { describe, expect, it, vi } from 'vitest' +import type { HostedReviewInfo } from '../../../../shared/hosted-review' +import { HostedReviewHeaderLink } from './SourceControl' + +function makeReview(overrides: Partial = {}): HostedReviewInfo { + return { + provider: 'github', + number: 2192, + title: 'Open PR in checks', + state: 'open', + url: 'https://github.com/stablyai/orca/pull/2192', + status: 'pending', + updatedAt: '2026-05-17T00:00:00Z', + mergeable: 'UNKNOWN', + ...overrides + } +} + +type MinimalClickEvent = Pick + +describe('HostedReviewHeaderLink', () => { + it('opens GitHub PRs in the Checks tab instead of rendering an external link', () => { + const onOpenGitHubPRInChecks = vi.fn() + const element = HostedReviewHeaderLink({ + review: makeReview(), + onOpenGitHubPRInChecks + }) + const markup = renderToStaticMarkup(element) + + expect(markup).toContain(' void)({ stopPropagation }) + expect(stopPropagation).toHaveBeenCalledTimes(1) + expect(onOpenGitHubPRInChecks).toHaveBeenCalledTimes(1) + }) + + it('keeps non-GitHub reviews as external hosted-review links', () => { + const markup = renderToStaticMarkup( + + ) + + expect(markup).toContain(' } +function hostedReviewLabel(review: HostedReviewInfo): string { + return `${review.provider === 'gitlab' ? 'MR' : 'PR'} #${review.number}` +} + +export function HostedReviewHeaderLink({ + review, + onOpenGitHubPRInChecks +}: { + review: HostedReviewInfo + onOpenGitHubPRInChecks: () => void +}): React.JSX.Element { + const label = hostedReviewLabel(review) + const className = + 'shrink-0 border-0 bg-transparent p-0 text-left font-medium leading-none text-foreground opacity-80 hover:text-foreground hover:underline' + + if (review.provider === 'github') { + return ( + + ) + } + + return ( + e.stopPropagation()} + > + {label} + + ) +} + function SourceControlInner(): React.JSX.Element { const sourceControlRef = useRef(null) // Why: React setState is async, so a rapid double-click on the Commit @@ -1285,6 +1330,11 @@ function SourceControlInner(): React.JSX.Element { ] ) + const openHostedGitHubPRInChecks = useCallback(() => { + setRightSidebarOpen(true) + setRightSidebarTab('checks') + }, [setRightSidebarOpen, setRightSidebarTab]) + const hasUnstagedChanges = grouped.unstaged.length > 0 || grouped.untracked.length > 0 const hasPartiallyStagedChanges = useMemo(() => { if (grouped.staged.length === 0 || grouped.unstaged.length === 0) { @@ -2434,15 +2484,10 @@ function SourceControlInner(): React.JSX.Element { {hostedReview && ( )}