diff --git a/autogpt_platform/frontend/src/app/(platform)/build/components/FlowEditor/nodes/CustomNode/StandardNodeBlock.tsx b/autogpt_platform/frontend/src/app/(platform)/build/components/FlowEditor/nodes/CustomNode/StandardNodeBlock.tsx index bec2aee47d..49bf95ae5f 100644 --- a/autogpt_platform/frontend/src/app/(platform)/build/components/FlowEditor/nodes/CustomNode/StandardNodeBlock.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/build/components/FlowEditor/nodes/CustomNode/StandardNodeBlock.tsx @@ -11,6 +11,7 @@ import { NodeBadges } from "./components/NodeBadges"; import { NodeExecutionBadge } from "./components/NodeExecutionBadge"; import { nodeStyleBasedOnStatus } from "./helpers"; import { NodeDataRenderer } from "./components/NodeOutput/NodeOutput"; +import { NodeContextMenu } from "./components/NodeContextMenu"; type StandardNodeBlockType = { data: CustomNodeData; @@ -37,24 +38,30 @@ export const StandardNodeBlock = ({ >
{/* Header */} -
- {/* Upper section */} -
- - {beautifyString(data.title)} - - - #{nodeId.split("-")[0]} - -
- {/* Lower section */} -
- - +
+
+ {/* Upper section */} +
+ + {beautifyString(data.title)} + + + #{nodeId.split("-")[0]} + +
+ {/* Lower section */} +
+ + +
+
{/* Input Handles */}
diff --git a/autogpt_platform/frontend/src/app/(platform)/build/components/FlowEditor/nodes/CustomNode/components/NodeContextMenu.tsx b/autogpt_platform/frontend/src/app/(platform)/build/components/FlowEditor/nodes/CustomNode/components/NodeContextMenu.tsx new file mode 100644 index 0000000000..c3f913d372 --- /dev/null +++ b/autogpt_platform/frontend/src/app/(platform)/build/components/FlowEditor/nodes/CustomNode/components/NodeContextMenu.tsx @@ -0,0 +1,75 @@ +import { Separator } from "@/components/__legacy__/ui/separator"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/molecules/DropdownMenu/DropdownMenu"; +import { DotsThreeOutlineVerticalIcon } from "@phosphor-icons/react"; +import { Copy, Trash2, ExternalLink } from "lucide-react"; +import { useNodeStore } from "@/app/(platform)/build/stores/nodeStore"; +import { useCopyPasteStore } from "@/app/(platform)/build/stores/copyPasteStore"; +import { useReactFlow } from "@xyflow/react"; + +export const NodeContextMenu = ({ + nodeId, + subGraphID, +}: { + nodeId: string; + subGraphID?: string; +}) => { + const { deleteElements } = useReactFlow(); + + const handleCopy = () => { + useNodeStore.setState((state) => ({ + nodes: state.nodes.map((node) => ({ + ...node, + selected: node.id === nodeId, + })), + })); + + useCopyPasteStore.getState().pasteNodes(); + }; + + const handleDelete = () => { + deleteElements({ nodes: [{ id: nodeId }] }); + }; + + return ( + + + + + + + + Copy + + + {subGraphID && ( + window.open(`/build?flowID=${subGraphID}`)} + className="hover:rounded-xlarge" + > + + Open Agent + + )} + + + + + + Delete + + + + ); +};