diff --git a/skyvern-frontend/src/api/types.ts b/skyvern-frontend/src/api/types.ts index 9371b6b8a..9c069723a 100644 --- a/skyvern-frontend/src/api/types.ts +++ b/skyvern-frontend/src/api/types.ts @@ -563,6 +563,7 @@ export type TaskRunListItem = { finished_at: string | null; created_at: string; workflow_permanent_id: string | null; + workflow_deleted: boolean; script_run: boolean; searchable_text: string | null; }; diff --git a/skyvern-frontend/src/routes/history/RunHistory.tsx b/skyvern-frontend/src/routes/history/RunHistory.tsx index 6003bbb08..367aa3a48 100644 --- a/skyvern-frontend/src/routes/history/RunHistory.tsx +++ b/skyvern-frontend/src/routes/history/RunHistory.tsx @@ -1,4 +1,8 @@ -import { LightningBoltIcon, MixerHorizontalIcon } from "@radix-ui/react-icons"; +import { + ExclamationTriangleIcon, + LightningBoltIcon, + MixerHorizontalIcon, +} from "@radix-ui/react-icons"; import { Select, @@ -192,16 +196,31 @@ function RunHistory() { const isExpanded = isWorkflowRun && expandedRows.has(run.run_id); const navPath = getRunNavigationPath(run); - const titleContent = run.script_run ? ( -
- - - - {run.title ?? ""} -
- ) : ( - (run.title ?? "") - ); + const titleContent = + run.script_run || run.workflow_deleted ? ( +
+ {run.script_run && ( + + + + )} + {run.workflow_deleted && ( + + + + )} + + {run.title ?? ""} + +
+ ) : ( + (run.title ?? "") + ); return ( diff --git a/skyvern-frontend/src/routes/workflows/WorkflowRun.tsx b/skyvern-frontend/src/routes/workflows/WorkflowRun.tsx index 453426a7a..238a29e3a 100644 --- a/skyvern-frontend/src/routes/workflows/WorkflowRun.tsx +++ b/skyvern-frontend/src/routes/workflows/WorkflowRun.tsx @@ -80,6 +80,7 @@ function WorkflowRun() { const workflowPermanentId = workflow?.workflow_permanent_id; const cacheKey = workflow?.cache_key ?? ""; const isFinalized = workflowRun ? statusIsFinalized(workflowRun) : null; + const isWorkflowDeleted = Boolean(workflow?.deleted_at); const [hasPublishedCode, setHasPublishedCode] = useState(false); @@ -93,7 +94,7 @@ function WorkflowRun() { cacheKey, debounceMs: 100, page: 1, - workflowPermanentId, + workflowPermanentId: isWorkflowDeleted ? undefined : workflowPermanentId, }); useEffect(() => { @@ -106,7 +107,7 @@ function WorkflowRun() { const { data: blockScriptsPublished } = useBlockScriptsQuery({ cacheKey, cacheKeyValue, - workflowPermanentId, + workflowPermanentId: isWorkflowDeleted ? undefined : workflowPermanentId, pollIntervalMs: !hasPublishedCode && !isFinalized ? 3000 : undefined, status: "published", workflowRunId: workflowRun?.workflow_run_id, @@ -159,7 +160,7 @@ function WorkflowRun() { const { data: fallbackEpisodes } = useFallbackEpisodesQuery({ workflowPermanentId, workflowRunId: workflowRun?.workflow_run_id, - enabled: workflowRunIsFinalized === true, + enabled: workflowRunIsFinalized === true && !isWorkflowDeleted, }); const finallyBlockLabel = workflow?.workflow_definition?.finally_block_label ?? null; @@ -176,6 +177,8 @@ function WorkflowRun() { const title = workflowRunIsLoading ? ( + ) : isWorkflowDeleted ? ( +

{workflow!.title}

) : (

{workflowRunId}

{workflowRun && - (workflowRun.started_at || workflowRun.finished_at) && ( -
+ (workflowRun.started_at || + workflowRun.finished_at || + isWorkflowDeleted) && ( +
{workflowRun.started_at && ( Started: {basicLocalTimeFormat(workflowRun.started_at)} @@ -374,6 +379,12 @@ function WorkflowRun() { Finished: {basicLocalTimeFormat(workflowRun.finished_at)} )} + {isWorkflowDeleted && ( + + Workflow deleted on{" "} + {basicLocalTimeFormat(workflow!.deleted_at!)} + + )}
)} {workflowRun?.browser_session_id && ( @@ -387,51 +398,57 @@ function WorkflowRun() {
- { - // Build headers - x-max-steps-override is optional and can be added manually if needed - const headers: Record = { - "Content-Type": "application/json", - "x-api-key": apiCredential ?? "", - }; + {!isWorkflowDeleted && ( + <> + { + // Build headers - x-max-steps-override is optional and can be added manually if needed + const headers: Record = { + "Content-Type": "application/json", + "x-api-key": apiCredential ?? "", + }; - const body: Record = { - workflow_id: workflowPermanentId, - parameters: workflowRun?.parameters, - proxy_location: proxyLocation, - }; + const body: Record = { + workflow_id: workflowPermanentId, + parameters: workflowRun?.parameters, + proxy_location: proxyLocation, + }; - if (maxScreenshotScrolls !== null) { - body.max_screenshot_scrolls = maxScreenshotScrolls; - } + if (maxScreenshotScrolls !== null) { + body.max_screenshot_scrolls = maxScreenshotScrolls; + } - if (workflowRun?.webhook_callback_url) { - body.webhook_url = workflowRun.webhook_callback_url; - } + if (workflowRun?.webhook_callback_url) { + body.webhook_url = workflowRun.webhook_callback_url; + } - return { - method: "POST", - url: `${runsApiBaseUrl}/run/workflows`, - body, - headers, - } satisfies ApiCommandOptions; - }} - webhookDisabled={workflowRunIsLoading || !workflowRunIsFinalized} - onTestWebhook={() => setReplayOpen(true)} - /> - - + return { + method: "POST", + url: `${runsApiBaseUrl}/run/workflows`, + body, + headers, + } satisfies ApiCommandOptions; + }} + webhookDisabled={ + workflowRunIsLoading || !workflowRunIsFinalized + } + onTestWebhook={() => setReplayOpen(true)} + /> + + + + )} {workflowRunIsCancellable && ( @@ -464,7 +481,7 @@ function WorkflowRun() { )} - {workflowRunIsFinalized && !isTaskv2Run && ( + {workflowRunIsFinalized && !isTaskv2Run && !isWorkflowDeleted && (