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}
>
+ >
+
+