11import { type LoopSchemas , listLoopRuns } from "@posthog/api-client/loops" ;
2+ import type { Task } from "@posthog/shared/domain-types" ;
3+ import { getAuthenticatedClient } from "@posthog/ui/features/auth/authClientImperative" ;
24import { AUTH_SCOPED_QUERY_META } from "@posthog/ui/features/auth/useCurrentUser" ;
35import { useQuery } from "@tanstack/react-query" ;
46import { loopsKeys } from "./loopsKeys" ;
57import { useLoopsClient } from "./useLoopsClient" ;
68
79export const RECENT_RUNS_LIMIT = 10 ;
810
11+ export function reconcileLoopRunStatus (
12+ run : LoopSchemas . LoopRun ,
13+ task : Task ,
14+ ) : LoopSchemas . LoopRun {
15+ const latestRun = task . latest_run ;
16+ if ( run . status !== "in_progress" || ! latestRun ) return run ;
17+ if ( latestRun . status !== "cancelled" && latestRun . status !== "failed" ) {
18+ return run ;
19+ }
20+
21+ return {
22+ ...run ,
23+ status : latestRun . status ,
24+ completed_at : latestRun . completed_at ,
25+ error_message : latestRun . error_message ,
26+ } ;
27+ }
28+
929/** The most recent runs for a loop, polled so the detail view stays live. */
1030export function useLoopRuns ( loopId : string | undefined ) {
1131 const loopsClient = useLoopsClient ( ) ;
@@ -14,12 +34,43 @@ export function useLoopRuns(loopId: string | undefined) {
1434 queryKey : loopsKeys . runs ( loopsClient ?. projectId ?? null , loopId ?? "" ) ,
1535 queryFn : async ( ) => {
1636 if ( ! loopsClient || ! loopId ) throw new Error ( "Not authenticated" ) ;
17- return await listLoopRuns (
37+ const page = await listLoopRuns (
1838 loopsClient . client ,
1939 loopsClient . projectId ,
2040 loopId ,
2141 { limit : RECENT_RUNS_LIMIT } ,
2242 ) ;
43+ const activeRuns = page . results . filter (
44+ ( run ) => run . status === "in_progress" ,
45+ ) ;
46+ if ( activeRuns . length === 0 ) return page ;
47+
48+ const taskClient = await getAuthenticatedClient ( ) ;
49+ if ( ! taskClient ) return page ;
50+
51+ const tasks = await Promise . allSettled (
52+ activeRuns . map ( async ( run ) => ( {
53+ run,
54+ task : ( await taskClient . getTask ( run . task_id ) ) as unknown as Task ,
55+ } ) ) ,
56+ ) ;
57+ const reconciled = new Map (
58+ tasks . flatMap ( ( result ) =>
59+ result . status === "fulfilled"
60+ ? [
61+ [
62+ result . value . run . id ,
63+ reconcileLoopRunStatus ( result . value . run , result . value . task ) ,
64+ ] as const ,
65+ ]
66+ : [ ] ,
67+ ) ,
68+ ) ;
69+
70+ return {
71+ ...page ,
72+ results : page . results . map ( ( run ) => reconciled . get ( run . id ) ?? run ) ,
73+ } ;
2374 } ,
2475 select : ( page ) => page . results . slice ( 0 , RECENT_RUNS_LIMIT ) ,
2576 enabled : ! ! loopsClient && ! ! loopId ,
0 commit comments