fix: fixed reconnect being able to circumvent connection rules
the fix fixes the behavior, however user feedback does not reflect the fix as it driven by events that aren't triggered by onReconnect connection, and thus it would take a lot of time to fix the user feedback for onReconnect
This commit is contained in:
@@ -107,4 +107,16 @@ export function useHandleRules(
|
|||||||
// finally we return a function that evaluates all rules using the created context
|
// finally we return a function that evaluates all rules using the created context
|
||||||
return evaluateRules(targetRules, connection, 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);
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
type XYPosition,
|
type XYPosition,
|
||||||
} from '@xyflow/react';
|
} from '@xyflow/react';
|
||||||
import '@xyflow/react/dist/style.css';
|
import '@xyflow/react/dist/style.css';
|
||||||
|
import {type ConnectionContext, validateConnectionWithRules} from "./HandleRuleLogic.ts";
|
||||||
import type { FlowState } from './VisProgTypes';
|
import type { FlowState } from './VisProgTypes';
|
||||||
import {
|
import {
|
||||||
NodeDefaults,
|
NodeDefaults,
|
||||||
@@ -129,7 +130,41 @@ const useFlowStore = create<FlowState>(UndoRedo((set, get) => ({
|
|||||||
* Handles reconnecting an edge between nodes.
|
* Handles reconnecting an edge between nodes.
|
||||||
*/
|
*/
|
||||||
onReconnect: (oldEdge, newConnection) => {
|
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) });
|
set({ edges: reconnectEdge(oldEdge, newConnection, get().edges) });
|
||||||
|
|
||||||
// We make sure to perform any required data updates on the newly reconnected nodes
|
// We make sure to perform any required data updates on the newly reconnected nodes
|
||||||
@@ -188,7 +223,7 @@ const useFlowStore = create<FlowState>(UndoRedo((set, get) => ({
|
|||||||
// Let's find our node to check if they have a special deletion function
|
// Let's find our node to check if they have a special deletion function
|
||||||
const ourNode = get().nodes.find((n)=>n.id==nodeId);
|
const ourNode = get().nodes.find((n)=>n.id==nodeId);
|
||||||
const ourFunction = Object.entries(NodeDeletes).find(([t])=>t==ourNode?.type)?.[1]
|
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 there's no function, OR, our function tells us we can delete it, let's do so...
|
||||||
if (ourFunction == undefined || ourFunction()) {
|
if (ourFunction == undefined || ourFunction()) {
|
||||||
set({
|
set({
|
||||||
|
|||||||
Reference in New Issue
Block a user