Repository: Significant-Gravitas/Auto-GPT
File: autogpt_platform/frontend/src/app/(platform)/build/components/FlowEditor/Flow/useFlow.ts (TypeScript)

Code before:
      executionDetails &&
      "node_executions" in executionDetails &&
      executionDetails.node_executions
    ) {
      executionDetails.node_executions.forEach((nodeExecution) => {
        updateNodeExecutionResult(nodeExecution.node_id, nodeExecution);
      });
    }
  }, [customNodes, addNodes, graph?.links, executionDetails, updateNodeStatus]);

  useEffect(() => {
    return () => {
      useNodeStore.getState().setNodes([]);
      useEdgeStore.getState().setConnections([]);
      useGraphStore.getState().reset();
      setIsGraphRunning(false);
    };
  }, []);

  // Drag and drop block from block menu
  const onDragOver = useCallback((event: React.DragEvent) => {
    event.preventDefault();
    event.dataTransfer.dropEffect = "copy";
  }, []);

  const onDrop = useCallback(
    async (event: React.DragEvent) => {
      event.preventDefault();
      const blockDataString = event.dataTransfer.getData(
        "application/reactflow",
      );
      if (!blockDataString) return;

      try {
        const blockData = JSON.parse(blockDataString) as BlockInfo;
        const position = screenToFlowPosition({
          x: event.clientX,
          y: event.clientY,
        });
        addBlock(blockData, position);

        await new Promise((resolve) => setTimeout(resolve, 200));
        setBlockMenuOpen(true);
      } catch (error) {
        console.error("Failed to drop block:", error);
        setBlockMenuOpen(true);
      }
    },
    [addBlock, screenToFlowPosition, setBlockMenuOpen],
  );


Review comment (performance):
We shouldn't need `useCallback` here unless we see performance issues? The drop event should only happens once or twice so I think no need to over-optimise for now 🙇🏽 

Code after:
      executionDetails &&
      "node_executions" in executionDetails &&
      executionDetails.node_executions
    ) {
      executionDetails.node_executions.forEach((nodeExecution) => {
        updateNodeExecutionResult(nodeExecution.node_id, nodeExecution);
      });
    }
  }, [customNodes, addNodes, graph?.links, executionDetails, updateNodeStatus]);

  useEffect(() => {
    return () => {
      useNodeStore.getState().setNodes([]);
      useEdgeStore.getState().setConnections([]);
      useGraphStore.getState().reset();
      setIsGraphRunning(false);
    };
  }, []);

  // Drag and drop block from block menu
  const onDragOver = useCallback((event: React.DragEvent) => {
    event.preventDefault();
    event.dataTransfer.dropEffect = "copy";
  }, []);

  const onDrop = async (event: React.DragEvent) => {
    event.preventDefault();
    const blockDataString = event.dataTransfer.getData("application/reactflow");
    if (!blockDataString) return;

    try {
      const blockData = JSON.parse(blockDataString) as BlockInfo;
      const position = screenToFlowPosition({
        x: event.clientX,
        y: event.clientY,
      });
      addBlock(blockData, position);

      await new Promise((resolve) => setTimeout(resolve, 200));
      setBlockMenuOpen(true);
    } catch (error) {
      console.error("Failed to drop block:", error);
      setBlockMenuOpen(true);
    }
  };

  return {
    isFlowContentLoading: isGraphLoading || isBlocksLoading,
    onDragOver,
    onDrop,
  };