diff --git a/packages/ui/src/views/agentflowsv2/Canvas.jsx b/packages/ui/src/views/agentflowsv2/Canvas.jsx index d0b3c6ec70b..3a724666f94 100644 --- a/packages/ui/src/views/agentflowsv2/Canvas.jsx +++ b/packages/ui/src/views/agentflowsv2/Canvas.jsx @@ -42,7 +42,7 @@ import useApi from '@/hooks/useApi' import useConfirm from '@/hooks/useConfirm' // icons -import { IconX, IconRefreshAlert } from '@tabler/icons-react' +import { IconX, IconRefreshAlert, IconMagnetFilled, IconMagnetOff } from '@tabler/icons-react' // utils import { @@ -100,6 +100,7 @@ const AgentflowCanvas = () => { const [isSyncNodesButtonEnabled, setIsSyncNodesButtonEnabled] = useState(false) const [editNodeDialogOpen, setEditNodeDialogOpen] = useState(false) const [editNodeDialogProps, setEditNodeDialogProps] = useState({}) + const [isSnappingEnabled, setIsSnappingEnabled] = useState(false) const reactFlowWrapper = useRef(null) @@ -718,17 +719,30 @@ const AgentflowCanvas = () => { fitView deleteKeyCode={canvas.canvasDialogShow ? null : ['Delete']} minZoom={0.5} + snapGrid={[25, 25]} + snapToGrid={isSnappingEnabled} connectionLineComponent={ConnectionLine} > + > + + { const theme = useTheme() const navigate = useNavigate() + const customization = useSelector((state) => state.customization) const { state } = useLocation() const { flowData, name } = state @@ -36,6 +41,7 @@ const MarketplaceCanvasV2 = () => { const [edges, setEdges, onEdgesChange] = useEdgesState() const [editNodeDialogOpen, setEditNodeDialogOpen] = useState(false) const [editNodeDialogProps, setEditNodeDialogProps] = useState({}) + const [isSnappingEnabled, setIsSnappingEnabled] = useState(false) const reactFlowWrapper = useRef(null) const { setReactFlowInstance } = useContext(flowContext) @@ -108,15 +114,29 @@ const MarketplaceCanvasV2 = () => { edgeTypes={edgeTypes} fitView minZoom={0.1} + snapGrid={[25, 25]} + snapToGrid={isSnappingEnabled} > + > + + { const { confirm } = useConfirm() const dispatch = useDispatch() + const customization = useSelector((state) => state.customization) const canvas = useSelector((state) => state.canvas) const [canvasDataStore, setCanvasDataStore] = useState(canvas) const [chatflow, setChatflow] = useState(null) @@ -96,6 +97,7 @@ const Canvas = () => { const [selectedNode, setSelectedNode] = useState(null) const [isUpsertButtonEnabled, setIsUpsertButtonEnabled] = useState(false) const [isSyncNodesButtonEnabled, setIsSyncNodesButtonEnabled] = useState(false) + const [isSnappingEnabled, setIsSnappingEnabled] = useState(false) const reactFlowWrapper = useRef(null) @@ -596,16 +598,30 @@ const Canvas = () => { fitView deleteKeyCode={canvas.canvasDialogShow ? null : ['Delete']} minZoom={0.1} + snapGrid={[25, 25]} + snapToGrid={isSnappingEnabled} className='chatflow-canvas' > + > + + {isSyncNodesButtonEnabled && ( diff --git a/packages/ui/src/views/marketplaces/MarketplaceCanvas.jsx b/packages/ui/src/views/marketplaces/MarketplaceCanvas.jsx index 024ca7dbbf4..8144496b25b 100644 --- a/packages/ui/src/views/marketplaces/MarketplaceCanvas.jsx +++ b/packages/ui/src/views/marketplaces/MarketplaceCanvas.jsx @@ -1,9 +1,10 @@ -import { useEffect, useRef } from 'react' +import { useEffect, useRef, useState } from 'react' import ReactFlow, { Controls, Background, useNodesState, useEdgesState } from 'reactflow' import 'reactflow/dist/style.css' import '@/views/canvas/index.css' import { useLocation, useNavigate } from 'react-router-dom' +import { useSelector } from 'react-redux' // material-ui import { Toolbar, Box, AppBar } from '@mui/material' @@ -14,6 +15,9 @@ import MarketplaceCanvasNode from './MarketplaceCanvasNode' import MarketplaceCanvasHeader from './MarketplaceCanvasHeader' import StickyNote from '../canvas/StickyNote' +// icons +import { IconMagnetFilled, IconMagnetOff } from '@tabler/icons-react' + const nodeTypes = { customNode: MarketplaceCanvasNode, stickyNote: StickyNote } const edgeTypes = { buttonedge: '' } @@ -22,15 +26,16 @@ const edgeTypes = { buttonedge: '' } const MarketplaceCanvas = () => { const theme = useTheme() const navigate = useNavigate() + const customization = useSelector((state) => state.customization) const { state } = useLocation() - const flowData = state?.flowData || '{}' - const name = state?.name || 'Untitled' + const { flowData, name } = state // ==============================|| ReactFlow ||============================== // const [nodes, setNodes, onNodesChange] = useNodesState() const [edges, setEdges, onEdgesChange] = useEdgesState() + const [isSnappingEnabled, setIsSnappingEnabled] = useState(false) const reactFlowWrapper = useRef(null) @@ -87,15 +92,29 @@ const MarketplaceCanvas = () => { edgeTypes={edgeTypes} fitView minZoom={0.1} + snapGrid={[25, 25]} + snapToGrid={isSnappingEnabled} > + > + +