From 3e678f25910b21ae0039fce35e70bf653a3eaa8e Mon Sep 17 00:00:00 2001 From: Lukas May Date: Tue, 3 Mar 2026 13:25:29 +0100 Subject: [PATCH] fix: Show detailing indicator by including detail tasks in listInitiativeTasks listInitiativeTasks was filtering out detail tasks server-side, so the detailAgentByPhase mapping could never resolve agent.taskId to a phaseId. Move the filter to client-side (displayTasks) so detail tasks are available for agent mapping but excluded from counts and display grouping. --- apps/server/trpc/routers/task.ts | 2 +- apps/web/src/components/ExecutionTab.tsx | 12 +++++++++--- apps/web/src/components/pipeline/PipelineTab.tsx | 12 +++++++++--- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/apps/server/trpc/routers/task.ts b/apps/server/trpc/routers/task.ts index 960d89b..5e29ec2 100644 --- a/apps/server/trpc/routers/task.ts +++ b/apps/server/trpc/routers/task.ts @@ -132,7 +132,7 @@ export function taskProcedures(publicProcedure: ProcedureBuilder) { .query(async ({ ctx, input }) => { const taskRepository = requireTaskRepository(ctx); const tasks = await taskRepository.findByInitiativeId(input.initiativeId); - return tasks.filter((t) => t.category !== 'detail'); + return tasks; }), listPhaseTasks: publicProcedure diff --git a/apps/web/src/components/ExecutionTab.tsx b/apps/web/src/components/ExecutionTab.tsx index 6d399d3..7250feb 100644 --- a/apps/web/src/components/ExecutionTab.tsx +++ b/apps/web/src/components/ExecutionTab.tsx @@ -117,11 +117,17 @@ export function ExecutionTab({ ); const allTasks = allTasksQuery.data ?? []; + // Filter out detail tasks for display (counts/grouping), keep allTasks unfiltered for detailAgentByPhase + const displayTasks = useMemo( + () => allTasks.filter((t) => t.category !== "detail"), + [allTasks], + ); + // Group tasks and counts by phaseId const { taskCountsByPhase, tasksByPhase } = useMemo(() => { const counts: Record = {}; - const grouped: Record = {}; - for (const task of allTasks) { + const grouped: Record = {}; + for (const task of displayTasks) { const pid = task.phaseId; if (!pid) continue; if (!counts[pid]) counts[pid] = { complete: 0, total: 0 }; @@ -131,7 +137,7 @@ export function ExecutionTab({ grouped[pid].push(task); } return { taskCountsByPhase: counts, tasksByPhase: grouped }; - }, [allTasks]); + }, [displayTasks]); // Map phaseId → most recent active detail agent const detailAgentByPhase = useMemo(() => { diff --git a/apps/web/src/components/pipeline/PipelineTab.tsx b/apps/web/src/components/pipeline/PipelineTab.tsx index f5a4702..07681c0 100644 --- a/apps/web/src/components/pipeline/PipelineTab.tsx +++ b/apps/web/src/components/pipeline/PipelineTab.tsx @@ -58,17 +58,23 @@ function PipelineTabInner({ initiativeId, phases, phasesLoading }: PipelineTabPr const agentsQuery = trpc.listAgents.useQuery(); const allAgents = agentsQuery.data ?? []; - // Group tasks by phaseId + // Filter out detail tasks for display (counts/grouping), keep allTasks unfiltered for detailAgentByPhase + const displayTasks = useMemo( + () => allTasks.filter((t) => t.category !== "detail"), + [allTasks], + ); + + // Group display tasks by phaseId const tasksByPhase = useMemo(() => { const map: Record = {}; - for (const task of allTasks) { + for (const task of displayTasks) { if (task.phaseId) { if (!map[task.phaseId]) map[task.phaseId] = []; map[task.phaseId].push(task); } } return map; - }, [allTasks]); + }, [displayTasks]); // Map phaseId → most recent active detail agent const detailAgentByPhase = useMemo(() => {