mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-07 22:24:06 -05:00
Implemented ability to drag blocks
This commit is contained in:
@@ -23,6 +23,7 @@ export default function Workflow() {
|
||||
const [pan, setPan] = useState({ x: 0, y: 0 })
|
||||
const [isPanning, setIsPanning] = useState(false)
|
||||
const [startPanPos, setStartPanPos] = useState({ x: 0, y: 0 })
|
||||
const [draggedBlock, setDraggedBlock] = useState<string | null>(null)
|
||||
|
||||
// Initialize pan position after mount
|
||||
useEffect(() => {
|
||||
@@ -178,6 +179,18 @@ export default function Workflow() {
|
||||
return () => document.removeEventListener('wheel', preventDefaultZoom)
|
||||
}, [])
|
||||
|
||||
// Add this new function to handle block position updates
|
||||
const updateBlockPosition = useCallback(
|
||||
(id: string, newPosition: { x: number; y: number }) => {
|
||||
setBlocks((prevBlocks) =>
|
||||
prevBlocks.map((block) =>
|
||||
block.id === id ? { ...block, position: newPosition } : block
|
||||
)
|
||||
)
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
return (
|
||||
<div
|
||||
className="w-full h-[calc(100vh-56px)] overflow-hidden"
|
||||
@@ -208,6 +221,8 @@ export default function Workflow() {
|
||||
position={block.position}
|
||||
config={block.config}
|
||||
name={`${block.config.toolbar.title} ${index + 1}`}
|
||||
onPositionUpdate={updateBlockPosition}
|
||||
zoom={zoom}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Card } from '@/components/ui/card'
|
||||
import { BlockConfig, SubBlockConfig } from '../../types/block'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { SubBlock } from './sub-block/sub-block'
|
||||
import { useCallback, useState, MouseEvent, useEffect } from 'react'
|
||||
|
||||
export interface WorkflowBlockProps {
|
||||
id: string
|
||||
@@ -9,6 +10,8 @@ export interface WorkflowBlockProps {
|
||||
position: { x: number; y: number }
|
||||
config: BlockConfig
|
||||
name: string
|
||||
onPositionUpdate: (id: string, position: { x: number; y: number }) => void
|
||||
zoom: number
|
||||
}
|
||||
|
||||
function groupSubBlocks(subBlocks: SubBlockConfig[]) {
|
||||
@@ -42,7 +45,64 @@ export function WorkflowBlock({
|
||||
position,
|
||||
config,
|
||||
name,
|
||||
onPositionUpdate,
|
||||
zoom,
|
||||
}: WorkflowBlockProps) {
|
||||
const [isDragging, setIsDragging] = useState(false)
|
||||
const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 })
|
||||
|
||||
const handleMouseDown = useCallback(
|
||||
(e: MouseEvent) => {
|
||||
e.stopPropagation()
|
||||
setIsDragging(true)
|
||||
|
||||
// Account for the sidebar width (344px) and control bar height (56px)
|
||||
const sidebarWidth = 344 // 72px (sidebar) + 272px (toolbar)
|
||||
const controlBarHeight = 56
|
||||
|
||||
const rect = e.currentTarget.getBoundingClientRect()
|
||||
setDragOffset({
|
||||
x: (e.clientX - sidebarWidth) / zoom - position.x,
|
||||
y: (e.clientY - controlBarHeight) / zoom - position.y,
|
||||
})
|
||||
},
|
||||
[zoom, position]
|
||||
)
|
||||
|
||||
const handleMouseMove = useCallback(
|
||||
(e: MouseEvent) => {
|
||||
if (isDragging) {
|
||||
e.stopPropagation()
|
||||
|
||||
// Account for the sidebar width and control bar height
|
||||
const sidebarWidth = 344
|
||||
const controlBarHeight = 56
|
||||
|
||||
const newX = (e.clientX - sidebarWidth) / zoom - dragOffset.x
|
||||
const newY = (e.clientY - controlBarHeight) / zoom - dragOffset.y
|
||||
|
||||
onPositionUpdate(id, { x: newX, y: newY })
|
||||
}
|
||||
},
|
||||
[id, isDragging, dragOffset, onPositionUpdate, zoom]
|
||||
)
|
||||
|
||||
const handleMouseUp = useCallback(() => {
|
||||
setIsDragging(false)
|
||||
}, [])
|
||||
|
||||
// Add event listeners to handle dragging outside the block
|
||||
useEffect(() => {
|
||||
if (isDragging) {
|
||||
document.addEventListener('mousemove', handleMouseMove as any)
|
||||
document.addEventListener('mouseup', handleMouseUp)
|
||||
return () => {
|
||||
document.removeEventListener('mousemove', handleMouseMove as any)
|
||||
document.removeEventListener('mouseup', handleMouseUp)
|
||||
}
|
||||
}
|
||||
}, [isDragging, handleMouseMove, handleMouseUp])
|
||||
|
||||
const { toolbar, workflow } = config
|
||||
const subBlockRows = groupSubBlocks(workflow.subBlocks)
|
||||
|
||||
@@ -50,12 +110,14 @@ export function WorkflowBlock({
|
||||
<Card
|
||||
className={cn(
|
||||
'absolute w-[320px] shadow-md cursor-move',
|
||||
'transform -translate-x-1/2 -translate-y-1/2'
|
||||
'transform -translate-x-1/2 -translate-y-1/2',
|
||||
isDragging && 'pointer-events-none'
|
||||
)}
|
||||
style={{
|
||||
left: `${position.x}px`,
|
||||
top: `${position.y}px`,
|
||||
}}
|
||||
onMouseDown={handleMouseDown}
|
||||
>
|
||||
<div className="flex items-center gap-3 p-3 border-b">
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user