@@ -6,17 +6,20 @@ import {
66 type Icon ,
77 Lightning ,
88 Play ,
9+ Stop ,
910 Timer ,
1011 Warning ,
1112 X ,
1213} from "@phosphor-icons/react" ;
1314import type { LoopSchemas } from "@posthog/api-client/loops" ;
1415import { cn } from "@posthog/quill" ;
16+ import { StopCloudRunDialog } from "@posthog/ui/features/sessions/components/StopCloudRunDialog" ;
1517import { Badge } from "@posthog/ui/primitives/Badge" ;
1618import { Button } from "@posthog/ui/primitives/Button" ;
19+ import { toast } from "@posthog/ui/primitives/toast" ;
1720import { navigateToTaskDetail } from "@posthog/ui/router/navigationBridge" ;
1821import { Flex , Text } from "@radix-ui/themes" ;
19- import type { ReactNode } from "react" ;
22+ import { type ReactNode , useState } from "react" ;
2023
2124function statusColor (
2225 status : LoopSchemas . LoopRunStatusEnum ,
@@ -109,10 +112,25 @@ function MetaItem({
109112 ) ;
110113}
111114
112- export function LoopRunRow ( { run } : { run : LoopSchemas . LoopRun } ) {
115+ function isStoppable ( run : LoopSchemas . LoopRun ) : boolean {
116+ return (
117+ run . environment === "cloud" &&
118+ ( run . status === "queued" || run . status === "in_progress" )
119+ ) ;
120+ }
121+
122+ export function LoopRunRow ( {
123+ run,
124+ onStopped,
125+ } : {
126+ run : LoopSchemas . LoopRun ;
127+ onStopped ?: ( ) => void ;
128+ } ) {
113129 const StatusIcon = statusIcon ( run . status ) ;
114130 const duration = runDuration ( run ) ;
115131 const triggered = Boolean ( run . loop_trigger_id ) ;
132+ const stoppable = isStoppable ( run ) ;
133+ const [ stopOpen , setStopOpen ] = useState ( false ) ;
116134
117135 return (
118136 < Flex
@@ -162,15 +180,41 @@ export function LoopRunRow({ run }: { run: LoopSchemas.LoopRun }) {
162180 </ Flex >
163181 ) : null }
164182 </ Flex >
165- < Button
166- variant = "soft"
167- color = "gray"
168- size = "1"
169- className = "shrink-0"
170- onClick = { ( ) => navigateToTaskDetail ( run . task_id ) }
171- >
172- View run
173- </ Button >
183+ < Flex align = "center" gap = "2" className = "shrink-0" >
184+ { stoppable ? (
185+ < Button
186+ variant = "soft"
187+ color = "red"
188+ size = "1"
189+ onClick = { ( ) => setStopOpen ( true ) }
190+ >
191+ < Stop size = { 12 } weight = "bold" />
192+ Stop run
193+ </ Button >
194+ ) : null }
195+ < Button
196+ variant = "soft"
197+ color = "gray"
198+ size = "1"
199+ onClick = { ( ) => navigateToTaskDetail ( run . task_id ) }
200+ >
201+ View run
202+ </ Button >
203+ </ Flex >
204+ { stoppable || stopOpen ? (
205+ < StopCloudRunDialog
206+ open = { stopOpen }
207+ taskId = { run . task_id }
208+ runId = { run . id }
209+ title = "Stop run"
210+ buttonLabel = "Stop run"
211+ onOpenChange = { setStopOpen }
212+ onStopped = { ( ) => {
213+ toast . success ( "Run stopped" ) ;
214+ onStopped ?.( ) ;
215+ } }
216+ />
217+ ) : null }
174218 </ Flex >
175219 ) ;
176220}
0 commit comments