diff --git a/frontend/src/components/workspace/canvas/action-node.tsx b/frontend/src/components/workspace/canvas/action-node.tsx index 36507ae6a..04250aa61 100644 --- a/frontend/src/components/workspace/canvas/action-node.tsx +++ b/frontend/src/components/workspace/canvas/action-node.tsx @@ -7,7 +7,6 @@ import { CheckSquare, ChevronDownIcon, CircleCheckBigIcon, - LayoutListIcon, Container, Copy, Delete, @@ -16,6 +15,7 @@ import { GitCompareArrows, Globe, Languages, + LayoutListIcon, LucideIcon, Mail, Regex, @@ -30,7 +30,7 @@ import { Handle, NodeProps, Position, useNodeId, type Node } from "reactflow" import { type ActionType } from "@/types/schemas" import { cn, copyToClipboard, slugify } from "@/lib/utils" -import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" +import { Avatar, AvatarFallback } from "@/components/ui/avatar" import { Button } from "@/components/ui/button" import { Card, @@ -107,7 +107,7 @@ export function getTileColor( return defaultColor } -const typeToNodeSubtitle: Record = { +export const typeToNodeSubtitle: Record = { webhook: "Webhook", http_request: "HTTP Request", data_transform: "Data Transform", @@ -135,7 +135,6 @@ export default React.memo(function ActionNode({ const tileIcon = tileIconMapping[type] ?? Sparkles const isConfiguredMessage = isConfigured ? "ready" : "missing inputs" const { toast } = useToast() - const avatarImageAlt = `${type}-${title}` const handleCopyToClipboard = useCallback(() => { const slug = slugify(title) @@ -175,10 +174,9 @@ export default React.memo(function ActionNode({ return ( - +
- {React.createElement(tileIcon, { className: "h-5 w-5" })} @@ -230,11 +228,11 @@ export default React.memo(function ActionNode({
{isConfigured ? ( - + ) : ( - + )} - {isConfiguredMessage} + {isConfiguredMessage}
diff --git a/frontend/src/components/workspace/panel/action/form.tsx b/frontend/src/components/workspace/panel/action/form.tsx index 1c3b5197c..4e3309bf3 100644 --- a/frontend/src/components/workspace/panel/action/form.tsx +++ b/frontend/src/components/workspace/panel/action/form.tsx @@ -2,16 +2,29 @@ import React from "react" import { useWorkflowBuilder } from "@/providers/builder" import { zodResolver } from "@hookform/resolvers/zod" import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query" -import { CircleIcon, Save } from "lucide-react" +import { + BracesIcon, + LayoutListIcon, + SaveIcon, + SettingsIcon, + Sparkles, + ViewIcon, +} from "lucide-react" import { FormProvider, useForm } from "react-hook-form" import SyntaxHighlighter from "react-syntax-highlighter" -import { atomOneDark } from "react-syntax-highlighter/dist/esm/styles/hljs" +import { atomOneLight } from "react-syntax-highlighter/dist/cjs/styles/hljs" import { z } from "zod" import { Action, type ActionType } from "@/types/schemas" import { getActionById, updateAction } from "@/lib/flow" import { cn } from "@/lib/utils" -import { Badge } from "@/components/ui/badge" +import { + Accordion, + AccordionContent, + AccordionItem, + AccordionTrigger, +} from "@/components/ui/accordion" +import { Avatar, AvatarFallback } from "@/components/ui/avatar" import { Button } from "@/components/ui/button" import { FormControl, @@ -22,6 +35,7 @@ import { } from "@/components/ui/form" import { Input } from "@/components/ui/input" import { Separator } from "@/components/ui/separator" +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { Textarea } from "@/components/ui/textarea" import { Tooltip, @@ -29,10 +43,14 @@ import { TooltipTrigger, } from "@/components/ui/tooltip" import { toast } from "@/components/ui/use-toast" -import { CollapsibleSection } from "@/components/collapsible-section" import { FormLoading } from "@/components/loading/form" import { AlertNotification } from "@/components/notifications" -import { ActionNodeType } from "@/components/workspace/canvas/action-node" +import { + ActionNodeType, + getTileColor, + tileIconMapping, + typeToNodeSubtitle, +} from "@/components/workspace/canvas/action-node" import { baseActionSchema, getSubActionSchema, @@ -114,11 +132,18 @@ export function ActionForm({ }, }) // Set the initial form values + // TODO: More robust handling of undefined values + const type = action?.type ?? "webhook" + const title = action?.title ?? "" + const description = action?.description ?? "" + const subtitle = typeToNodeSubtitle[type as keyof typeof typeToNodeSubtitle] + const tileIcon = tileIconMapping[actionType] ?? Sparkles + const methods = useForm({ resolver: zodResolver(schema), values: { - title: action?.title ?? "", - description: action?.description ?? "", + title: title, + description: description, ...(action?.inputs ? processInputs(action.inputs) : {}), // Unpack the inputs object }, }) @@ -169,197 +194,208 @@ export function ActionForm({ mutate(values) }) - const status = "online" return ( -
+
-
-
-
-

Action Status

-
- - +
+
+

+
+ + + {React.createElement(tileIcon, { className: "h-5 w-5" })} + + +
+
+
+
+ {title} + {type.startsWith("llm.") && ( + + )} +
+
+

+ {description || subtitle} +

+
+
+
+

+
+
+ + + + + Save + +
+
+ + {/* Metadata */} + + + +
+ + General +
+
+ +
+ ( + + Name + + + + + )} /> - ( + + Description + +