diff --git a/src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx b/src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx index 49c296b..607c817 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx +++ b/src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx @@ -114,7 +114,7 @@ const useFlowStore = create((set, get) => ({ set({ nodes: get().nodes.map((node) => { if (node.id === nodeId) { - node.data = { ...node.data, ...data }; + node = { ...node, data: { ...node.data, ...data }}; } return node; }), diff --git a/src/pages/VisProgPage/visualProgrammingUI/components/DragDropSidebar.tsx b/src/pages/VisProgPage/visualProgrammingUI/components/DragDropSidebar.tsx index d59d821..b67f55f 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/components/DragDropSidebar.tsx +++ b/src/pages/VisProgPage/visualProgrammingUI/components/DragDropSidebar.tsx @@ -124,7 +124,7 @@ export function DndToolbar() { } {droppableNodes.map(({type, data}) => ( diff --git a/src/pages/VisProgPage/visualProgrammingUI/components/TriggerNodeComponent.tsx b/src/pages/VisProgPage/visualProgrammingUI/components/TriggerNodeComponent.tsx deleted file mode 100644 index 9c0b342..0000000 --- a/src/pages/VisProgPage/visualProgrammingUI/components/TriggerNodeComponent.tsx +++ /dev/null @@ -1,121 +0,0 @@ -import {Handle, type NodeProps, Position} from "@xyflow/react"; -import useFlowStore from "../VisProgStores.tsx"; -import styles from "../../VisProg.module.css"; -import {RealtimeTextField, TextField} from "../../../../components/TextField.tsx"; -import {Toolbar} from "./NodeComponents.tsx"; -import {useState} from "react"; -import duplicateIndices from "../../../../utils/duplicateIndices.ts"; -import type { TriggerNode } from "../nodes/TriggerNode.tsx"; - -export type EmotionTriggerNodeProps = { - type: "emotion"; - value: string; -} - -type Keyword = { id: string, keyword: string }; - -export type KeywordTriggerNodeProps = { - type: "keywords"; - value: Keyword[]; -} - -export type TriggerNodeProps = EmotionTriggerNodeProps | KeywordTriggerNodeProps; - -function KeywordAdder({ addKeyword }: { addKeyword: (keyword: string) => void }) { - const [input, setInput] = useState(""); - - const text_input_id = "keyword_adder_input"; - - return
- - { - if (!input) return; - addKeyword(input); - setInput(""); - }} - placeholder={"..."} - className={"flex-1"} - /> -
; -} - -function Keywords({ - keywords, - setKeywords, -}: { - keywords: Keyword[]; - setKeywords: (keywords: Keyword[]) => void; -}) { - type Interpolatable = string | number | boolean | bigint | null | undefined; - - const inputElementId = (id: Interpolatable) => `keyword_${id}_input`; - - /** Indices of duplicates in the keyword array. */ - const [duplicates, setDuplicates] = useState([]); - - function replace(id: string, value: string) { - value = value.trim(); - const newKeywords = value === "" - ? keywords.filter((kw) => kw.id != id) - : keywords.map((kw) => kw.id === id ? {...kw, keyword: value} : kw); - setKeywords(newKeywords); - setDuplicates(duplicateIndices(newKeywords.map((kw) => kw.keyword))); - } - - function add(value: string) { - value = value.trim(); - if (value === "") return; - const newKeywords = [...keywords, {id: crypto.randomUUID(), keyword: value}]; - setKeywords(newKeywords); - setDuplicates(duplicateIndices(newKeywords.map((kw) => kw.keyword))); - } - - return <> - Triggers when {keywords.length <= 1 ? "the keyword is" : "all keywords are"} spoken. - {[...keywords].map(({id, keyword}, index) => { - return
- - replace(id, val)} - placeholder={"..."} - className={"flex-1"} - invalid={duplicates.includes(index)} - /> -
; - })} - - ; -} - -// export default function TriggerNodeComponent({ -// id, -// data, -// }: NodeProps) { -// const {updateNodeData} = useFlowStore(); - -// const setKeywords = (keywords: Keyword[]) => { -// updateNodeData(id, {...data, value: keywords}); -// } - -// return <> -// -//
-// {data.type === "emotion" && ( -//
Emotion?
-// )} -// {data.type === "keywords" && ( -// -// )} -// -//
-// ; -// } diff --git a/src/pages/VisProgPage/visualProgrammingUI/nodes/EndNode.tsx b/src/pages/VisProgPage/visualProgrammingUI/nodes/EndNode.tsx index b7159b6..c6f8f14 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/nodes/EndNode.tsx +++ b/src/pages/VisProgPage/visualProgrammingUI/nodes/EndNode.tsx @@ -7,6 +7,9 @@ import { import { Toolbar } from '../components/NodeComponents'; import styles from '../../VisProg.module.css'; +/** + * The typing of this node's data + */ export type EndNodeData = { label: string; droppable: boolean; @@ -15,6 +18,11 @@ export type EndNodeData = { export type EndNode = Node +/** + * Default function to render an end node given its properties + * @param props the node's properties + * @returns React.JSX.Element + */ export default function EndNode(props: NodeProps) { return ( <> @@ -23,13 +31,18 @@ export default function EndNode(props: NodeProps) {
End
- - + ); } +/** + * Functionality for reducing this node into its more compact json program + * @param node the node to reduce + * @param nodes all nodes present + * @returns Dictionary, {id: node.id} + */ export function EndReduce(node: Node, nodes: Node[]) { // Replace this for nodes functionality if (nodes.length <= -1) { @@ -40,6 +53,12 @@ export function EndReduce(node: Node, nodes: Node[]) { } } +/** + * Any connection functionality that should get called when a connection is made to this node + * @param thisNode the node of which the functionality gets called + * @param otherNode the other node which has connected + * @param isThisSource whether this node is the one that is the source of the connection + */ export function EndConnects(thisNode: Node, otherNode: Node, isThisSource: boolean) { // Replace this for connection logic if (thisNode == undefined && otherNode == undefined && isThisSource == false) { diff --git a/src/pages/VisProgPage/visualProgrammingUI/nodes/GoalNode.tsx b/src/pages/VisProgPage/visualProgrammingUI/nodes/GoalNode.tsx index ce0b119..322d6bb 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/nodes/GoalNode.tsx +++ b/src/pages/VisProgPage/visualProgrammingUI/nodes/GoalNode.tsx @@ -12,10 +12,11 @@ import { TextField } from '../../../../components/TextField'; import useFlowStore from '../VisProgStores'; /** - * The default data dot a Goal node - * @param label: the label of this Goal + * 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 children: ID's of children of this node + * @param desciption: description of the goal + * @param hasReduce: whether this node has reducing functionality (true by default) */ export type GoalNodeData = { label: string; diff --git a/src/pages/VisProgPage/visualProgrammingUI/nodes/NormNode.tsx b/src/pages/VisProgPage/visualProgrammingUI/nodes/NormNode.tsx index fde48ea..4dee91f 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/nodes/NormNode.tsx +++ b/src/pages/VisProgPage/visualProgrammingUI/nodes/NormNode.tsx @@ -8,12 +8,14 @@ import { } from '@xyflow/react'; import { Toolbar } from '../components/NodeComponents'; import styles from '../../VisProg.module.css'; +import { TextField } from '../../../../components/TextField'; /** - * The default data dot a Norm node - * @param label: the label of this Norm + * 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 children: ID's of children of this node + * @param normList: list of strings of norms for this node + * @param hasReduce: whether this node has reducing functionality (true by default) */ export type NormNodeData = { label: string; @@ -47,7 +49,10 @@ export default function NormNode(props: NodeProps) { {props.data.label as string} - {data.normList.map((norm) => (
{norm}
))} +
+ +
+ @@ -75,4 +80,25 @@ 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 548753f..e6a6bfb 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/nodes/PhaseNode.tsx +++ b/src/pages/VisProgPage/visualProgrammingUI/nodes/PhaseNode.tsx @@ -13,6 +13,7 @@ import { NodeDefaults, NodeReduces } from '../NodeRegistry'; * @param label: the label of this phase * @param droppable: whether this node is droppable from the drop bar (initialized as true) * @param children: ID's of children of this node + * @param hasReduce: whether this node has reducing functionality (true by default) */ export type PhaseNodeData = { label: string; @@ -43,7 +44,6 @@ export default function PhaseNode(props: NodeProps) { - ); diff --git a/src/pages/VisProgPage/visualProgrammingUI/nodes/StartNode.tsx b/src/pages/VisProgPage/visualProgrammingUI/nodes/StartNode.tsx index d99a6ef..ac5bb0c 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/nodes/StartNode.tsx +++ b/src/pages/VisProgPage/visualProgrammingUI/nodes/StartNode.tsx @@ -25,8 +25,6 @@ export default function StartNode(props: NodeProps) {
Start
- - diff --git a/src/pages/VisProgPage/visualProgrammingUI/nodes/TriggerNode.tsx b/src/pages/VisProgPage/visualProgrammingUI/nodes/TriggerNode.tsx index 97a792e..299bc24 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/nodes/TriggerNode.tsx +++ b/src/pages/VisProgPage/visualProgrammingUI/nodes/TriggerNode.tsx @@ -22,8 +22,8 @@ import duplicateIndices from '../../../../utils/duplicateIndices'; export type TriggerNodeData = { label: string; droppable: boolean; - triggerType: unknown; - triggers: [unknown]; + triggerType: "keywords" | string; + triggers: Keyword[] | never; hasReduce: boolean; }; @@ -56,7 +56,7 @@ export default function TriggerNode(props: NodeProps) { )} {data.triggerType === "keywords" && ( )}