diff --git a/skyvern-frontend/src/routes/workflows/editor/nodes/WaitNode/WaitNode.tsx b/skyvern-frontend/src/routes/workflows/editor/nodes/WaitNode/WaitNode.tsx index f1b89e81..c1381458 100644 --- a/skyvern-frontend/src/routes/workflows/editor/nodes/WaitNode/WaitNode.tsx +++ b/skyvern-frontend/src/routes/workflows/editor/nodes/WaitNode/WaitNode.tsx @@ -10,8 +10,8 @@ import { EditableNodeTitle } from "../components/EditableNodeTitle"; import { NodeActionMenu } from "../NodeActionMenu"; import { WorkflowBlockIcon } from "../WorkflowBlockIcon"; import type { WaitNode } from "./types"; -import { WorkflowBlockInput } from "@/components/WorkflowBlockInput"; import { useIsFirstBlockInWorkflow } from "../../hooks/useIsFirstNodeInWorkflow"; +import { Input } from "@/components/ui/input"; function WaitNode({ id, data }: NodeProps) { const { updateNodeData } = useReactFlow(); @@ -89,18 +89,10 @@ function WaitNode({ id, data }: NodeProps) { ) : null} - - { - if (!editable) { - return; - } - handleChange("waitInSeconds", Number(value)); + onChange={(event) => { + handleChange("waitInSeconds", event.target.value); }} className="nopan text-xs" /> diff --git a/skyvern-frontend/src/routes/workflows/editor/nodes/WaitNode/types.ts b/skyvern-frontend/src/routes/workflows/editor/nodes/WaitNode/types.ts index 7720aea5..9063f75c 100644 --- a/skyvern-frontend/src/routes/workflows/editor/nodes/WaitNode/types.ts +++ b/skyvern-frontend/src/routes/workflows/editor/nodes/WaitNode/types.ts @@ -2,7 +2,7 @@ import type { Node } from "@xyflow/react"; import { NodeBaseData } from "../types"; export type WaitNodeData = NodeBaseData & { - waitInSeconds: number; + waitInSeconds: string; }; export type WaitNode = Node; @@ -11,7 +11,7 @@ export const waitNodeDefaultData: WaitNodeData = { label: "", continueOnFailure: false, editable: true, - waitInSeconds: 1, + waitInSeconds: "1", }; export function isWaitNode(node: Node): node is WaitNode { diff --git a/skyvern-frontend/src/routes/workflows/editor/workflowEditorUtils.ts b/skyvern-frontend/src/routes/workflows/editor/workflowEditorUtils.ts index 8d627f5d..f215b7d4 100644 --- a/skyvern-frontend/src/routes/workflows/editor/workflowEditorUtils.ts +++ b/skyvern-frontend/src/routes/workflows/editor/workflowEditorUtils.ts @@ -82,7 +82,7 @@ import { isExtractionNode, } from "./nodes/ExtractionNode/types"; import { loginNodeDefaultData } from "./nodes/LoginNode/types"; -import { waitNodeDefaultData } from "./nodes/WaitNode/types"; +import { isWaitNode, waitNodeDefaultData } from "./nodes/WaitNode/types"; import { fileDownloadNodeDefaultData } from "./nodes/FileDownloadNode/types"; import { ProxyLocation } from "@/api/types"; import { pdfParserNodeDefaultData } from "./nodes/PDFParserNode/types"; @@ -301,7 +301,7 @@ function convertToNode( type: "wait", data: { ...commonData, - waitInSeconds: block.wait_sec ?? 1, + waitInSeconds: String(block.wait_sec ?? 1), }, }; } @@ -962,7 +962,7 @@ function getWorkflowBlock(node: WorkflowBlockNode): BlockYAML { return { ...base, block_type: "wait", - wait_sec: node.data.waitInSeconds, + wait_sec: Number(node.data.waitInSeconds), }; } case "fileDownload": { @@ -1809,6 +1809,18 @@ function getWorkflowErrors(nodes: Array): Array { } }); + const waitNodes = nodes.filter(isWaitNode); + waitNodes.forEach((node) => { + const waitTimeString = node.data.waitInSeconds.trim(); + + const decimalRegex = new RegExp("^\\d+$"); + const isNumber = decimalRegex.test(waitTimeString); + + if (!isNumber) { + errors.push(`${node.data.label}: Invalid input for wait time.`); + } + }); + return errors; }