From cba4e4a3a5a66cf65fe2f0bfa611f93b075893b5 Mon Sep 17 00:00:00 2001 From: Dotta Date: Wed, 15 Apr 2026 08:28:17 -0500 Subject: [PATCH] Keep queued issue chat mounted Co-Authored-By: Paperclip (cherry picked from commit 65a7f2679d4dc29c9228baded57b39b9a2a84029) --- ui/src/pages/IssueDetail.tsx | 46 ++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/ui/src/pages/IssueDetail.tsx b/ui/src/pages/IssueDetail.tsx index 158487d0015..4a6f2269062 100644 --- a/ui/src/pages/IssueDetail.tsx +++ b/ui/src/pages/IssueDetail.tsx @@ -553,19 +553,20 @@ const IssueDetailChatTab = memo(function IssueDetailChatTab({ interruptingQueuedRunId, onImageClick, }: IssueDetailChatTabProps) { - const { data: activity, isLoading: activityLoading } = useQuery({ + const { data: activity } = useQuery({ queryKey: queryKeys.issues.activity(issueId), queryFn: () => activityApi.forIssue(issueId), placeholderData: keepPreviousDataForSameQueryTail(issueId), }); - const { data: liveRuns, isLoading: liveRunsLoading } = useQuery({ + const { data: liveRuns } = useQuery({ queryKey: queryKeys.issues.liveRuns(issueId), queryFn: () => heartbeatsApi.liveRunsForIssue(issueId), refetchInterval: 3000, placeholderData: keepPreviousDataForSameQueryTail(issueId), }); - const liveRunCount = liveRuns?.length ?? 0; - const { data: activeRun, isLoading: activeRunLoading } = useQuery({ + const resolvedLiveRuns = liveRuns ?? []; + const liveRunCount = resolvedLiveRuns.length; + const { data: activeRun = null } = useQuery({ queryKey: queryKeys.issues.activeRun(issueId), queryFn: () => heartbeatsApi.activeRunForIssue(issueId), enabled: !!executionRunId || issueStatus === "in_progress", @@ -573,39 +574,41 @@ const IssueDetailChatTab = memo(function IssueDetailChatTab({ placeholderData: keepPreviousDataForSameQueryTail(issueId), }); const hasLiveRuns = liveRunCount > 0 || !!activeRun; - const { data: linkedRuns, isLoading: linkedRunsLoading } = useQuery({ + const { data: linkedRuns } = useQuery({ queryKey: queryKeys.issues.runs(issueId), queryFn: () => activityApi.runsForIssue(issueId), refetchInterval: hasLiveRuns ? 5000 : false, placeholderData: keepPreviousDataForSameQueryTail(issueId), }); + const resolvedActivity = activity ?? []; + const resolvedLinkedRuns = linkedRuns ?? []; const runningIssueRun = useMemo( - () => resolveRunningIssueRun(activeRun, liveRuns), - [activeRun, liveRuns], + () => resolveRunningIssueRun(activeRun, resolvedLiveRuns), + [activeRun, resolvedLiveRuns], ); const timelineRuns = useMemo(() => { const liveIds = new Set(); - for (const run of liveRuns ?? []) liveIds.add(run.id); + for (const run of resolvedLiveRuns) liveIds.add(run.id); if (activeRun) liveIds.add(activeRun.id); const historicalRuns = liveIds.size === 0 - ? (linkedRuns ?? []) - : (linkedRuns ?? []).filter((run) => !liveIds.has(run.runId)); + ? resolvedLinkedRuns + : resolvedLinkedRuns.filter((run) => !liveIds.has(run.runId)); return historicalRuns.map((run) => ({ ...run, adapterType: run.adapterType, hasStoredOutput: (run.logBytes ?? 0) > 0, })); - }, [activeRun, linkedRuns, liveRuns]); + }, [activeRun, resolvedLinkedRuns, resolvedLiveRuns]); const commentsWithRunMeta = useMemo(() => { const activeRunStartedAt = runningIssueRun?.startedAt ?? runningIssueRun?.createdAt ?? null; const runMetaByCommentId = new Map(); const agentIdByRunId = new Map(); - for (const run of linkedRuns ?? []) { + for (const run of resolvedLinkedRuns) { agentIdByRunId.set(run.runId, run.agentId); } - for (const evt of activity ?? []) { + for (const evt of resolvedActivity) { if (evt.action !== "issue.comment_added" || !evt.runId) continue; const details = evt.details ?? {}; const commentId = typeof details["commentId"] === "string" ? details["commentId"] : null; @@ -639,20 +642,11 @@ const IssueDetailChatTab = memo(function IssueDetailChatTab({ } return nextComment; }); - }, [activity, comments, linkedRuns, runningIssueRun]); + }, [comments, resolvedActivity, resolvedLinkedRuns, runningIssueRun]); const timelineEvents = useMemo( - () => extractIssueTimelineEvents(activity), - [activity], + () => extractIssueTimelineEvents(resolvedActivity), + [resolvedActivity], ); - const initialLoading = - (activityLoading && activity === undefined) - || (linkedRunsLoading && linkedRuns === undefined) - || (liveRunsLoading && liveRuns === undefined) - || (activeRunLoading && activeRun === undefined); - - if (initialLoading) { - return ; - } return (
@@ -677,7 +671,7 @@ const IssueDetailChatTab = memo(function IssueDetailChatTab({ feedbackTermsUrl={feedbackTermsUrl} linkedRuns={timelineRuns} timelineEvents={timelineEvents} - liveRuns={liveRuns} + liveRuns={resolvedLiveRuns} activeRun={activeRun} companyId={companyId} projectId={projectId}