Skip to content

Commit

Permalink
🔄 synced local 'skyvern-frontend/src/' with remote 'skyvern-frontend/…
Browse files Browse the repository at this point in the history
…src/'

<!-- ELLIPSIS_HIDDEN -->

| 🚀 | This description was created by [Ellipsis](https://www.ellipsis.dev) for commit bcb9334de610d5cb11b2e5d7fe074855eefb937f  |
|--------|--------|

### Summary:
This PR introduces editable workflows in the Skyvern frontend, enhancing UI components and state management for workflow and parameter editing.

**Key points**:
- Introduces editable workflows in Skyvern frontend.
- Adds `GarbageIcon`, `SaveIcon`, and `Popover` components.
- Updates `FlowRenderer` for node and edge management.
- Implements `WorkflowEditor` for workflow fetching and saving logic.
- Adds `WorkflowHeader` with save and parameter toggle functionality.
- Creates `WorkflowParametersStateContext` for parameter state management.
- Defines `REACT_FLOW_EDGE_Z_INDEX` for edge layering.
- Develops `EdgeWithAddButton` to add nodes between edges.
- Updates node components for editability and data changes.
- Adds `WorkflowNodeLibraryPanel` for node selection.
- Implements `WorkflowParameterAddPanel` and `WorkflowParameterEditPanel`.
- Utilizes `zustand` for state management.
- Enhances `WorkflowParametersPanel` for adding/editing workflow and credential parameters.
- Adds `DropdownMenu` for parameter type selection.
- Enhances state management with `operationPanelState`.

----
Generated with ❤️ by [ellipsis.dev](https://www.ellipsis.dev)

<!-- ELLIPSIS_HIDDEN -->
  • Loading branch information
ykeremy committed Sep 9, 2024
1 parent c85d868 commit 1dd88c9
Show file tree
Hide file tree
Showing 43 changed files with 2,293 additions and 321 deletions.
24 changes: 24 additions & 0 deletions skyvern-frontend/src/components/icons/GarbageIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
type Props = {
className: string;
};

function GarbageIcon({ className }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className={className}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"
/>
</svg>
);
}

export { GarbageIcon };
21 changes: 21 additions & 0 deletions skyvern-frontend/src/components/icons/SaveIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
function SaveIcon() {
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7 3V6.4C7 6.96005 7 7.24008 7.10899 7.45399C7.20487 7.64215 7.35785 7.79513 7.54601 7.89101C7.75992 8 8.03995 8 8.6 8H15.4C15.9601 8 16.2401 8 16.454 7.89101C16.6422 7.79513 16.7951 7.64215 16.891 7.45399C17 7.24008 17 6.96005 17 6.4V4M17 21V14.6C17 14.0399 17 13.7599 16.891 13.546C16.7951 13.3578 16.6422 13.2049 16.454 13.109C16.2401 13 15.9601 13 15.4 13H8.6C8.03995 13 7.75992 13 7.54601 13.109C7.35785 13.2049 7.20487 13.3578 7.10899 13.546C7 13.7599 7 14.0399 7 14.6V21M21 9.32548V16.2C21 17.8802 21 18.7202 20.673 19.362C20.3854 19.9265 19.9265 20.3854 19.362 20.673C18.7202 21 17.8802 21 16.2 21H7.8C6.11984 21 5.27976 21 4.63803 20.673C4.07354 20.3854 3.6146 19.9265 3.32698 19.362C3 18.7202 3 17.8802 3 16.2V7.8C3 6.11984 3 5.27976 3.32698 4.63803C3.6146 4.07354 4.07354 3.6146 4.63803 3.32698C5.27976 3 6.11984 3 7.8 3H14.6745C15.1637 3 15.4083 3 15.6385 3.05526C15.8425 3.10425 16.0376 3.18506 16.2166 3.29472C16.4184 3.4184 16.5914 3.59135 16.9373 3.93726L20.0627 7.06274C20.4086 7.40865 20.5816 7.5816 20.7053 7.78343C20.8149 7.96237 20.8957 8.15746 20.9447 8.36154C21 8.59171 21 8.8363 21 9.32548Z"
stroke="#F8FAFC"
strokeWidth="1.6"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}

export { SaveIcon };
31 changes: 31 additions & 0 deletions skyvern-frontend/src/components/ui/popover.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as React from "react";
import * as PopoverPrimitive from "@radix-ui/react-popover";

import { cn } from "@/util/utils";

const Popover = PopoverPrimitive.Root;

const PopoverTrigger = PopoverPrimitive.Trigger;

const PopoverAnchor = PopoverPrimitive.Anchor;

const PopoverContent = React.forwardRef<
React.ElementRef<typeof PopoverPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
<PopoverPrimitive.Portal>
<PopoverPrimitive.Content
ref={ref}
align={align}
sideOffset={sideOffset}
className={cn(
"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
)}
{...props}
/>
</PopoverPrimitive.Portal>
));
PopoverContent.displayName = PopoverPrimitive.Content.displayName;

export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };
52 changes: 50 additions & 2 deletions skyvern-frontend/src/routes/workflows/Workflows.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,29 @@ import {
CounterClockwiseClockIcon,
Pencil2Icon,
PlayIcon,
PlusIcon,
ReloadIcon,
} from "@radix-ui/react-icons";
import { useQuery } from "@tanstack/react-query";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useNavigate, useSearchParams } from "react-router-dom";
import { WorkflowsBetaAlertCard } from "./WorkflowsBetaAlertCard";
import { WorkflowTitle } from "./WorkflowTitle";
import { WorkflowCreateYAMLRequest } from "./types/workflowYamlTypes";
import { stringify as convertToYAML } from "yaml";

const emptyWorkflowRequest: WorkflowCreateYAMLRequest = {
title: "New Workflow",
description: "",
workflow_definition: {
blocks: [],
parameters: [],
},
};

function Workflows() {
const credentialGetter = useCredentialGetter();
const navigate = useNavigate();
const queryClient = useQueryClient();
const [searchParams, setSearchParams] = useSearchParams();
const workflowsPage = searchParams.get("workflowsPage")
? Number(searchParams.get("workflowsPage"))
Expand Down Expand Up @@ -79,6 +93,27 @@ function Workflows() {
},
});

const createNewWorkflowMutation = useMutation({
mutationFn: async () => {
const client = await getClient(credentialGetter);
const yaml = convertToYAML(emptyWorkflowRequest);
return client.post<
typeof emptyWorkflowRequest,
{ data: WorkflowApiResponse }
>("/workflows", yaml, {
headers: {
"Content-Type": "text/plain",
},
});
},
onSuccess: (response) => {
queryClient.invalidateQueries({
queryKey: ["workflows"],
});
navigate(`/workflows/${response.data.workflow_permanent_id}`);
},
});

if (workflows?.length === 0 && workflowsPage === 1) {
return <WorkflowsBetaAlertCard />;
}
Expand Down Expand Up @@ -115,8 +150,21 @@ function Workflows() {

return (
<div className="space-y-8">
<header>
<header className="flex items-center justify-between">
<h1 className="text-2xl font-semibold">Workflows</h1>
<Button
disabled={createNewWorkflowMutation.isPending}
onClick={() => {
createNewWorkflowMutation.mutate();
}}
>
{createNewWorkflowMutation.isPending ? (
<ReloadIcon className="mr-2 h-4 w-4 animate-spin" />
) : (
<PlusIcon className="mr-2 h-4 w-4" />
)}
Create Workflow
</Button>
</header>
<div className="rounded-md border">
<Table>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import CodeMirror from "@uiw/react-codemirror";
import CodeMirror, { EditorView } from "@uiw/react-codemirror";
import { json } from "@codemirror/lang-json";
import { python } from "@codemirror/lang-python";
import { tokyoNightStorm } from "@uiw/codemirror-theme-tokyo-night-storm";
Expand All @@ -22,7 +22,10 @@ function CodeEditor({
className,
fontSize = 8,
}: Props) {
const extensions = language === "json" ? [json()] : [python()];
const extensions =
language === "json"
? [json(), EditorView.lineWrapping]
: [python(), EditorView.lineWrapping];
return (
<CodeMirror
value={value}
Expand Down
Loading

0 comments on commit 1dd88c9

Please sign in to comment.