feat: added an inferred belief node to the editor #42
@@ -76,6 +76,11 @@
|
|||||||
filter: drop-shadow(0 0 0.25rem plum);
|
filter: drop-shadow(0 0 0.25rem plum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.node-inferred_belief {
|
||||||
|
outline: mediumpurple solid 2pt;
|
||||||
|
filter: drop-shadow(0 0 0.25rem mediumpurple);
|
||||||
|
}
|
||||||
|
|
||||||
.draggable-node {
|
.draggable-node {
|
||||||
padding: 3px 10px;
|
padding: 3px 10px;
|
||||||
background-color: canvas;
|
background-color: canvas;
|
||||||
@@ -140,6 +145,14 @@
|
|||||||
filter: drop-shadow(0 0 0.25rem plum);
|
filter: drop-shadow(0 0 0.25rem plum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.draggable-node-inferred_belief {
|
||||||
|
padding: 3px 10px;
|
||||||
|
background-color: canvas;
|
||||||
|
border-radius: 5pt;
|
||||||
|
outline: mediumpurple solid 2pt;
|
||||||
|
filter: drop-shadow(0 0 0.25rem mediumpurple);
|
||||||
|
}
|
||||||
|
|
||||||
.planNoIterate {
|
.planNoIterate {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
|||||||
@@ -163,6 +163,7 @@ function runProgram() {
|
|||||||
// when the program was sent to the backend successfully:
|
// when the program was sent to the backend successfully:
|
||||||
useProgramStore.getState().setProgramState(structuredClone(program));
|
useProgramStore.getState().setProgramState(structuredClone(program));
|
||||||
}).catch(() => console.log("Failed to send program to the backend."));
|
}).catch(() => console.log("Failed to send program to the backend."));
|
||||||
|
console.log(program);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -46,8 +46,22 @@ import TriggerNode, {
|
|||||||
TriggerReduce
|
TriggerReduce
|
||||||
} from "./nodes/TriggerNode";
|
} from "./nodes/TriggerNode";
|
||||||
import { TriggerNodeDefaults } from "./nodes/TriggerNode.default";
|
import { TriggerNodeDefaults } from "./nodes/TriggerNode.default";
|
||||||
import BasicBeliefNode, { BasicBeliefConnectionSource, BasicBeliefConnectionTarget, BasicBeliefDisconnectionSource, BasicBeliefDisconnectionTarget, BasicBeliefReduce } from "./nodes/BasicBeliefNode";
|
import InferredBeliefNode, {
|
||||||
import { BasicBeliefNodeDefaults } from "./nodes/BasicBeliefNode.default";
|
InferredBeliefConnectionTarget,
|
||||||
|
InferredBeliefConnectionSource,
|
||||||
|
InferredBeliefDisconnectionTarget,
|
||||||
|
InferredBeliefDisconnectionSource,
|
||||||
|
InferredBeliefReduce
|
||||||
|
} from "./nodes/InferredBeliefNode";
|
||||||
|
import { InferredBeliefNodeDefaults } from "./nodes/InferredBeliefNode.default";
|
||||||
|
import BasicBeliefNode, {
|
||||||
|
BasicBeliefConnectionSource,
|
||||||
|
BasicBeliefConnectionTarget,
|
||||||
|
BasicBeliefDisconnectionSource,
|
||||||
|
BasicBeliefDisconnectionTarget,
|
||||||
|
BasicBeliefReduce
|
||||||
|
} from "./nodes/BasicBeliefNode.tsx";
|
||||||
|
import { BasicBeliefNodeDefaults } from "./nodes/BasicBeliefNode.default.ts";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registered node types in the visual programming system.
|
* Registered node types in the visual programming system.
|
||||||
@@ -63,6 +77,7 @@ export const NodeTypes = {
|
|||||||
goal: GoalNode,
|
goal: GoalNode,
|
||||||
trigger: TriggerNode,
|
trigger: TriggerNode,
|
||||||
basic_belief: BasicBeliefNode,
|
basic_belief: BasicBeliefNode,
|
||||||
|
inferred_belief: InferredBeliefNode,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -78,6 +93,7 @@ export const NodeDefaults = {
|
|||||||
goal: GoalNodeDefaults,
|
goal: GoalNodeDefaults,
|
||||||
trigger: TriggerNodeDefaults,
|
trigger: TriggerNodeDefaults,
|
||||||
basic_belief: BasicBeliefNodeDefaults,
|
basic_belief: BasicBeliefNodeDefaults,
|
||||||
|
inferred_belief: InferredBeliefNodeDefaults,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -95,6 +111,7 @@ export const NodeReduces = {
|
|||||||
goal: GoalReduce,
|
goal: GoalReduce,
|
||||||
trigger: TriggerReduce,
|
trigger: TriggerReduce,
|
||||||
basic_belief: BasicBeliefReduce,
|
basic_belief: BasicBeliefReduce,
|
||||||
|
inferred_belief: InferredBeliefReduce,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -113,6 +130,7 @@ export const NodeConnections = {
|
|||||||
goal: GoalConnectionTarget,
|
goal: GoalConnectionTarget,
|
||||||
trigger: TriggerConnectionTarget,
|
trigger: TriggerConnectionTarget,
|
||||||
basic_belief: BasicBeliefConnectionTarget,
|
basic_belief: BasicBeliefConnectionTarget,
|
||||||
|
inferred_belief: InferredBeliefConnectionTarget,
|
||||||
},
|
},
|
||||||
Sources: {
|
Sources: {
|
||||||
start: StartConnectionSource,
|
start: StartConnectionSource,
|
||||||
@@ -121,7 +139,8 @@ export const NodeConnections = {
|
|||||||
norm: NormConnectionSource,
|
norm: NormConnectionSource,
|
||||||
goal: GoalConnectionSource,
|
goal: GoalConnectionSource,
|
||||||
trigger: TriggerConnectionSource,
|
trigger: TriggerConnectionSource,
|
||||||
basic_belief: BasicBeliefConnectionSource
|
basic_belief: BasicBeliefConnectionSource,
|
||||||
|
inferred_belief: InferredBeliefConnectionSource,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,6 +159,7 @@ export const NodeDisconnections = {
|
|||||||
goal: GoalDisconnectionTarget,
|
goal: GoalDisconnectionTarget,
|
||||||
trigger: TriggerDisconnectionTarget,
|
trigger: TriggerDisconnectionTarget,
|
||||||
basic_belief: BasicBeliefDisconnectionTarget,
|
basic_belief: BasicBeliefDisconnectionTarget,
|
||||||
|
inferred_belief: InferredBeliefDisconnectionTarget,
|
||||||
},
|
},
|
||||||
Sources: {
|
Sources: {
|
||||||
start: StartDisconnectionSource,
|
start: StartDisconnectionSource,
|
||||||
@@ -149,6 +169,7 @@ export const NodeDisconnections = {
|
|||||||
goal: GoalDisconnectionSource,
|
goal: GoalDisconnectionSource,
|
||||||
trigger: TriggerDisconnectionSource,
|
trigger: TriggerDisconnectionSource,
|
||||||
basic_belief: BasicBeliefDisconnectionSource,
|
basic_belief: BasicBeliefDisconnectionSource,
|
||||||
|
inferred_belief: InferredBeliefDisconnectionSource,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,4 +194,5 @@ export const NodesInPhase = {
|
|||||||
end: () => false,
|
end: () => false,
|
||||||
phase: () => false,
|
phase: () => false,
|
||||||
basic_belief: () => false,
|
basic_belief: () => false,
|
||||||
|
inferred_belief: () => false,
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { BasicBeliefNodeData } from "./BasicBeliefNode";
|
import type { BasicBeliefNodeData } from "./BasicBeliefNode.tsx";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ import {
|
|||||||
Position,
|
Position,
|
||||||
type Node,
|
type Node,
|
||||||
} from '@xyflow/react';
|
} from '@xyflow/react';
|
||||||
import { Toolbar } from '../components/NodeComponents';
|
import { Toolbar } from '../components/NodeComponents.tsx';
|
||||||
import styles from '../../VisProg.module.css';
|
import styles from '../../VisProg.module.css';
|
||||||
import {MultiConnectionHandle} from "../components/RuleBasedHandle.tsx";
|
import {MultiConnectionHandle} from "../components/RuleBasedHandle.tsx";
|
||||||
import {allowOnlyConnectionsFromType} from "../HandleRules.ts";
|
import {allowOnlyConnectionsFromType} from "../HandleRules.ts";
|
||||||
import useFlowStore from '../VisProgStores';
|
import useFlowStore from '../VisProgStores.tsx';
|
||||||
import { TextField } from '../../../../components/TextField';
|
import { TextField } from '../../../../components/TextField.tsx';
|
||||||
import { MultilineTextField } from '../../../../components/MultilineTextField';
|
import { MultilineTextField } from '../../../../components/MultilineTextField.tsx';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default data structure for a BasicBelief node
|
* The default data structure for a BasicBelief node
|
||||||
@@ -31,7 +31,7 @@ export type BasicBeliefNodeData = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// These are all the types a basic belief could be.
|
// These are all the types a basic belief could be.
|
||||||
type BasicBeliefType = Keyword | Semantic | DetectedObject | Emotion
|
export type BasicBeliefType = Keyword | Semantic | DetectedObject | Emotion
|
||||||
type Keyword = { type: "keyword", id: string, value: string, label: "Keyword said:"};
|
type Keyword = { type: "keyword", id: string, value: string, label: "Keyword said:"};
|
||||||
type Semantic = { type: "semantic", id: string, value: string, description: string, label: "Detected with LLM:"};
|
type Semantic = { type: "semantic", id: string, value: string, description: string, label: "Detected with LLM:"};
|
||||||
type DetectedObject = { type: "object", id: string, value: string, label: "Object found:"};
|
type DetectedObject = { type: "object", id: string, value: string, label: "Object found:"};
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import type { InferredBeliefNodeData } from "./InferredBeliefNode.tsx";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default data for this node
|
||||||
|
*/
|
||||||
|
export const InferredBeliefNodeDefaults: InferredBeliefNodeData = {
|
||||||
|
label: "Inferred Belief",
|
||||||
|
droppable: true,
|
||||||
|
inferredBelief: {
|
||||||
|
id: "",
|
||||||
|
left: undefined,
|
||||||
|
operator: "OR",
|
||||||
|
right: undefined
|
||||||
|
},
|
||||||
|
hasReduce: true,
|
||||||
|
};
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
.operator-switch {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5em;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: sans-serif;
|
||||||
|
/* Change this font-size to scale the whole component */
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* hide the default checkbox */
|
||||||
|
.operator-switch input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The Track */
|
||||||
|
.switch-visual {
|
||||||
|
position: relative;
|
||||||
|
/* height is now 3x the font size */
|
||||||
|
height: 3em;
|
||||||
|
aspect-ratio: 1 / 2;
|
||||||
|
background-color: ButtonFace;
|
||||||
|
border-radius: 2em;
|
||||||
|
transition: 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The Knob */
|
||||||
|
.switch-visual::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0.1em;
|
||||||
|
left: 0.1em;
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
background: Canvas;
|
||||||
|
border: 0.175em solid mediumpurple;
|
||||||
|
border-radius: 50%;
|
||||||
|
transition: transform 0.2s ease-in-out, border-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Labels */
|
||||||
|
.switch-labels {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: 3em; /* Matches the track height */
|
||||||
|
font-weight: 800;
|
||||||
|
color: Canvas;
|
||||||
|
line-height: 1.4;
|
||||||
|
padding: 0.2em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.operator-switch input:checked + .switch-visual::after {
|
||||||
|
/* Moves the slider down */
|
||||||
|
transform: translateY(1.4em);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*change the colours to highlight the selected operator*/
|
||||||
|
.operator-switch input:checked ~ .switch-labels{
|
||||||
|
:first-child {
|
||||||
|
transition: ease-in-out color 0.2s;
|
||||||
|
color: ButtonFace;
|
||||||
|
}
|
||||||
|
:last-child {
|
||||||
|
transition: ease-in-out color 0.2s;
|
||||||
|
color: mediumpurple;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.operator-switch input:not(:checked) ~ .switch-labels{
|
||||||
|
:first-child {
|
||||||
|
transition: ease-in-out color 0.2s;
|
||||||
|
color: mediumpurple;
|
||||||
|
}
|
||||||
|
:last-child {
|
||||||
|
transition: ease-in-out color 0.2s;
|
||||||
|
color: ButtonFace;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
import {
|
||||||
|
type NodeProps,
|
||||||
|
Position,
|
||||||
|
type Node,
|
||||||
|
} from '@xyflow/react';
|
||||||
|
import {useState} from "react";
|
||||||
|
import { Toolbar } from '../components/NodeComponents.tsx';
|
||||||
|
import styles from '../../VisProg.module.css';
|
||||||
|
import switchStyles from './InferredBeliefNode.module.css';
|
||||||
|
import {MultiConnectionHandle, SingleConnectionHandle} from "../components/RuleBasedHandle.tsx";
|
||||||
|
import {allowOnlyConnectionsFromType} from "../HandleRules.ts";
|
||||||
|
import useFlowStore from "../VisProgStores.tsx";
|
||||||
|
import type {BasicBeliefType} from "./BasicBeliefNode.tsx";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default data structure for an InferredBelief node
|
||||||
|
*/
|
||||||
|
export type InferredBeliefNodeData = {
|
||||||
|
label: string;
|
||||||
|
droppable: boolean;
|
||||||
|
inferredBelief: Belief;
|
||||||
|
hasReduce: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Belief = InferredBelief | BasicBeliefType;
|
||||||
|
|
||||||
|
type InferredBelief = {
|
||||||
|
id: string;
|
||||||
|
left: Belief | undefined,
|
||||||
|
operator: "AND" | "OR"
|
||||||
|
right: Belief | undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
// helper validation function for InferredBelief objects
|
||||||
|
// const isValidInferredBelief = (inferredBelief: InferredBelief) : boolean => {
|
||||||
|
// return !(inferredBelief.left && inferredBelief.right);
|
||||||
|
// };
|
||||||
|
|
||||||
|
export type InferredBeliefNode = Node<InferredBeliefNodeData>;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called whenever a connection is made with this node type as the target
|
||||||
|
* @param _thisNode the node of this node type which function is called
|
||||||
|
* @param _sourceNodeId the source of the received connection
|
||||||
|
*/
|
||||||
|
export function InferredBeliefConnectionTarget(_thisNode: Node, _sourceNodeId: string) {
|
||||||
|
// no additional connection logic exists yet
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called whenever a connection is made with this node type as the source
|
||||||
|
* @param _thisNode the node of this node type which function is called
|
||||||
|
* @param _targetNodeId the target of the created connection
|
||||||
|
*/
|
||||||
|
export function InferredBeliefConnectionSource(_thisNode: Node, _targetNodeId: string) {
|
||||||
|
// no additional connection logic exists yet
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called whenever a connection is disconnected with this node type as the target
|
||||||
|
* @param _thisNode the node of this node type which function is called
|
||||||
|
* @param _sourceNodeId the source of the disconnected connection
|
||||||
|
*/
|
||||||
|
export function InferredBeliefDisconnectionTarget(_thisNode: Node, _sourceNodeId: string) {
|
||||||
|
// no additional connection logic exists yet
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called whenever a connection is disconnected with this node type as the source
|
||||||
|
* @param _thisNode the node of this node type which function is called
|
||||||
|
* @param _targetNodeId the target of the diconnected connection
|
||||||
|
*/
|
||||||
|
export function InferredBeliefDisconnectionSource(_thisNode: Node, _targetNodeId: string) {
|
||||||
|
// no additional connection logic exists yet
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines how a BasicBelief node should be rendered
|
||||||
|
* @param props - Node properties provided by React Flow, including `id` and `data`.
|
||||||
|
* @returns The rendered BasicBeliefNode React element (React.JSX.Element).
|
||||||
|
*/
|
||||||
|
export default function InferredBeliefNode(props: NodeProps<InferredBeliefNode>) {
|
||||||
|
const data = props.data;
|
||||||
|
const { updateNodeData } = useFlowStore();
|
||||||
|
// start of as an AND operator, true: "AND", false: "OR"
|
||||||
|
const [enforceAllBeliefs, setEnforceAllBeliefs] = useState(true);
|
||||||
|
function onToggle() {
|
||||||
|
setEnforceAllBeliefs(!enforceAllBeliefs);
|
||||||
|
updateNodeData(props.id, {
|
||||||
|
...data,
|
||||||
|
belief: {
|
||||||
|
...data.inferredBelief,
|
||||||
|
operator: enforceAllBeliefs ? "AND" : "OR",
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO define node
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Toolbar nodeId={props.id} allowDelete={true}/>
|
||||||
|
<div className={`${styles.defaultNode} ${styles.nodeInferredBelief}`}>
|
||||||
|
|
||||||
|
<label className={switchStyles.operatorSwitch}>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={enforceAllBeliefs}
|
||||||
|
onChange={onToggle}
|
||||||
|
/>
|
||||||
|
<div className={switchStyles.switchVisual}></div>
|
||||||
|
<div className={switchStyles.switchLabels}>
|
||||||
|
<span title={"Belief is fulfilled if either of the supplied beliefs is true"}>OR</span>
|
||||||
|
<span title={"Belief is fulfilled if all of the supplied beliefs are true"}>AND</span>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
|
||||||
|
{/* outgoing connections */}
|
||||||
|
<MultiConnectionHandle type="source" position={Position.Right} id="source" rules={[
|
||||||
|
allowOnlyConnectionsFromType(["norm", "trigger"]),
|
||||||
|
]}/>
|
||||||
|
|
||||||
|
{/* incoming connections */}
|
||||||
|
<SingleConnectionHandle type="target" position={Position.Left} style={{top: '30%'}} id="beliefLeft" rules={[
|
||||||
|
allowOnlyConnectionsFromType(["basic_belief", "inferred_belief"]),
|
||||||
|
]}/>
|
||||||
|
<SingleConnectionHandle type="target" position={Position.Left} style={{top: '70%'}} id="beliefRight" rules={[
|
||||||
|
allowOnlyConnectionsFromType(["basic_belief", "inferred_belief"]),
|
||||||
|
]}/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reduces each BasicBelief, including its children down into its core data.
|
||||||
|
* @param node - The BasicBelief node to reduce.
|
||||||
|
* @param _nodes - The list of all nodes in the current flow graph.
|
||||||
|
* @returns A simplified object containing the node label and its list of BasicBeliefs.
|
||||||
|
*/
|
||||||
|
export function InferredBeliefReduce(node: Node, _nodes: Node[]) {
|
||||||
|
//const data = node.data as InferredBeliefNodeData;
|
||||||
|
const result: Record<string, unknown> = {
|
||||||
|
id: node.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO define reduce
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@ import { TextField } from '../../../../components/TextField';
|
|||||||
import {MultiConnectionHandle, SingleConnectionHandle} from "../components/RuleBasedHandle.tsx";
|
import {MultiConnectionHandle, SingleConnectionHandle} from "../components/RuleBasedHandle.tsx";
|
||||||
import {allowOnlyConnectionsFromHandle, allowOnlyConnectionsFromType} from "../HandleRules.ts";
|
import {allowOnlyConnectionsFromHandle, allowOnlyConnectionsFromType} from "../HandleRules.ts";
|
||||||
import useFlowStore from '../VisProgStores';
|
import useFlowStore from '../VisProgStores';
|
||||||
import { BasicBeliefReduce } from './BasicBeliefNode';
|
import { BasicBeliefReduce } from './BasicBeliefNode.tsx';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default data dot a phase node
|
* The default data dot a phase node
|
||||||
@@ -81,7 +81,7 @@ export default function NormNode(props: NodeProps<NormNode>) {
|
|||||||
allowOnlyConnectionsFromHandle([{nodeType:"phase",handleId:"data"}])
|
allowOnlyConnectionsFromHandle([{nodeType:"phase",handleId:"data"}])
|
||||||
]}/>
|
]}/>
|
||||||
<SingleConnectionHandle type="target" position={Position.Bottom} id="beliefs" rules={[
|
<SingleConnectionHandle type="target" position={Position.Bottom} id="beliefs" rules={[
|
||||||
allowOnlyConnectionsFromType(["basic_belief"])
|
allowOnlyConnectionsFromType(["basic_belief, inferred_belief"])
|
||||||
]}/>
|
]}/>
|
||||||
</div>
|
</div>
|
||||||
</>;
|
</>;
|
||||||
@@ -122,7 +122,7 @@ export function NormReduce(node: Node, nodes: Node[]) {
|
|||||||
export function NormConnectionTarget(_thisNode: Node, _sourceNodeId: string) {
|
export function NormConnectionTarget(_thisNode: Node, _sourceNodeId: string) {
|
||||||
const data = _thisNode.data as NormNodeData;
|
const data = _thisNode.data as NormNodeData;
|
||||||
// If we got a belief connected, this is the condition for the norm.
|
// If we got a belief connected, this is the condition for the norm.
|
||||||
if ((useFlowStore.getState().nodes.find((node) => node.id === _sourceNodeId && node.type === 'basic_belief' /* TODO: Add the option for an inferred belief */))) {
|
if ((useFlowStore.getState().nodes.find((node) => node.id === _sourceNodeId && ['basic_belief', 'inferred_belief'].includes(node.type!)))) {
|
||||||
data.condition = _sourceNodeId;
|
data.condition = _sourceNodeId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {allowOnlyConnectionsFromHandle, allowOnlyConnectionsFromType} from "../H
|
|||||||
import useFlowStore from '../VisProgStores';
|
import useFlowStore from '../VisProgStores';
|
||||||
import { PlanReduce, type Plan } from '../components/Plan';
|
import { PlanReduce, type Plan } from '../components/Plan';
|
||||||
import PlanEditorDialog from '../components/PlanEditor';
|
import PlanEditorDialog from '../components/PlanEditor';
|
||||||
import { BasicBeliefReduce } from './BasicBeliefNode';
|
import { BasicBeliefReduce } from './BasicBeliefNode.tsx';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default data structure for a Trigger node
|
* The default data structure for a Trigger node
|
||||||
@@ -66,7 +66,7 @@ export default function TriggerNode(props: NodeProps<TriggerNode>) {
|
|||||||
allowOnlyConnectionsFromHandle([{nodeType:"phase",handleId:"data"}]),
|
allowOnlyConnectionsFromHandle([{nodeType:"phase",handleId:"data"}]),
|
||||||
]}/>
|
]}/>
|
||||||
<SingleConnectionHandle type="target" position={Position.Bottom} id="beliefs" rules={[
|
<SingleConnectionHandle type="target" position={Position.Bottom} id="beliefs" rules={[
|
||||||
allowOnlyConnectionsFromType(["basic_belief"])
|
allowOnlyConnectionsFromType(["basic_belief","inferred_belief"]),
|
||||||
]}/>
|
]}/>
|
||||||
|
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ export function TriggerConnectionTarget(_thisNode: Node, _sourceNodeId: string)
|
|||||||
// no additional connection logic exists yet
|
// no additional connection logic exists yet
|
||||||
const data = _thisNode.data as TriggerNodeData;
|
const data = _thisNode.data as TriggerNodeData;
|
||||||
// If we got a belief connected, this is the condition for the norm.
|
// If we got a belief connected, this is the condition for the norm.
|
||||||
if ((useFlowStore.getState().nodes.find((node) => node.id === _sourceNodeId && node.type === 'basic_belief' /* TODO: Add the option for an inferred belief */))) {
|
if ((useFlowStore.getState().nodes.find((node) => node.id === _sourceNodeId && ['basic_belief', 'inferred_belief'].includes(node.type!)))) {
|
||||||
data.condition = _sourceNodeId;
|
data.condition = _sourceNodeId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { describe, it, beforeEach } from '@jest/globals';
|
|||||||
import { screen, waitFor } from '@testing-library/react';
|
import { screen, waitFor } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { renderWithProviders } from '../.././/./../../test-utils/test-utils';
|
import { renderWithProviders } from '../.././/./../../test-utils/test-utils';
|
||||||
import BasicBeliefNode, { type BasicBeliefNodeData } from '../../../../../src/pages/VisProgPage/visualProgrammingUI/nodes/BasicBeliefNode';
|
import BasicBeliefNode, { type BasicBeliefNodeData } from '../../../../../src/pages/VisProgPage/visualProgrammingUI/nodes/BasicBeliefNode.tsx';
|
||||||
import useFlowStore from '../../../../../src/pages/VisProgPage/visualProgrammingUI/VisProgStores';
|
import useFlowStore from '../../../../../src/pages/VisProgPage/visualProgrammingUI/VisProgStores';
|
||||||
import type { Node } from '@xyflow/react';
|
import type { Node } from '@xyflow/react';
|
||||||
import '@testing-library/jest-dom';
|
import '@testing-library/jest-dom';
|
||||||
|
|||||||
Reference in New Issue
Block a user