diff --git a/src/pages/VisProgPage/visualProgrammingUI/NodeRegistry.ts b/src/pages/VisProgPage/visualProgrammingUI/NodeRegistry.ts index e02f5f2..0ef5455 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/NodeRegistry.ts +++ b/src/pages/VisProgPage/visualProgrammingUI/NodeRegistry.ts @@ -1,6 +1,6 @@ import StartNode, { StartConnects, StartReduce } from "./nodes/StartNode"; import EndNode, { EndConnects, EndReduce } from "./nodes/EndNode"; -import PhaseNode, { PhaseConnects, PhaseReduce } from "./nodes/PhaseNode"; +import PhaseNode, { PhaseConnects, PhaseReduce, PhaseReduce2 } from "./nodes/PhaseNode"; import NormNode, { NormConnects, NormReduce } from "./nodes/NormNode"; import { EndNodeDefaults } from "./nodes/EndNode.default"; import { StartNodeDefaults } from "./nodes/StartNode.default"; @@ -11,6 +11,9 @@ import { GoalNodeDefaults } from "./nodes/GoalNode.default"; import TriggerNode, { TriggerConnects, TriggerReduce } from "./nodes/TriggerNode"; import { TriggerNodeDefaults } from "./nodes/TriggerNode.default"; +/** + * The types of the nodes we have registered. + */ export const NodeTypes = { start: StartNode, end: EndNode, @@ -20,7 +23,9 @@ export const NodeTypes = { trigger: TriggerNode, }; -// Default node data for creation +/** + * The default functions of the nodes we have registered. + */ export const NodeDefaults = { start: StartNodeDefaults, end: EndNodeDefaults, @@ -30,15 +35,23 @@ export const NodeDefaults = { trigger: TriggerNodeDefaults, }; + +/** + * The reduce functions of the nodes we have registered. + */ export const NodeReduces = { start: StartReduce, end: EndReduce, - phase: PhaseReduce, + phase: PhaseReduce2, norm: NormReduce, goal: GoalReduce, trigger: TriggerReduce, } + +/** + * The connection functionality of the nodes we have registered. + */ export const NodeConnects = { start: StartConnects, end: EndConnects, @@ -48,9 +61,21 @@ export const NodeConnects = { trigger: TriggerConnects, } -// Function to tell the visual program if we're allowed to delete them... -// Right now it doesn't take in any values, but that could also be done later. +/** + * Functions that define whether a node should be deleted, currently constant only for start and end. + * Any node types that aren't mentioned are 'true', and can be deleted by default. + */ export const NodeDeletes = { start: () => false, end: () => false, +} + +/** + * Defines which types are variables in the phase node- + * any node that is NOT mentioned here, is automatically seen as a variable of a phase. + */ +export const NodesInPhase = { + start: () => false, + end: () => false, + phase: () => false, } \ No newline at end of file diff --git a/src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx b/src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx index 607c817..e9c9bef 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx +++ b/src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx @@ -18,6 +18,7 @@ import { NodeDefaults, NodeConnects, NodeDeletes } from './NodeRegistry'; * @param id the id of the node to create * @param position the position of the node to create * @param data the data in the node to create + * @param deletable if this node should be able to be deleted IN ANY WAY POSSIBLE * @constructor */ function createNode(id: string, type: string, position: XYPosition, data: Record, deletable? : boolean) { @@ -35,8 +36,8 @@ function createNode(id: string, type: string, position: XYPosition, data: Record //* Initial nodes, created by using createNode. */ const initialNodes : Node[] = [ createNode('start', 'start', {x: 100, y: 100}, {label: "Start"}, false), - createNode('end', 'end', {x: 370, y: 100}, {label: "End"}, false), - createNode('phase-1', 'phase', {x:200, y:100}, {label: "Phase 1", children: ['end', 'start']}), + createNode('end', 'end', {x: 500, y: 100}, {label: "End"}, false), + createNode('phase-1', 'phase', {x:200, y:100}, {label: "Phase 1", children : []}), createNode('norms-1', 'norm', {x:-200, y:100}, {label: "Initial Norms", normList: ["Be a robot", "get good"]}), ]; diff --git a/src/pages/VisProgPage/visualProgrammingUI/nodes/GoalNode.tsx b/src/pages/VisProgPage/visualProgrammingUI/nodes/GoalNode.tsx index 322d6bb..cf528c7 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/nodes/GoalNode.tsx +++ b/src/pages/VisProgPage/visualProgrammingUI/nodes/GoalNode.tsx @@ -93,7 +93,9 @@ export function GoalReduce(node: Node, nodes: Node[]) { } const data = node.data as GoalNodeData; return { + id: node.id, label: data.label, + description: data.description, achieved: data.achieved, } } diff --git a/src/pages/VisProgPage/visualProgrammingUI/nodes/NormNode.default.ts b/src/pages/VisProgPage/visualProgrammingUI/nodes/NormNode.default.ts index 829085b..12cb182 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/nodes/NormNode.default.ts +++ b/src/pages/VisProgPage/visualProgrammingUI/nodes/NormNode.default.ts @@ -6,6 +6,6 @@ import type { NormNodeData } from "./NormNode"; export const NormNodeDefaults: NormNodeData = { label: "Norm Node", droppable: true, - normList: [], + norm: "", hasReduce: true, }; \ No newline at end of file diff --git a/src/pages/VisProgPage/visualProgrammingUI/nodes/NormNode.tsx b/src/pages/VisProgPage/visualProgrammingUI/nodes/NormNode.tsx index 4dee91f..1d143da 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/nodes/NormNode.tsx +++ b/src/pages/VisProgPage/visualProgrammingUI/nodes/NormNode.tsx @@ -9,18 +9,19 @@ import { import { Toolbar } from '../components/NodeComponents'; import styles from '../../VisProg.module.css'; import { TextField } from '../../../../components/TextField'; +import useFlowStore from '../VisProgStores'; /** * 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 normList: list of strings of norms for this node + * @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; - normList: string[]; + norm: string; hasReduce: boolean; }; @@ -39,25 +40,32 @@ export function NormNodeCanConnect(connection: Connection | Edge): boolean { * @returns React.JSX.Element */ export default function NormNode(props: NodeProps) { - const label_input_id = `Norm_${props.id}_label_input`; const data = props.data as NormNodeData; - return ( - <> - -
-
- - {props.data.label as string} -
-
- -
- - + const {updateNodeData} = useFlowStore(); + + const text_input_id = `norm_${props.id}_text_input`; + + const setValue = (value: string) => { + updateNodeData(props.id, {norm: value}); + } + + return <> + +
+
+ + setValue(val)} + placeholder={"Pepper should ..."} + />
- - ); -} + +
+ ; +}; + /** * Reduces each Norm, including its children down into its relevant data. @@ -70,8 +78,9 @@ export function NormReduce(node: Node, nodes: Node[]) { } const data = node.data as NormNodeData; return { + id: node.id, label: data.label, - list: data.normList, + norm: data.norm, } } @@ -80,25 +89,4 @@ export function NormConnects(thisNode: Node, otherNode: Node, isThisSource: bool if (thisNode == undefined && otherNode == undefined && isThisSource == false) { console.warn("Impossible node connection called in EndConnects") } -} - -function Norms(props: { id: string; list: string[] }) { - const { id, list } = props; - return ( - <> - The norms that the robot will uphold: - { - list.map((norm, idx) => { - return ( -
- { return; }} - /> -
- ); - }) - } - - ); } \ No newline at end of file diff --git a/src/pages/VisProgPage/visualProgrammingUI/nodes/PhaseNode.tsx b/src/pages/VisProgPage/visualProgrammingUI/nodes/PhaseNode.tsx index e6a6bfb..864278d 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/nodes/PhaseNode.tsx +++ b/src/pages/VisProgPage/visualProgrammingUI/nodes/PhaseNode.tsx @@ -6,7 +6,9 @@ import { } from '@xyflow/react'; import { Toolbar } from '../components/NodeComponents'; import styles from '../../VisProg.module.css'; -import { NodeDefaults, NodeReduces } from '../NodeRegistry'; +import { NodeDefaults, NodeReduces, NodesInPhase, NodeTypes } from '../NodeRegistry'; +import useFlowStore from '../VisProgStores'; +import { TextField } from '../../../../components/TextField'; /** * The default data dot a phase node @@ -32,22 +34,33 @@ export type PhaseNode = Node * @returns React.JSX.Element */ export default function PhaseNode(props: NodeProps) { + const data = props.data as PhaseNodeData; + const {updateNodeData} = useFlowStore(); + + const updateLabel = (value: string) => updateNodeData(props.id, {...data, label: value}); + const label_input_id = `phase_${props.id}_label_input`; + return ( <>
- - {props.data.label as string} + +
+ -
); -} +}; /** * Reduces each phase, including its children down into its relevant data. @@ -86,10 +99,53 @@ export function PhaseReduce(node: Node, nodes: Node[]) { } } + +/** + * Reduces each phase, including its children down into its relevant data. + * @param props: The Node Properties of this node. + */ +export function PhaseReduce2(node: Node, nodes: Node[]) { + const thisnode = node as PhaseNode; + const data = thisnode.data as PhaseNodeData; + + // node typings that are not in phase + let nodesNotInPhase: string[] = Object.entries(NodesInPhase) + .filter(([, f]) => !f()) + .map(([t]) => t); + + // node typings that then are in phase + let nodesInPhase: string[] = Object.entries(NodeTypes) + .filter(([t]) => !nodesNotInPhase.includes(t)) + .map(([t]) => t); + + // children nodes + let childrenNodes = nodes.filter((node) => data.children.includes(node.id)); + + // Build the result object + let result: Record = { + id: thisnode.id, + label: data.label, + }; + + nodesInPhase.forEach((type) => { + let typedChildren = childrenNodes.filter((child) => child.type == type); + const reducer = NodeReduces[type as keyof typeof NodeReduces]; + if (!reducer) { + console.warn(`No reducer found for node type ${type}`); + result[type + "s"] = []; + } else { + result[type + "s"] = typedChildren.map((child) => reducer(child, nodes)); + } + }); + + return result; +} + + export function PhaseConnects(thisNode: Node, otherNode: Node, isThisSource: boolean) { console.log("Connect functionality called.") const node = thisNode as PhaseNode const data = node.data as PhaseNodeData - if (isThisSource) + if (!isThisSource) data.children.push(otherNode.id) } \ No newline at end of file diff --git a/src/pages/VisProgPage/visualProgrammingUI/nodes/TriggerNode.default.ts b/src/pages/VisProgPage/visualProgrammingUI/nodes/TriggerNode.default.ts index 725f0d8..d1daf4a 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/nodes/TriggerNode.default.ts +++ b/src/pages/VisProgPage/visualProgrammingUI/nodes/TriggerNode.default.ts @@ -6,7 +6,7 @@ import type { TriggerNodeData } from "./TriggerNode"; export const TriggerNodeDefaults: TriggerNodeData = { label: "Trigger Node", droppable: true, - triggers: [{id: "help-trigger", keyword:"help"}], + triggers: [], triggerType: "keywords", hasReduce: true, }; \ No newline at end of file