removable edges implemented (#149)

# removable and draggable edges
This pull request adds two new features: removable edges and draggable
edges. Removable edges allow users to delete unwanted connections
without using the keyboard, while draggable edges enable the
repositioning of connections
This commit is contained in:
anovazzi1 2023-04-10 19:02:18 -03:00 • committed by GitHub
commit 17a2997637
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -6,9 +6,10 @@ import ReactFlow, {
useEdgesState, useEdgesState,
useNodesState, useNodesState,
useReactFlow, useReactFlow,
ControlButton, updateEdge,
EdgeChange, EdgeChange,
Connection, Connection,
Edge,
} from "reactflow"; } from "reactflow";
import { locationContext } from "../../contexts/locationContext"; import { locationContext } from "../../contexts/locationContext";
import ExtraSidebar from "./components/extraSidebarComponent"; import ExtraSidebar from "./components/extraSidebarComponent";
@ -20,6 +21,7 @@ import { typesContext } from "../../contexts/typesContext";
import ConnectionLineComponent from "./components/ConnectionLineComponent"; import ConnectionLineComponent from "./components/ConnectionLineComponent";
import { FlowType, NodeType } from "../../types/flow"; import { FlowType, NodeType } from "../../types/flow";
import { APIClassType } from "../../types/api"; import { APIClassType } from "../../types/api";
import { isValidConnection } from "../../utils";
const nodeTypes = { const nodeTypes = {
genericNode: GenericNode, genericNode: GenericNode,
@ -28,7 +30,7 @@ const nodeTypes = {
var _ = require("lodash"); var _ = require("lodash");
export default function FlowPage({ flow }:{flow:FlowType}) { export default function FlowPage({ flow }:{flow:FlowType}) {
let { updateFlow, incrementNodeId, downloadFlow, uploadFlow } = let { updateFlow, incrementNodeId} =
useContext(TabsContext); useContext(TabsContext);
const { types, reactFlowInstance, setReactFlowInstance } = const { types, reactFlowInstance, setReactFlowInstance } =
useContext(typesContext); useContext(typesContext);
@ -43,6 +45,7 @@ export default function FlowPage({ flow }:{flow:FlowType}) {
flow.data?.edges ?? [] flow.data?.edges ?? []
); );
const { setViewport } = useReactFlow(); const { setViewport } = useReactFlow();
const edgeUpdateSuccessful = useRef(true)
useEffect(() => { useEffect(() => {
if (reactFlowInstance && flow) { if (reactFlowInstance && flow) {
@ -155,6 +158,26 @@ export default function FlowPage({ flow }:{flow:FlowType}) {
setEdges(edges.filter((ns) => !nodes.some((n) => ns.source === n.id || ns.target === n.id))); setEdges(edges.filter((ns) => !nodes.some((n) => ns.source === n.id || ns.target === n.id)));
} }
const onEdgeUpdateStart = useCallback(() => {
edgeUpdateSuccessful.current = false;
}, []);
const onEdgeUpdate = useCallback((oldEdge:Edge, newConnection:Connection) => {
if(isValidConnection(newConnection,reactFlowInstance)){
edgeUpdateSuccessful.current = true;
setEdges((els) => updateEdge(oldEdge, newConnection, els));
}
}, []);
const onEdgeUpdateEnd = useCallback((_, edge) => {
if (!edgeUpdateSuccessful.current) {
setEdges((eds) => eds.filter((e) => e.id !== edge.id));
}
edgeUpdateSuccessful.current = true;
}, []);
return ( return (
<div className="w-full h-full" ref={reactFlowWrapper}> <div className="w-full h-full" ref={reactFlowWrapper}>
{Object.keys(types).length > 0 ? ( {Object.keys(types).length > 0 ? (
@ -171,6 +194,9 @@ export default function FlowPage({ flow }:{flow:FlowType}) {
onLoad={setReactFlowInstance} onLoad={setReactFlowInstance}
onInit={setReactFlowInstance} onInit={setReactFlowInstance}
nodeTypes={nodeTypes} nodeTypes={nodeTypes}
onEdgeUpdate={onEdgeUpdate}
onEdgeUpdateStart={onEdgeUpdateStart}
onEdgeUpdateEnd={onEdgeUpdateEnd}
connectionLineComponent={ConnectionLineComponent} connectionLineComponent={ConnectionLineComponent}
onDragOver={onDragOver} onDragOver={onDragOver}
onDrop={onDrop} onDrop={onDrop}