Files
pepperplus-ui/src/pages/VisProgPage/visualProgrammingUI/nodes/NormNode.tsx
Pim Hutting faaf67138d Merge branch 'feat/norm-critical-checkbox' into 'demo'
feat: add critical checkbox to the norm node, send it with the program, add test.

See merge request ics/sp/2025/n25b/pepperplus-ui!29
2025-12-16 13:12:59 +00:00

125 lines
3.9 KiB
TypeScript

import {
Handle,
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 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 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;
norm: string;
hasReduce: boolean;
critical: boolean;
};
export type NormNode = Node<NormNodeData>
/**
* 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<NormNode>) {
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 <>
<Toolbar nodeId={props.id} allowDelete={true}/>
<div className={`${styles.defaultNode} ${styles.nodeNorm}`}>
<div className={"flex-row gap-sm"}>
<label htmlFor={text_input_id}>Norm :</label>
<TextField
id={text_input_id}
value={data.norm}
setValue={(val) => setValue(val)}
placeholder={"Pepper should ..."}
/>
</div>
<div className={"flex-row gap-md align-center"}>
<label htmlFor={checkbox_id}>Critical:</label>
<input
id={checkbox_id}
type={"checkbox"}
checked={data.critical || false}
onChange={(e) => setCritical(e.target.checked)}
/>
</div>
<Handle type="source" position={Position.Right} id="norms"/>
</div>
</>;
};
/**
* 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;
return {
id: node.id,
label: data.label,
norm: data.norm,
critical: data.critical,
}
}
/**
* 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) {
// 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 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) {
// 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 NormDisconnectionSource(_thisNode: Node, _targetNodeId: string) {
// no additional connection logic exists yet
}