diff --git a/skyvern-frontend/src/api/utils.ts b/skyvern-frontend/src/api/utils.ts new file mode 100644 index 00000000..dfa9fe53 --- /dev/null +++ b/skyvern-frontend/src/api/utils.ts @@ -0,0 +1,13 @@ +import { Status, TaskApiResponse } from "./types"; + +const finalTaskStates: Array = [ + Status.Canceled, + Status.Completed, + Status.Terminated, + Status.TimedOut, + Status.Failed, +]; + +export function taskIsFinalized(task: TaskApiResponse) { + return finalTaskStates.includes(task.status); +} diff --git a/skyvern-frontend/src/router.tsx b/skyvern-frontend/src/router.tsx index c5bb0e63..3cdff585 100644 --- a/skyvern-frontend/src/router.tsx +++ b/skyvern-frontend/src/router.tsx @@ -17,6 +17,7 @@ import { WorkflowsPageLayout } from "./routes/workflows/WorkflowsPageLayout"; import { Workflows } from "./routes/workflows/Workflows"; import { WorkflowPage } from "./routes/workflows/WorkflowPage"; import { WorkflowRunParameters } from "./routes/workflows/WorkflowRunParameters"; +import { RetryTask } from "./routes/tasks/create/retry/RetryTask"; const router = createBrowserRouter([ { @@ -79,6 +80,10 @@ const router = createBrowserRouter([ path: ":template", element: , }, + { + path: "retry/:taskId", + element: , + }, ], }, { diff --git a/skyvern-frontend/src/routes/tasks/create/retry/RetryTask.tsx b/skyvern-frontend/src/routes/tasks/create/retry/RetryTask.tsx new file mode 100644 index 00000000..26c01310 --- /dev/null +++ b/skyvern-frontend/src/routes/tasks/create/retry/RetryTask.tsx @@ -0,0 +1,41 @@ +import { useParams } from "react-router-dom"; +import { useTaskQuery } from "../../detail/hooks/useTaskQuery"; +import { CreateNewTaskForm } from "../CreateNewTaskForm"; + +function RetryTask() { + const { taskId } = useParams(); + const { data: task, isLoading } = useTaskQuery({ id: taskId }); + + if (isLoading) { + return
Fetching task details...
; + } + + if (!task) { + return null; + } + + return ( + + ); +} + +export { RetryTask }; diff --git a/skyvern-frontend/src/routes/tasks/detail/TaskDetails.tsx b/skyvern-frontend/src/routes/tasks/detail/TaskDetails.tsx index 87d8ac7d..1ae07c80 100644 --- a/skyvern-frontend/src/routes/tasks/detail/TaskDetails.tsx +++ b/skyvern-frontend/src/routes/tasks/detail/TaskDetails.tsx @@ -19,9 +19,10 @@ import { useCredentialGetter } from "@/hooks/useCredentialGetter"; import { cn } from "@/util/utils"; import { ReloadIcon } from "@radix-ui/react-icons"; import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { NavLink, Outlet, useParams } from "react-router-dom"; +import { Link, NavLink, Outlet, useParams } from "react-router-dom"; import { TaskInfo } from "./TaskInfo"; import { useTaskQuery } from "./hooks/useTaskQuery"; +import { taskIsFinalized } from "@/api/utils"; function TaskDetails() { const { taskId } = useParams(); @@ -84,6 +85,8 @@ function TaskDetails() { const taskIsRunningOrQueued = task?.status === Status.Running || task?.status === Status.Queued; + const taskHasTerminalState = task && taskIsFinalized(task); + const showFailureReason = task?.status === Status.Failed || task?.status === Status.Terminated || @@ -138,6 +141,11 @@ function TaskDetails() { )} + {taskHasTerminalState && ( + + )} {taskIsLoading ? (
diff --git a/skyvern-frontend/src/routes/tasks/list/TaskActions.tsx b/skyvern-frontend/src/routes/tasks/list/TaskActions.tsx index c6de071d..3f43b479 100644 --- a/skyvern-frontend/src/routes/tasks/list/TaskActions.tsx +++ b/skyvern-frontend/src/routes/tasks/list/TaskActions.tsx @@ -41,6 +41,7 @@ import { TaskTemplateFormValues, taskTemplateFormSchema, } from "../create/TaskTemplateFormSchema"; +import { useNavigate } from "react-router-dom"; function createTaskTemplateRequestObject( values: TaskTemplateFormValues, @@ -88,6 +89,7 @@ function TaskActions({ task }: Props) { const [open, setOpen] = useState(false); const id = useId(); const queryClient = useQueryClient(); + const navigate = useNavigate(); const credentialGetter = useCredentialGetter(); const form = useForm({ resolver: zodResolver(taskTemplateFormSchema), @@ -154,6 +156,13 @@ function TaskActions({ task }: Props) { Save as Template + { + navigate(`/create/retry/${task.task_id}`); + }} + > + Retry Task +