Add cancel workflow functionality (#1193)

Co-authored-by: Muhammed Salih Altun <muhammedsalihaltun@gmail.com>
This commit is contained in:
Shuchang Zheng
2024-11-14 11:30:11 -08:00
committed by GitHub
parent 17d9a56738
commit 6eeaa583ff

View File

@@ -43,9 +43,11 @@ import {
Pencil2Icon, Pencil2Icon,
PlayIcon, PlayIcon,
ReaderIcon, ReaderIcon,
ReloadIcon,
} from "@radix-ui/react-icons"; } from "@radix-ui/react-icons";
import { import {
keepPreviousData, keepPreviousData,
useMutation,
useQuery, useQuery,
useQueryClient, useQueryClient,
} from "@tanstack/react-query"; } from "@tanstack/react-query";
@@ -59,9 +61,23 @@ import {
} from "react-router-dom"; } from "react-router-dom";
import { TaskActions } from "../tasks/list/TaskActions"; import { TaskActions } from "../tasks/list/TaskActions";
import { TaskListSkeletonRows } from "../tasks/list/TaskListSkeletonRows"; import { TaskListSkeletonRows } from "../tasks/list/TaskListSkeletonRows";
import { statusIsNotFinalized, statusIsRunningOrQueued } from "../tasks/types"; import {
statusIsFinalized,
statusIsNotFinalized,
statusIsRunningOrQueued,
} from "../tasks/types";
import { CodeEditor } from "./components/CodeEditor"; import { CodeEditor } from "./components/CodeEditor";
import { useWorkflowQuery } from "./hooks/useWorkflowQuery"; import { useWorkflowQuery } from "./hooks/useWorkflowQuery";
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
type StreamMessage = { type StreamMessage = {
task_id: string; task_id: string;
@@ -144,6 +160,35 @@ function WorkflowRun() {
workflowRun?.status === Status.Running ? "always" : false, workflowRun?.status === Status.Running ? "always" : false,
}); });
const cancelWorkflowMutation = useMutation({
mutationFn: async () => {
const client = await getClient(credentialGetter);
return client
.post(`/workflows/runs/${workflowRunId}/cancel`)
.then((response) => response.data);
},
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["workflowRun", workflowRunId],
});
queryClient.invalidateQueries({
queryKey: ["workflowRun", workflowPermanentId, workflowRunId],
});
toast({
variant: "success",
title: "Workflow Canceled",
description: "The workflow has been successfully canceled.",
});
},
onError: (error) => {
toast({
variant: "destructive",
title: "Error",
description: error.message,
});
},
});
const currentRunningTask = workflowTasks?.find( const currentRunningTask = workflowTasks?.find(
(task) => task.status === Status.Running, (task) => task.status === Status.Running,
); );
@@ -151,6 +196,8 @@ function WorkflowRun() {
const workflowRunIsRunningOrQueued = const workflowRunIsRunningOrQueued =
workflowRun && statusIsRunningOrQueued(workflowRun); workflowRun && statusIsRunningOrQueued(workflowRun);
const workflowRunIsFinalized = workflowRun && statusIsFinalized(workflowRun);
useEffect(() => { useEffect(() => {
if (!workflowRunIsRunningOrQueued) { if (!workflowRunIsRunningOrQueued) {
return; return;
@@ -347,17 +394,51 @@ function WorkflowRun() {
Edit Edit
</Link> </Link>
</Button> </Button>
<Button asChild> {workflowRunIsRunningOrQueued && (
<Link <Dialog>
to={`/workflows/${workflowPermanentId}/run`} <DialogTrigger asChild>
state={{ <Button variant="destructive">Cancel</Button>
data: parameters, </DialogTrigger>
}} <DialogContent>
> <DialogHeader>
<PlayIcon className="mr-2 h-4 w-4" /> <DialogTitle>Are you sure?</DialogTitle>
Rerun <DialogDescription>
</Link> Are you sure you want to cancel this workflow run?
</Button> </DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose asChild>
<Button variant="secondary">Back</Button>
</DialogClose>
<Button
variant="destructive"
onClick={() => {
cancelWorkflowMutation.mutate();
}}
disabled={cancelWorkflowMutation.isPending}
>
{cancelWorkflowMutation.isPending && (
<ReloadIcon className="mr-2 h-4 w-4 animate-spin" />
)}
Cancel Workflow Run
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)}
{workflowRunIsFinalized && (
<Button asChild>
<Link
to={`/workflows/${workflowPermanentId}/run`}
state={{
data: parameters,
}}
>
<PlayIcon className="mr-2 h-4 w-4" />
Rerun
</Link>
</Button>
)}
</div> </div>
</header> </header>
{workflowRun && statusIsNotFinalized(workflowRun) && ( {workflowRun && statusIsNotFinalized(workflowRun) && (