import { type NodeProps, Position, type Node, } from '@xyflow/react'; import { Toolbar } from '../components/NodeComponents'; import styles from '../../VisProg.module.css'; import { TextField } from '../../../../components/TextField'; import {MultiConnectionHandle, SingleConnectionHandle} from "../components/RuleBasedHandle.tsx"; import {allowOnlyConnectionsFromHandle, allowOnlyConnectionsFromType} from "../HandleRules.ts"; import useFlowStore from '../VisProgStores'; import {BeliefGlobalReduce} from "./BeliefGlobals.ts"; /** * The default data dot a phase node * @param label: the label of this phase * @param droppable: whether this node is droppable from the drop bar (initialized as true) * @param norm: list of strings of norms for this node * @param hasReduce: whether this node has reducing functionality (true by default) */ export type NormNodeData = { label: string; droppable: boolean; condition?: string; // id of this node's belief. norm: string; hasReduce: boolean; critical: boolean; }; export type NormNode = Node /** * Defines how a Norm node should be rendered * @param props NodeProps, like id, label, children * @returns React.JSX.Element */ export default function NormNode(props: NodeProps) { const data = props.data; const {updateNodeData} = useFlowStore(); const text_input_id = `norm_${props.id}_text_input`; const checkbox_id = `goal_${props.id}_checkbox`; const setValue = (value: string) => { updateNodeData(props.id, {norm: value}); } const setCritical = (value: boolean) => { updateNodeData(props.id, {...data, critical: value}); } return <>
setValue(val)} placeholder={"Pepper should ..."} />
setCritical(e.target.checked)} />
{data.condition && (
)}
; }; /** * Reduces each Norm, including its children down into its relevant data. * @param node The Node Properties of this node. * @param nodes all the nodes in the graph */ export function NormReduce(node: Node, nodes: Node[]) { const data = node.data as NormNodeData; // conditions nodes - make sure to check for empty arrays const result: Record = { id: node.id, label: data.label, norm: data.norm, critical: data.critical, }; if (data.condition) { const conditionNode = nodes.find((node) => node.id === data.condition); // In case something went wrong, and our condition doesn't actually exist; if (conditionNode == undefined) return result; result["condition"] = BeliefGlobalReduce(conditionNode, nodes) } return result } export const NormTooltip = ` A norm describes a behavioral rule Pepper must follow during the connected phase(-s), for example: "respond using formal language"`; /** * 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 NormConnectionTarget(_thisNode: Node, _sourceNodeId: string) { const data = _thisNode.data as NormNodeData; // If we got a belief connected, this is the condition for the norm. if ((useFlowStore.getState().nodes.find((node) => node.id === _sourceNodeId && ['basic_belief', 'inferred_belief'].includes(node.type!)))) { data.condition = _sourceNodeId; } } /** * 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 NormConnectionSource(_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 NormDisconnectionTarget(_thisNode: Node, _sourceNodeId: string) { const data = _thisNode.data as NormNodeData; // remove if the target of disconnection was our condition if (_sourceNodeId == data.condition) data.condition = undefined } /** * 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 NormDisconnectionSource(_thisNode: Node, _targetNodeId: string) { // no additional connection logic exists yet }