From 2d2906f23faf201640bddf39d0cdafd6446b6a13 Mon Sep 17 00:00:00 2001 From: Forgotten Date: Fri, 20 Feb 2026 14:48:30 -0600 Subject: [PATCH] feat: show child issues on issue detail page Add a Sub-issues section between Comments and Linked Approvals on the issue detail page. Lists child issues with status, priority, identifier, title, and assignee. Reuses the cached company issues list for zero extra API calls. Co-Authored-By: Claude Opus 4.6 --- ui/src/pages/IssueDetail.tsx | 46 ++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/ui/src/pages/IssueDetail.tsx b/ui/src/pages/IssueDetail.tsx index dcdc3e6f..5f2ffd9b 100644 --- a/ui/src/pages/IssueDetail.tsx +++ b/ui/src/pages/IssueDetail.tsx @@ -159,6 +159,12 @@ export function IssueDetail() { enabled: !!issueId, }); + const { data: allIssues } = useQuery({ + queryKey: queryKeys.issues.list(selectedCompanyId!), + queryFn: () => issuesApi.list(selectedCompanyId!), + enabled: !!selectedCompanyId, + }); + const { data: agents } = useQuery({ queryKey: queryKeys.agents.list(selectedCompanyId!), queryFn: () => agentsApi.list(selectedCompanyId!), @@ -177,6 +183,13 @@ export function IssueDetail() { return map; }, [agents]); + const childIssues = useMemo(() => { + if (!allIssues || !issueId) return []; + return allIssues + .filter((i) => i.parentId === issueId) + .sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()); + }, [allIssues, issueId]); + const commentsWithRunMeta = useMemo(() => { const runMetaByCommentId = new Map(); const agentIdByRunId = new Map(); @@ -562,6 +575,39 @@ export function IssueDetail() { }} /> + {childIssues.length > 0 && ( + <> + +
+

Sub-issues

+
+ {childIssues.map((child) => ( + +
+ + + + {child.identifier ?? child.id.slice(0, 8)} + + {child.title} +
+ {child.assigneeAgentId && (() => { + const name = agentMap.get(child.assigneeAgentId)?.name; + return name + ? + : {child.assigneeAgentId.slice(0, 8)}; + })()} + + ))} +
+
+ + )} + {linkedApprovals && linkedApprovals.length > 0 && ( <>