diff --git a/src/pages/VisProgPage/visualProgrammingUI/HandleRuleLogic.ts b/src/pages/VisProgPage/visualProgrammingUI/HandleRuleLogic.ts index 427542a..e212ed2 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/HandleRuleLogic.ts +++ b/src/pages/VisProgPage/visualProgrammingUI/HandleRuleLogic.ts @@ -107,4 +107,16 @@ export function useHandleRules( // finally we return a function that evaluates all rules using the created context return evaluateRules(targetRules, connection, context); }; +} + +export function validateConnectionWithRules( + connection: Connection, + context: ConnectionContext +): RuleResult { + const rules = useFlowStore.getState().getTargetRules( + connection.target!, + connection.targetHandle! + ); + + return evaluateRules(rules,connection, context); } \ No newline at end of file diff --git a/src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx b/src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx index defa934..2831748 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx +++ b/src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx @@ -9,6 +9,7 @@ import { type XYPosition, } from '@xyflow/react'; import '@xyflow/react/dist/style.css'; +import {type ConnectionContext, validateConnectionWithRules} from "./HandleRuleLogic.ts"; import type { FlowState } from './VisProgTypes'; import { NodeDefaults, @@ -129,7 +130,41 @@ const useFlowStore = create(UndoRedo((set, get) => ({ * Handles reconnecting an edge between nodes. */ onReconnect: (oldEdge, newConnection) => { - get().edgeReconnectSuccessful = true; + + function createContext( + source: {id: string, handleId: string}, + target: {id: string, handleId: string} + ) : ConnectionContext { + const edges = get().edges; + const targetConnections = edges.filter(edge => edge.target === target.id && edge.targetHandle === target.handleId).length + return { + connectionCount: targetConnections, + source: source, + target: target + } + } + + // connection validation + const context: ConnectionContext = oldEdge.source === newConnection.source + ? createContext({id: newConnection.source, handleId: newConnection.sourceHandle!}, {id: newConnection.target, handleId: newConnection.targetHandle!}) + : createContext({id: newConnection.target, handleId: newConnection.targetHandle!}, {id: newConnection.source, handleId: newConnection.sourceHandle!}); + + const result = validateConnectionWithRules( + newConnection, + context + ); + + if (!result.isSatisfied) { + set({ + edges: get().edges.map(e => + e.id === oldEdge.id ? oldEdge : e + ), + }); + return; + } + + // further reconnect logic + set({ edgeReconnectSuccessful: true }); set({ edges: reconnectEdge(oldEdge, newConnection, get().edges) }); // We make sure to perform any required data updates on the newly reconnected nodes @@ -188,7 +223,7 @@ const useFlowStore = create(UndoRedo((set, get) => ({ // Let's find our node to check if they have a special deletion function const ourNode = get().nodes.find((n)=>n.id==nodeId); const ourFunction = Object.entries(NodeDeletes).find(([t])=>t==ourNode?.type)?.[1] - + // If there's no function, OR, our function tells us we can delete it, let's do so... if (ourFunction == undefined || ourFunction()) { set({