Files
AutoMetabuilder/frontend/autometabuilder/hooks/useCanvasDragDrop.ts
copilot-swe-agent[bot] 6e9ff896e7 Phase 9: Implement atomic hooks-based workflow canvas components
- Created custom hooks: useWorkflowGraph, useWorkflowPlugins, usePluginSearch, useTabNavigation
- Decomposed canvas logic into: useCanvasNodes, useCanvasEdges, useCanvasDragDrop
- Built atomic node components: NodeHeader, NodeBody, NodePorts
- Created canvas UI components: CanvasInfoPanel, CanvasHintPanel
- Split builder into: LoadingState, ErrorState, WorkflowBuilderHeader, WorkflowBuilderTabs, WorkflowBuilderContent
- Added React Flow for n8n-style visual canvas with drag-and-drop
- All components now under 100 LOC following PROMPT.md guidelines

Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
2026-01-10 12:25:36 +00:00

55 lines
1.5 KiB
TypeScript

import { useCallback, DragEvent, useRef } from "react";
import { Node, useReactFlow } from "reactflow";
import { WorkflowPluginMap } from "../lib/types";
export function useCanvasDragDrop(
plugins: WorkflowPluginMap,
t: (key: string, fallback?: string) => string,
onNodeAdd: (node: Node) => void
) {
const reactFlowWrapper = useRef<HTMLDivElement>(null);
const { project } = useReactFlow();
const onDragOver = useCallback((event: DragEvent<HTMLDivElement>) => {
event.preventDefault();
event.dataTransfer.dropEffect = "move";
}, []);
const onDrop = useCallback(
(event: DragEvent<HTMLDivElement>) => {
event.preventDefault();
const type = event.dataTransfer.getData("application/reactflow");
if (!type || !reactFlowWrapper.current) {
return;
}
const reactFlowBounds = reactFlowWrapper.current.getBoundingClientRect();
const position = project({
x: event.clientX - reactFlowBounds.left,
y: event.clientY - reactFlowBounds.top,
});
const plugin = plugins[type] || {};
const newNode: Node = {
id: `node-${Date.now()}`,
type: "workflow",
position,
data: {
label: plugin.label ? t(plugin.label, type) : type,
type,
inputs: {},
outputs: {},
plugin,
t,
},
};
onNodeAdd(newNode);
},
[plugins, project, t, onNodeAdd]
);
return { onDragOver, onDrop, reactFlowWrapper };
}