From a6f24b677ff0a075853eb63b472af701237f7941 Mon Sep 17 00:00:00 2001 From: JGerla Date: Thu, 15 Jan 2026 16:09:24 +0100 Subject: [PATCH] feat: added two new warnings ref: N25B-450 --- .../components/WarningSidebar.module.css | 4 +-- .../visualProgrammingUI/nodes/EndNode.tsx | 26 ++++++++++++++++++- .../visualProgrammingUI/nodes/PhaseNode.tsx | 25 +++++++++++++++++- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/pages/VisProgPage/visualProgrammingUI/components/WarningSidebar.module.css b/src/pages/VisProgPage/visualProgrammingUI/components/WarningSidebar.module.css index 182d99e..97f04b1 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/components/WarningSidebar.module.css +++ b/src/pages/VisProgPage/visualProgrammingUI/components/WarningSidebar.module.css @@ -60,11 +60,11 @@ } .warning-item--warning { - border-left: 3px solid orange; + border: 3px solid orange; } .warning-item--info { - border-left: 3px solid steelblue; + border: 3px solid steelblue; } .warning-item .meta { diff --git a/src/pages/VisProgPage/visualProgrammingUI/nodes/EndNode.tsx b/src/pages/VisProgPage/visualProgrammingUI/nodes/EndNode.tsx index 5c456b5..5bed205 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/nodes/EndNode.tsx +++ b/src/pages/VisProgPage/visualProgrammingUI/nodes/EndNode.tsx @@ -1,12 +1,15 @@ import { type NodeProps, Position, - type Node, + type Node, useNodeConnections } from '@xyflow/react'; +import {useEffect} from "react"; +import type {EditorWarning} from "../components/EditorWarnings.tsx"; import { Toolbar } from '../components/NodeComponents'; import styles from '../../VisProg.module.css'; import {SingleConnectionHandle} from "../components/RuleBasedHandle.tsx"; import {allowOnlyConnectionsFromType} from "../HandleRules.ts"; +import useFlowStore from "../VisProgStores.tsx"; @@ -27,6 +30,27 @@ export type EndNode = Node * @returns React.JSX.Element */ export default function EndNode(props: NodeProps) { + const {registerWarning, unregisterWarning} = useFlowStore.getState(); + const connections = useNodeConnections({ + id: props.id, + handleId: 'target' + }) + + useEffect(() => { + const noConnectionWarning : EditorWarning = { + scope: { + id: props.id, + handleId: 'target' + }, + type: 'MISSING_INPUT', + severity: "ERROR", + description: "the endNode does not have an incoming connection from a phaseNode" + } + + if (connections.length === 0) { registerWarning(noConnectionWarning); } + else { unregisterWarning(props.id, `${noConnectionWarning.type}:target`); } + }, [connections.length, props.id, registerWarning, unregisterWarning]); + return ( <> diff --git a/src/pages/VisProgPage/visualProgrammingUI/nodes/PhaseNode.tsx b/src/pages/VisProgPage/visualProgrammingUI/nodes/PhaseNode.tsx index 9a48103..e80aec3 100644 --- a/src/pages/VisProgPage/visualProgrammingUI/nodes/PhaseNode.tsx +++ b/src/pages/VisProgPage/visualProgrammingUI/nodes/PhaseNode.tsx @@ -1,8 +1,10 @@ import { type NodeProps, Position, - type Node + type Node, useNodeConnections } from '@xyflow/react'; +import {useEffect} from "react"; +import type {EditorWarning} from "../components/EditorWarnings.tsx"; import { Toolbar } from '../components/NodeComponents'; import styles from '../../VisProg.module.css'; import {SingleConnectionHandle, MultiConnectionHandle} from "../components/RuleBasedHandle.tsx"; @@ -41,6 +43,27 @@ export default function PhaseNode(props: NodeProps) { const updateLabel = (value: string) => updateNodeData(props.id, {...data, label: value}); const label_input_id = `phase_${props.id}_label_input`; + const {registerWarning, unregisterWarning} = useFlowStore.getState(); + const connections = useNodeConnections({ + id: props.id, + handleId: 'data' + }) + + useEffect(() => { + const noConnectionWarning : EditorWarning = { + scope: { + id: props.id, + handleId: 'data' + }, + type: 'MISSING_INPUT', + severity: "WARNING", + description: "the phaseNode has no incoming goals, norms, and/or triggers" + } + + if (connections.length === 0) { registerWarning(noConnectionWarning); } + else { unregisterWarning(props.id, `${noConnectionWarning.type}:source`); } + }, [connections.length, props.id, registerWarning, unregisterWarning]); + return ( <>