chore: cleanup broken tests, add extra documentation, make sure everything is clean and code style isn't inconsistant

This commit is contained in:
Björn Otgaar
2025-11-19 10:13:08 +01:00
parent 8c2e51114e
commit f37df1c726
12 changed files with 56 additions and 74 deletions

View File

@@ -141,4 +141,4 @@ function VisProgPage() {
)
}
export default VisProgPage
export default VisProgPage

View File

@@ -25,6 +25,7 @@ export const NodeTypes = {
/**
* The default functions of the nodes we have registered.
* These are defined in the <node>.default.ts files.
*/
export const NodeDefaults = {
start: StartNodeDefaults,

View File

@@ -47,6 +47,12 @@ const initialEdges: Edge[] = [
{ id: 'phase-1-end', source: 'phase-1', target: 'end' },
];
/**
* How we have defined the functions for our FlowState.
* We have the normal functionality of a default FlowState with some exceptions to account for extra functionality.
* The biggest changes are in onConnect and onDelete, which we have given extra functionality based on the nodes defined functions.
*/
const useFlowStore = create<FlowState>((set, get) => ({
nodes: initialNodes,
edges: initialEdges,
@@ -56,7 +62,6 @@ const useFlowStore = create<FlowState>((set, get) => ({
set({nodes: applyNodeChanges(changes, get().nodes)}),
onEdgesChange: (changes) => set({ edges: applyEdgeChanges(changes, get().edges) }),
// Let's make sure we tell the nodes when they're connected, and how it matters.
onConnect: (connection) => {
const edges = addEdge(connection, get().edges);
const nodes = get().nodes;

View File

@@ -47,12 +47,13 @@ function DraggableNode({ className, children, nodeType, onDrop }: DraggableNodeP
* addNode — adds a new node to the flow using the unified class-based system.
* Keeps numbering logic for phase/norm nodes.
*/
function addNode(nodeType: keyof typeof NodeTypes, position: XYPosition) {
function addNode(nodeType: keyof typeof NodeTypes, position: XYPosition) {
const { nodes, setNodes } = useFlowStore.getState();
const defaultData = NodeDefaults[nodeType]
if (!defaultData) throw new Error(`Node type '${nodeType}' not found in registry`);
// Find out if there's any default data about our ndoe
const defaultData = NodeDefaults[nodeType] ?? {}
// Currently, we find out what the Id is by checking the last node and adding one
const sameTypeNodes = nodes.filter((node) => node.type === nodeType);
const nextNumber =
sameTypeNodes.length > 0
@@ -63,9 +64,9 @@ function DraggableNode({ className, children, nodeType, onDrop }: DraggableNodeP
return Number.isNaN(lastNum) ? sameTypeNodes.length + 1 : lastNum + 1;
})()
: 1;
const id = `${nodeType}-${nextNumber}`;
// Create new node
const newNode = {
id: id,
type: nodeType,
@@ -104,6 +105,7 @@ export function DndToolbar() {
);
// Map over our default settings to see which of them have their droppable data set to true
const droppableNodes = Object.entries(NodeDefaults)
.filter(([, data]) => data.droppable)
.map(([type, data]) => ({
@@ -111,20 +113,16 @@ export function DndToolbar() {
data
}));
return (
<div className={`flex-col gap-lg padding-md ${styles.innerDndPanel}`}>
<div className="description">
You can drag these nodes to the pane to create new nodes.
</div>
<div className={`flex-row gap-lg ${styles.dndNodeContainer}`}>
{
// Maps over all the nodes that are droppable, and puts them in the panel
}
{/* Maps over all the nodes that are droppable, and puts them in the panel */}
{droppableNodes.map(({type, data}) => (
<DraggableNode
className={styles[`draggable-node-${type}`]}
className={styles[`draggable-node-${type}`]} // Our current style signature for nodes
nodeType={type}
onDrop={handleNodeDrop}
>

View File

@@ -54,7 +54,7 @@ export function EndReduce(node: Node, nodes: Node[]) {
}
/**
* Any connection functionality that should get called when a connection is made to this node
* Any connection functionality that should get called when a connection is made to this node type (end)
* @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

View File

@@ -2,8 +2,6 @@ import {
Handle,
type NodeProps,
Position,
type Connection,
type Edge,
type Node,
} from '@xyflow/react';
import { Toolbar } from '../components/NodeComponents';
@@ -26,15 +24,9 @@ export type GoalNodeData = {
hasReduce: boolean;
};
export type GoalNode = Node<GoalNodeData>
export function GoalNodeCanConnect(connection: Connection | Edge): boolean {
return (connection != undefined);
}
/**
* Defines how a Goal node should be rendered
* @param props NodeProps, like id, label, children

View File

@@ -2,8 +2,6 @@ import {
Handle,
type NodeProps,
Position,
type Connection,
type Edge,
type Node,
} from '@xyflow/react';
import { Toolbar } from '../components/NodeComponents';
@@ -25,15 +23,8 @@ export type NormNodeData = {
hasReduce: boolean;
};
export type NormNode = Node<NormNodeData>
export function NormNodeCanConnect(connection: Connection | Edge): boolean {
return (connection != undefined);
}
/**
* Defines how a Norm node should be rendered
* @param props NodeProps, like id, label, children

View File

@@ -24,10 +24,8 @@ export type PhaseNodeData = {
hasReduce: boolean;
};
export type PhaseNode = Node<PhaseNodeData>
/**
* Defines how a phase node should be rendered
* @param props NodeProps, like id, label, children
@@ -36,9 +34,7 @@ export type PhaseNode = Node<PhaseNodeData>
export default function PhaseNode(props: NodeProps<Node>) {
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 (
@@ -62,10 +58,11 @@ export default function PhaseNode(props: NodeProps<Node>) {
);
};
/**
* Reduces each phase, including its children down into its relevant data.
* @param props: The Node Properties of this node.
* @param node the node which is being reduced
* @param nodes all the nodes currently in the flow.
* @returns A collection of all reduced nodes in this phase, starting with this phases' reduced data.
*/
export function PhaseReduce(node: Node, nodes: Node[]) {
const thisnode = node as PhaseNode;
@@ -104,7 +101,12 @@ export function PhaseReduce(node: Node, nodes: Node[]) {
return result;
}
/**
* This function is called whenever a connection is made with this node type (phase)
* @param thisNode the node of this node type which function is called
* @param otherNode the other node which was part of the connection
* @param isThisSource whether this instance of the node was the source in the connection, true = yes.
*/
export function PhaseConnects(thisNode: Node, otherNode: Node, isThisSource: boolean) {
console.log("Connect functionality called.")
const node = thisNode as PhaseNode

View File

@@ -41,6 +41,12 @@ export function StartReduce(node: Node, nodes: Node[]) {
}
}
/**
* This function is called whenever a connection is made with this node type (start)
* @param thisNode the node of this node type which function is called
* @param otherNode the other node which was part of the connection
* @param isThisSource whether this instance of the node was the source in the connection, true = yes.
*/
export function StartConnects(thisNode: Node, otherNode: Node, isThisSource: boolean) {
// Replace this for connection logic
if (thisNode == undefined && otherNode == undefined && isThisSource == false) {

View File

@@ -81,6 +81,12 @@ export function TriggerReduce(node: Node, nodes: Node[]) {
}
}
/**
* This function is called whenever a connection is made with this node type (trigger)
* @param thisNode the node of this node type which function is called
* @param otherNode the other node which was part of the connection
* @param isThisSource whether this instance of the node was the source in the connection, true = yes.
*/
export function TriggerConnects(thisNode: Node, otherNode: Node, isThisSource: boolean) {
// Replace this for connection logic
if (thisNode == undefined && otherNode == undefined && isThisSource == false) {
@@ -88,14 +94,13 @@ export function TriggerConnects(thisNode: Node, otherNode: Node, isThisSource: b
}
}
// Definitions for the possible triggers, being keywords and emotions
type Keyword = { id: string, keyword: string };
export type EmotionTriggerNodeProps = {
type: "emotion";
value: string;
}
type Keyword = { id: string, keyword: string };
export type KeywordTriggerNodeProps = {
type: "keywords";
value: Keyword[];
@@ -103,6 +108,11 @@ export type KeywordTriggerNodeProps = {
export type TriggerNodeProps = EmotionTriggerNodeProps | KeywordTriggerNodeProps;
/**
* The JSX element that is responsible for updating the field and showing the text
* @param param0 the function that updates the field
* @returns React.JSX.Element that handles adding keywords
*/
function KeywordAdder({ addKeyword }: { addKeyword: (keyword: string) => void }) {
const [input, setInput] = useState("");

View File

@@ -0,0 +1,5 @@
describe('not yet implemented', () => {
test('nothing yet', () => {
expect(true);
});
});

View File

@@ -1,33 +1,5 @@
// import { mockReactFlow } from '../../../../setupFlowTests.ts';
// import {act} from "@testing-library/react";
// import useFlowStore from "../../../../../src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx";
// import {addNode} from "../../../../../src/pages/VisProgPage/visualProgrammingUI/components/DragDropSidebar.tsx";
// beforeAll(() => {
// mockReactFlow();
// });
// describe('Drag-and-Drop sidebar', () => {
// test.each(['phase', 'phase'])('new nodes get added correctly', (nodeType: string) => {
// act(()=> {
// addNode(nodeType, {x:100, y:100});
// })
// const updatedState = useFlowStore.getState();
// expect(updatedState.nodes.length).toBe(1);
// expect(updatedState.nodes[0].type).toBe(nodeType);
// });
// test.each(['phase', 'norm'])('new nodes get correct Id', (nodeType) => {
// act(()=> {
// addNode(nodeType, {x:100, y:100});
// addNode(nodeType, {x:100, y:100});
// })
// const updatedState = useFlowStore.getState();
// expect(updatedState.nodes.length).toBe(2);
// expect(updatedState.nodes[0].id).toBe(`${nodeType}-1`);
// expect(updatedState.nodes[1].id).toBe(`${nodeType}-2`);
// });
// test('throws error on unexpected node type', () => {
// expect(() => addNode('I do not Exist', {x:100, y:100})).toThrow("Node I do not Exist not found");
// })
// });
describe('Not implemented', () => {
test('nothing yet', () => {
expect(true)
});
});