diff --git a/packages/ui/src/features/loops/components/LoopDetailView.tsx b/packages/ui/src/features/loops/components/LoopDetailView.tsx index c2f5ee7cfc..96c453f43a 100644 --- a/packages/ui/src/features/loops/components/LoopDetailView.tsx +++ b/packages/ui/src/features/loops/components/LoopDetailView.tsx @@ -212,7 +212,11 @@ export function LoopDetailView({ loopId }: { loopId: string }) { ) : ( {runs.map((run) => ( - + void runsQuery.refetch()} + /> ))} )} diff --git a/packages/ui/src/features/loops/components/LoopRunRow.tsx b/packages/ui/src/features/loops/components/LoopRunRow.tsx index 9f8c1f46b2..66defbfe8a 100644 --- a/packages/ui/src/features/loops/components/LoopRunRow.tsx +++ b/packages/ui/src/features/loops/components/LoopRunRow.tsx @@ -6,17 +6,20 @@ import { type Icon, Lightning, Play, + Stop, Timer, Warning, X, } from "@phosphor-icons/react"; import type { LoopSchemas } from "@posthog/api-client/loops"; import { cn } from "@posthog/quill"; +import { StopCloudRunDialog } from "@posthog/ui/features/sessions/components/StopCloudRunDialog"; import { Badge } from "@posthog/ui/primitives/Badge"; import { Button } from "@posthog/ui/primitives/Button"; +import { toast } from "@posthog/ui/primitives/toast"; import { navigateToTaskDetail } from "@posthog/ui/router/navigationBridge"; import { Flex, Text } from "@radix-ui/themes"; -import type { ReactNode } from "react"; +import { type ReactNode, useState } from "react"; function statusColor( status: LoopSchemas.LoopRunStatusEnum, @@ -109,10 +112,25 @@ function MetaItem({ ); } -export function LoopRunRow({ run }: { run: LoopSchemas.LoopRun }) { +function isStoppable(run: LoopSchemas.LoopRun): boolean { + return ( + run.environment === "cloud" && + (run.status === "queued" || run.status === "in_progress") + ); +} + +export function LoopRunRow({ + run, + onStopped, +}: { + run: LoopSchemas.LoopRun; + onStopped?: () => void; +}) { const StatusIcon = statusIcon(run.status); const duration = runDuration(run); const triggered = Boolean(run.loop_trigger_id); + const stoppable = isStoppable(run); + const [stopOpen, setStopOpen] = useState(false); return ( ) : null} - + + {stoppable ? ( + + ) : null} + + + {stoppable || stopOpen ? ( + { + toast.success("Run stopped"); + onStopped?.(); + }} + /> + ) : null} ); }