diff --git a/skyvern-frontend/package-lock.json b/skyvern-frontend/package-lock.json index 6e2c87cf..720ae419 100644 --- a/skyvern-frontend/package-lock.json +++ b/skyvern-frontend/package-lock.json @@ -39,6 +39,7 @@ "serve-handler": "^6.1.5", "tailwind-merge": "^2.2.2", "tailwindcss-animate": "^1.0.7", + "yaml": "^2.4.2", "zod": "^3.22.4", "zustand": "^4.5.2" }, @@ -4324,6 +4325,15 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/lint-staged/node_modules/yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, "node_modules/listr2": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.1.tgz", @@ -6522,9 +6532,12 @@ "dev": true }, "node_modules/yaml": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", - "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz", + "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==", + "bin": { + "yaml": "bin.mjs" + }, "engines": { "node": ">= 14" } diff --git a/skyvern-frontend/package.json b/skyvern-frontend/package.json index 35ce0907..0996a2d3 100644 --- a/skyvern-frontend/package.json +++ b/skyvern-frontend/package.json @@ -42,11 +42,11 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-hook-form": "^7.51.1", - "react-medium-image-zoom": "^5.1.11", "react-router-dom": "^6.22.3", "serve-handler": "^6.1.5", "tailwind-merge": "^2.2.2", "tailwindcss-animate": "^1.0.7", + "yaml": "^2.4.2", "zod": "^3.22.4", "zustand": "^4.5.2" }, diff --git a/skyvern-frontend/src/api/QueryClient.ts b/skyvern-frontend/src/api/QueryClient.ts index aaaac778..3d0ffb9d 100644 --- a/skyvern-frontend/src/api/QueryClient.ts +++ b/skyvern-frontend/src/api/QueryClient.ts @@ -3,7 +3,7 @@ import { QueryClient } from "@tanstack/react-query"; const queryClient = new QueryClient({ defaultOptions: { queries: { - staleTime: 1000 * 60 * 5, // 5 minutes + staleTime: Infinity, }, }, }); diff --git a/skyvern-frontend/src/api/types.ts b/skyvern-frontend/src/api/types.ts index 70df7e84..373db475 100644 --- a/skyvern-frontend/src/api/types.ts +++ b/skyvern-frontend/src/api/types.ts @@ -65,7 +65,7 @@ export type TaskApiResponse = { navigation_payload: string | object; // stringified JSON error_code_mapping: null; proxy_location: string; - extracted_information_schema: string; + extracted_information_schema: string | object; }; task_id: string; status: Status; @@ -101,3 +101,50 @@ export type ApiKeyApiResponse = { token_type: string; valid: boolean; }; + +export type WorkflowParameter = { + workflow_parameter_id: string; + workflow_parameter_type?: string; + key: string; + description: string | null; + workflow_id: string; + parameter_type: "workflow"; // TODO other values + default_value?: string; + created_at: string | null; + modified_at: string | null; + deleted_at: string | null; +}; + +export type WorkflowBlock = { + label: string; + block_type: string; + output_parameter?: null; + continue_on_failure: boolean; + url: string; + title: string; + navigation_goal: string; + data_extraction_goal: string; + data_schema: object | null; + error_code_mapping: null; // ? + max_retries: number | null; + max_steps_per_run: number | null; + parameters: []; // ? +}; + +export type WorkflowApiResponse = { + workflow_id: string; + organization_id: string; + title: string; + workflow_permanent_id: string; + version: number; + description: string; + workflow_definition: { + parameters: Array; + blocks: Array; + }; + proxy_location: string; + webhook_callback_url: string; + created_at: string; + modified_at: string; + deleted_at: string | null; +}; diff --git a/skyvern-frontend/src/components/ui/dropdown-menu.tsx b/skyvern-frontend/src/components/ui/dropdown-menu.tsx index 0759c1a3..60e73e35 100644 --- a/skyvern-frontend/src/components/ui/dropdown-menu.tsx +++ b/skyvern-frontend/src/components/ui/dropdown-menu.tsx @@ -86,7 +86,7 @@ const DropdownMenuItem = React.forwardRef< , + element: , + children: [ + { + index: true, + element: , + }, + { + path: ":template", + element: , + }, + ], }, { path: "settings", diff --git a/skyvern-frontend/src/routes/tasks/create/CreateNewTask.tsx b/skyvern-frontend/src/routes/tasks/create/CreateNewTask.tsx deleted file mode 100644 index e5a736d7..00000000 --- a/skyvern-frontend/src/routes/tasks/create/CreateNewTask.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { useId, useState } from "react"; -import { CreateNewTaskForm } from "./CreateNewTaskForm"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/components/ui/select"; -import { SampleCase } from "../types"; -import { getSampleForInitialFormValues } from "../data/sampleTaskData"; -import { Label } from "@/components/ui/label"; -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, -} from "@/components/ui/card"; - -function CreateNewTask() { - const [selectedCase, setSelectedCase] = useState("geico"); - const caseInputId = useId(); - - return ( -
-
- - -
- - - Create a new task - - Fill out the form below to create a new task. You can select a - sample from above to prefill the form with sample data. - - - - - - -
- ); -} - -export { CreateNewTask }; diff --git a/skyvern-frontend/src/routes/tasks/create/CreateNewTaskForm.tsx b/skyvern-frontend/src/routes/tasks/create/CreateNewTaskForm.tsx index a72bd45d..ca7804fe 100644 --- a/skyvern-frontend/src/routes/tasks/create/CreateNewTaskForm.tsx +++ b/skyvern-frontend/src/routes/tasks/create/CreateNewTaskForm.tsx @@ -23,7 +23,7 @@ import { Textarea } from "@/components/ui/textarea"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { getClient } from "@/api/AxiosClient"; import { useToast } from "@/components/ui/use-toast"; -import { InfoCircledIcon } from "@radix-ui/react-icons"; +import { InfoCircledIcon, ReloadIcon } from "@radix-ui/react-icons"; import { Tooltip, TooltipContent, @@ -41,11 +41,11 @@ const createNewTaskFormSchema = z.object({ url: z.string().url({ message: "Invalid URL", }), - webhookCallbackUrl: z.string().optional(), // url maybe, but shouldn't be validated as one - navigationGoal: z.string().optional(), - dataExtractionGoal: z.string().optional(), - navigationPayload: z.string().optional(), - extractedInformationSchema: z.string().optional(), + webhookCallbackUrl: z.string().or(z.null()).optional(), // url maybe, but shouldn't be validated as one + navigationGoal: z.string().or(z.null()).optional(), + dataExtractionGoal: z.string().or(z.null()).optional(), + navigationPayload: z.string().or(z.null()).optional(), + extractedInformationSchema: z.string().or(z.null()).optional(), }); export type CreateNewTaskFormValues = z.infer; @@ -62,8 +62,8 @@ function createTaskRequestObject(formValues: CreateNewTaskFormValues) { data_extraction_goal: formValues.dataExtractionGoal ?? "", proxy_location: "NONE", error_code_mapping: null, - navigation_payload: formValues.navigationPayload ?? "", - extracted_information_schema: formValues.extractedInformationSchema ?? "", + navigation_payload: formValues.navigationPayload, + extracted_information_schema: formValues.extractedInformationSchema, }; } @@ -90,7 +90,7 @@ function CreateNewTaskForm({ initialValues }: Props) { onError: (error) => { toast({ variant: "destructive", - title: "Error", + title: "There was an error creating the task.", description: error.message, }); }, @@ -126,7 +126,7 @@ function CreateNewTaskForm({ initialValues }: Props) {
- URL* + URL * @@ -167,7 +167,11 @@ function CreateNewTaskForm({ initialValues }: Props) {
- +
@@ -194,7 +198,12 @@ function CreateNewTaskForm({ initialValues }: Props) { -