From a59b5bcf3fb017d2e5042283ffe581b242723969 Mon Sep 17 00:00:00 2001 From: Emir Karabeg Date: Sat, 11 Jan 2025 13:10:00 -0800 Subject: [PATCH] Implemented ability to drag blocks --- app/w/[id]/workflow.tsx | 15 +++++ .../workflow-block/workflow-block.tsx | 64 ++++++++++++++++++- 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/app/w/[id]/workflow.tsx b/app/w/[id]/workflow.tsx index 449c7492e..7d021cf6c 100644 --- a/app/w/[id]/workflow.tsx +++ b/app/w/[id]/workflow.tsx @@ -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(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 (
))}
diff --git a/app/w/components/blocks/components/workflow-block/workflow-block.tsx b/app/w/components/blocks/components/workflow-block/workflow-block.tsx index 991b785b5..979b09026 100644 --- a/app/w/components/blocks/components/workflow-block/workflow-block.tsx +++ b/app/w/components/blocks/components/workflow-block/workflow-block.tsx @@ -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({