Merge branch 'dev' into feat/monitoringpage-pim
This commit is contained in:
@@ -119,7 +119,7 @@ const VisProgUI = () => {
|
||||
<SaveLoadPanel></SaveLoadPanel>
|
||||
</Panel>
|
||||
<Panel position="bottom-center">
|
||||
<button onClick={() => undo()}>undo</button>
|
||||
<button onClick={() => undo()}>Undo</button>
|
||||
<button onClick={() => redo()}>Redo</button>
|
||||
</Panel>
|
||||
<Controls/>
|
||||
@@ -175,7 +175,7 @@ function VisProgPage() {
|
||||
return (
|
||||
<>
|
||||
<VisualProgrammingUI/>
|
||||
<button onClick={runProgram}>run program</button>
|
||||
<button onClick={runProgram}>Run Program</button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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<FlowState>(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<FlowState>(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({
|
||||
|
||||
@@ -10,6 +10,7 @@ import {allowOnlyConnectionsFromHandle} from "../HandleRules.ts";
|
||||
import useFlowStore from '../VisProgStores.tsx';
|
||||
import { TextField } from '../../../../components/TextField.tsx';
|
||||
import { MultilineTextField } from '../../../../components/MultilineTextField.tsx';
|
||||
import {noMatchingLeftRightBelief} from "./BeliefGlobals.ts";
|
||||
|
||||
/**
|
||||
* The default data structure for a BasicBelief node
|
||||
@@ -189,7 +190,8 @@ export default function BasicBeliefNode(props: NodeProps<BasicBeliefNode>) {
|
||||
</div>
|
||||
)}
|
||||
<MultiConnectionHandle type="source" position={Position.Right} id="source" rules={[
|
||||
allowOnlyConnectionsFromHandle([{nodeType:"trigger",handleId:"TriggerBeliefs"}, {nodeType:"norm",handleId:"NormBeliefs"},{nodeType:"InferredBelief",handleId:"inferred_belief"}]),
|
||||
noMatchingLeftRightBelief,
|
||||
allowOnlyConnectionsFromHandle([{nodeType:"trigger",handleId:"TriggerBeliefs"}, {nodeType:"norm",handleId:"NormBeliefs"},{nodeType:"InferredBelief",handleId:"inferred_belief"}]),
|
||||
]}/>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { InferredBeliefNodeData } from "./InferredBeliefNode.tsx";
|
||||
* Default data for this node
|
||||
*/
|
||||
export const InferredBeliefNodeDefaults: InferredBeliefNodeData = {
|
||||
label: "Inferred Belief",
|
||||
label: "AND/OR",
|
||||
droppable: true,
|
||||
inferredBelief: {
|
||||
left: undefined,
|
||||
|
||||
@@ -50,9 +50,9 @@ export default function TriggerNode(props: NodeProps<TriggerNode>) {
|
||||
const setName= (value: string) => {
|
||||
updateNodeData(props.id, {...data, name: value})
|
||||
}
|
||||
|
||||
|
||||
return <>
|
||||
|
||||
|
||||
<Toolbar nodeId={props.id} allowDelete={true}/>
|
||||
<div className={`${styles.defaultNode} ${styles.nodeTrigger} flex-col gap-sm`}>
|
||||
<TextField
|
||||
@@ -70,9 +70,9 @@ export default function TriggerNode(props: NodeProps<TriggerNode>) {
|
||||
type="target"
|
||||
position={Position.Bottom}
|
||||
id="TriggerBeliefs"
|
||||
style={{ left: '40%' }}
|
||||
style={{ left: '40%' }}
|
||||
rules={[
|
||||
allowOnlyConnectionsFromType(['basic_belief', "inferred_belief"]),
|
||||
allowOnlyConnectionsFromType(['basic_belief']),
|
||||
]}
|
||||
/>
|
||||
|
||||
@@ -136,7 +136,7 @@ export function TriggerConnectionTarget(_thisNode: Node, _sourceNodeId: string)
|
||||
const otherNode = nodes.find((x) => x.id === _sourceNodeId)
|
||||
if (!otherNode) return;
|
||||
|
||||
if (otherNode.type === 'basic_belief'|| otherNode.type ==='inferred_belief') {
|
||||
if (otherNode.type === 'basic_belief' /* TODO: Add the option for an inferred belief */) {
|
||||
data.condition = _sourceNodeId;
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ export function TriggerDisconnectionTarget(_thisNode: Node, _sourceNodeId: strin
|
||||
const data = _thisNode.data as TriggerNodeData;
|
||||
// remove if the target of disconnection was our condition
|
||||
if (_sourceNodeId == data.condition) data.condition = undefined
|
||||
|
||||
|
||||
data.plan = deleteGoalInPlanByID(structuredClone(data.plan) as Plan, _sourceNodeId)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user