diff --git a/frontend/relay-workflows-lib/lib/components/BaseWorkflowRelay.tsx b/frontend/relay-workflows-lib/lib/components/BaseWorkflowRelay.tsx index 3ba378360..eb8fb9702 100644 --- a/frontend/relay-workflows-lib/lib/components/BaseWorkflowRelay.tsx +++ b/frontend/relay-workflows-lib/lib/components/BaseWorkflowRelay.tsx @@ -10,6 +10,7 @@ import { ResizableBox } from "react-resizable"; import { Box } from "@mui/material"; import { WorkflowAccordion, type WorkflowStatus } from "workflows-lib"; import RetriggerWorkflow from "../query-components/RetriggerWorkflow"; +import StopWorkflow from "../mutation-components/StopWorkflow"; import { useSelectedTaskIds } from "../utils/workflowRelayUtils"; import { graphql } from "relay-runtime"; import { useFragment } from "react-relay"; @@ -80,6 +81,14 @@ export default function BaseWorkflowRelay({ ? (data.status.startTime as string | undefined) : undefined; + const stoppable = + data.status?.__typename == undefined || + ![ + "WorkflowSucceededStatus", + "WorkflowErroredStatus", + "WorkflowFailedStatus", + ].includes(data.status.__typename); + const [selectedTaskIds, setSelectedTaskIds] = useSelectedTaskIds() as [ string[], Dispatch>, @@ -189,6 +198,7 @@ export default function BaseWorkflowRelay({ }} /> + {stoppable && } ); diff --git a/frontend/relay-workflows-lib/lib/mutation-components/StopWorkflow.tsx b/frontend/relay-workflows-lib/lib/mutation-components/StopWorkflow.tsx new file mode 100644 index 000000000..3b39d5c42 --- /dev/null +++ b/frontend/relay-workflows-lib/lib/mutation-components/StopWorkflow.tsx @@ -0,0 +1,71 @@ +import React, { useState, useEffect } from "react"; +import Tooltip from "@mui/material/Tooltip"; +import Cancel from "@mui/icons-material/Cancel"; +import { graphql } from "relay-runtime"; +import { useMutation } from "react-relay"; +import { IconButton, Box } from "@mui/material"; +import { StopWorkflowMutation as StopWorkflowMutationType } from "./__generated__/StopWorkflowMutation.graphql"; + +const stopWorkflowMutation = graphql` + mutation StopWorkflowMutation($id: ID!) { + stopWorkflow(id: $id) { + id + } + } +`; + +interface StopWorkflowProps { + workflowId: string; +} + +const StopWorkflow: React.FC = ({ workflowId }) => { + const [loading, setLoading] = useState(false); + const buttonCooldown = 5000; + useEffect(() => { + if (loading) { + const timeout = setTimeout(() => { + setLoading(false); + }, buttonCooldown); + return () => { + clearTimeout(timeout); + }; + } + }, [loading]); + const [errorMessage, setErrorMessage] = useState(""); + + const [commitMutation] = + useMutation(stopWorkflowMutation); + + const stopWorkflow = () => { + setLoading(true); + commitMutation({ + variables: { id: workflowId }, + onCompleted: () => { + // Puts button on a cooldown so its not spammed + setErrorMessage(""); + }, + onError: (err) => { + setLoading(false); + setErrorMessage(err.message); + }, + }); + }; + + return ( + + + { + stopWorkflow(); + }} + color={errorMessage === "" ? "default" : "error"} + loading={loading} + > + + + + + ); +}; + +export default StopWorkflow;