From 45e0a5fa72da691e7e4e582c39390adfd80291ae Mon Sep 17 00:00:00 2001 From: Shuchang Zheng Date: Wed, 23 Oct 2024 19:40:03 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'skyvern-fronte?= =?UTF-8?q?nd/src/'=20with=20remote=20'skyvern-frontend/src/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > [!IMPORTANT] > Add `webhookCallbackUrl` field to `RunWorkflowForm` with validation and UI changes in `RunWorkflowForm.tsx`. > > - **Behavior**: > - Add `webhookCallbackUrl` field to `RunWorkflowForm` in `RunWorkflowForm.tsx`. > - Update form submission to include `webhookCallbackUrl` in the request body if provided. > - **Validation**: > - Add URL validation for `webhookCallbackUrl` using `zod` schema. > - **UI**: > - Add new section "Advanced Settings" for `webhookCallbackUrl` input in the form. > > This description was created by [Ellipsis](https://www.ellipsis.dev?ref=Skyvern-AI%2Fskyvern-cloud&utm_source=github&utm_medium=referral) for 33008e62a3f1d4d5da1a31d4906b4301d0f8ba4c. It will automatically update as commits are pushed. --- .../src/routes/workflows/RunWorkflowForm.tsx | 216 ++++++++++++------ 1 file changed, 146 insertions(+), 70 deletions(-) diff --git a/skyvern-frontend/src/routes/workflows/RunWorkflowForm.tsx b/skyvern-frontend/src/routes/workflows/RunWorkflowForm.tsx index cf21b103fd..d6c932382d 100644 --- a/skyvern-frontend/src/routes/workflows/RunWorkflowForm.tsx +++ b/skyvern-frontend/src/routes/workflows/RunWorkflowForm.tsx @@ -5,6 +5,7 @@ import { FormField, FormItem, FormLabel, + FormMessage, } from "@/components/ui/form"; import { useCredentialGetter } from "@/hooks/useCredentialGetter"; import { useMutation, useQueryClient } from "@tanstack/react-query"; @@ -20,6 +21,8 @@ import { apiBaseUrl } from "@/util/env"; import { useApiCredential } from "@/hooks/useApiCredential"; import { copyText } from "@/util/copyText"; import { WorkflowParameter } from "./types/workflowTypes"; +import { Input } from "@/components/ui/input"; +import { z } from "zod"; type Props = { workflowParameters: Array; @@ -61,20 +64,33 @@ function RunWorkflowForm({ workflowParameters, initialValues }: Props) { const { workflowPermanentId } = useParams(); const credentialGetter = useCredentialGetter(); const queryClient = useQueryClient(); - const form = useForm({ - defaultValues: initialValues, + const form = useForm>({ + defaultValues: { ...initialValues, webhookCallbackUrl: null }, }); const apiCredential = useApiCredential(); const runWorkflowMutation = useMutation({ mutationFn: async (values: Record) => { const client = await getClient(credentialGetter); + + const { webhookCallbackUrl, ...parameters } = values; + + const body: { + data: Record; + proxy_location: string; + webhook_callback_url?: string; + } = { + data: parameters, + proxy_location: "RESIDENTIAL", + }; + + if (webhookCallbackUrl) { + body.webhook_callback_url = webhookCallbackUrl as string; + } + return client.post( `/workflows/${workflowPermanentId}/run`, - { - data: values, - proxy_location: "RESIDENTIAL", - }, + body, ); }, onSuccess: (response) => { @@ -114,75 +130,135 @@ function RunWorkflowForm({ workflowParameters, initialValues }: Props) { return (
- - {workflowParameters?.map((parameter) => { - return ( - { - if ( - parameter.workflow_parameter_type === "json" && - typeof value === "string" - ) { - try { - JSON.parse(value); - return true; - } catch (e) { - return "Invalid JSON"; + +
+
+

Workflow Parameters

+
+ {workflowParameters?.map((parameter) => { + return ( + { + if ( + parameter.workflow_parameter_type === "json" && + typeof value === "string" + ) { + try { + JSON.parse(value); + return true; + } catch (e) { + return "Invalid JSON"; + } } - } - if (value === null) { - return "This field is required"; - } - }, - }} - render={({ field }) => { - return ( - -
- -
-
- {parameter.key} - - {parameter.workflow_parameter_type} - + if (value === null) { + return "This field is required"; + } + }, + }} + render={({ field }) => { + return ( + +
+ +
+
+ {parameter.key} + + {parameter.workflow_parameter_type} + +
+

+ {parameter.description} +

-

- {parameter.description} -

+
+
+ + + + {form.formState.errors[parameter.key] && ( +
+ {form.formState.errors[parameter.key]?.message} +
+ )}
- -
- - - - {form.formState.errors[parameter.key] && ( -
- {form.formState.errors[parameter.key]?.message} -
- )}
+ + ); + }} + /> + ); + })} + {workflowParameters.length === 0 && ( +
No workflow parameters for this workflow.
+ )} +
+ +
+
+

Advanced Settings

+
+ { + if (value === null) { + return; + } + if (typeof value !== "string") { + return "Invalid URL"; + } + const urlSchema = z.string().url({ message: "Invalid URL" }); + const { success } = urlSchema.safeParse(value); + if (!success) { + return "Invalid URL"; + } + }, + }} + render={({ field }) => { + return ( + +
+ +
+
+ Webhook Callback URL +
+

+ The URL of a webhook endpoint to send the details of + the workflow result. +

+
+
+
+ + + +
- - ); - }} - /> - ); - })} - {workflowParameters.length === 0 && ( -
No workflow parameters for this workflow.
- )} +
+
+ ); + }} + /> +
+