From 8ac5c66fab37dae9e4e892cfc15449339f70a9ae Mon Sep 17 00:00:00 2001 From: Jinjing <6427696+AmethystLiang@users.noreply.github.com> Date: Fri, 27 Mar 2026 10:35:28 -0700 Subject: [PATCH] feat: auto-fetch PR data on worktree change and add refresh to empty state Add useEffect to fetch PR data when the active worktree/branch changes, and add a refresh button with loading spinner to the "no PR found" empty state. Extract check helpers to separate file to stay within line limit. Co-Authored-By: Claude Opus 4.6 --- .../components/right-sidebar/ChecksPanel.tsx | 69 +++++++------------ .../right-sidebar/checks-helpers.tsx | 47 +++++++++++++ 2 files changed, 71 insertions(+), 45 deletions(-) create mode 100644 src/renderer/src/components/right-sidebar/checks-helpers.tsx diff --git a/src/renderer/src/components/right-sidebar/ChecksPanel.tsx b/src/renderer/src/components/right-sidebar/ChecksPanel.tsx index 0bc20f05b55..758c912d365 100644 --- a/src/renderer/src/components/right-sidebar/ChecksPanel.tsx +++ b/src/renderer/src/components/right-sidebar/ChecksPanel.tsx @@ -4,7 +4,6 @@ import { CircleX, LoaderCircle, CircleDashed, - CircleMinus, ExternalLink, RefreshCw, Check, @@ -14,63 +13,22 @@ import { import { useAppStore } from '@/store' import { cn } from '@/lib/utils' import PRActions from './PRActions' +import { PullRequestIcon, CHECK_ICON, CHECK_COLOR, prStateColor } from './checks-helpers' import type { PRInfo, PRCheckDetail } from '../../../../shared/types' -function PullRequestIcon({ className }: { className?: string }): React.JSX.Element { - return ( - - - - ) -} - -const CHECK_ICON: Record> = { - success: CircleCheck, - failure: CircleX, - pending: LoaderCircle, - neutral: CircleDashed, - skipped: CircleMinus, - cancelled: CircleX, - timed_out: CircleX -} - -const CHECK_COLOR: Record = { - success: 'text-emerald-500', - failure: 'text-rose-500', - pending: 'text-amber-500', - neutral: 'text-muted-foreground', - skipped: 'text-muted-foreground/60', - cancelled: 'text-muted-foreground/60', - timed_out: 'text-rose-500' -} - -function prStateColor(state: PRInfo['state']): string { - switch (state) { - case 'merged': - return 'bg-purple-500/15 text-purple-500 border-purple-500/20' - case 'open': - return 'bg-emerald-500/15 text-emerald-500 border-emerald-500/20' - case 'closed': - return 'bg-muted text-muted-foreground border-border' - case 'draft': - return 'bg-muted text-muted-foreground/70 border-border' - } -} - export default function ChecksPanel(): React.JSX.Element { const activeWorktreeId = useAppStore((s) => s.activeWorktreeId) const worktreesByRepo = useAppStore((s) => s.worktreesByRepo) const repos = useAppStore((s) => s.repos) const prCache = useAppStore((s) => s.prCache) const fetchPRForBranch = useAppStore((s) => s.fetchPRForBranch) + const refreshGitHubForWorktree = useAppStore((s) => s.refreshGitHubForWorktree) const fetchPRChecks = useAppStore((s) => s.fetchPRChecks) const [checks, setChecks] = useState([]) const [checksLoading, setChecksLoading] = useState(false) + const [emptyRefreshing, setEmptyRefreshing] = useState(false) const [editingTitle, setEditingTitle] = useState(false) const [titleDraft, setTitleDraft] = useState('') const [titleSaving, setTitleSaving] = useState(false) @@ -99,6 +57,13 @@ export default function ChecksPanel(): React.JSX.Element { const pr: PRInfo | null = prCacheKey ? (prCache[prCacheKey]?.data ?? null) : null const prNumber = pr?.number ?? null + // Fetch PR data when the active worktree/branch changes + useEffect(() => { + if (repo && branch) { + void fetchPRForBranch(repo.path, branch) + } + }, [repo, branch, fetchPRForBranch]) + // Fetch checks via cached store method const fetchChecks = useCallback(async () => { if (!repo || !prNumber) { @@ -247,6 +212,20 @@ export default function ChecksPanel(): React.JSX.Element {
Push your branch and open a PR to see checks here
+ ) } diff --git a/src/renderer/src/components/right-sidebar/checks-helpers.tsx b/src/renderer/src/components/right-sidebar/checks-helpers.tsx new file mode 100644 index 00000000000..3e06bc93158 --- /dev/null +++ b/src/renderer/src/components/right-sidebar/checks-helpers.tsx @@ -0,0 +1,47 @@ +import React from 'react' +import { CircleCheck, CircleX, LoaderCircle, CircleDashed, CircleMinus } from 'lucide-react' +import type { PRInfo } from '../../../../shared/types' + +export function PullRequestIcon({ className }: { className?: string }): React.JSX.Element { + return ( + + + + ) +} + +export const CHECK_ICON: Record> = { + success: CircleCheck, + failure: CircleX, + pending: LoaderCircle, + neutral: CircleDashed, + skipped: CircleMinus, + cancelled: CircleX, + timed_out: CircleX +} + +export const CHECK_COLOR: Record = { + success: 'text-emerald-500', + failure: 'text-rose-500', + pending: 'text-amber-500', + neutral: 'text-muted-foreground', + skipped: 'text-muted-foreground/60', + cancelled: 'text-muted-foreground/60', + timed_out: 'text-rose-500' +} + +export function prStateColor(state: PRInfo['state']): string { + switch (state) { + case 'merged': + return 'bg-purple-500/15 text-purple-500 border-purple-500/20' + case 'open': + return 'bg-emerald-500/15 text-emerald-500 border-emerald-500/20' + case 'closed': + return 'bg-muted text-muted-foreground border-border' + case 'draft': + return 'bg-muted text-muted-foreground/70 border-border' + } +}