diff --git a/Data/Server/WebUI/src/nodes/Flow Control/Node_Edge_Toggle.jsx b/Data/Server/WebUI/src/nodes/Flow Control/Node_Edge_Toggle.jsx index a6b0fb3..0920c3a 100644 --- a/Data/Server/WebUI/src/nodes/Flow Control/Node_Edge_Toggle.jsx +++ b/Data/Server/WebUI/src/nodes/Flow Control/Node_Edge_Toggle.jsx @@ -1,41 +1,73 @@ +////////// PROJECT FILE SEPARATION LINE ////////// CODE AFTER THIS LINE ARE FROM: /Data/WebUI/src/nodes/General Purpose/Node_Edge_Toggle.jsx import React, { useEffect, useState, useRef } from "react"; import { Handle, Position, useReactFlow, useStore } from "reactflow"; import Switch from "@mui/material/Switch"; import Tooltip from "@mui/material/Tooltip"; -/** - * Borealis - Edge Toggle Node - * =========================== - * Allows users to toggle data flow between upstream and downstream nodes. - * - When enabled: propagates upstream value. - * - When disabled: outputs "0" (or null/blank) so downstream sees a cleared value. - */ +/* + Borealis - Edge Toggle Node + =========================== + Allows users to toggle data flow between upstream and downstream nodes. + - When enabled: propagates upstream value. + - When disabled: outputs "0" (or null/blank) so downstream sees a cleared value. + + Fully captures and restores toggle state ("enabled"/"disabled") from imported workflow JSON, + so state is always restored as last persisted. +*/ + +// Init shared value bus if needed +if (!window.BorealisValueBus) window.BorealisValueBus = {}; +if (!window.BorealisUpdateRate) window.BorealisUpdateRate = 100; + const EdgeToggleNode = ({ id, data }) => { const { setNodes } = useReactFlow(); const edges = useStore((state) => state.edges); - // Local state for switch - const [enabled, setEnabled] = useState(data?.enabled ?? true); - // What was last passed to output - const [outputValue, setOutputValue] = useState(undefined); + // === CAPTURE persisted toggle state on load/rehydrate === + // Restore "enabled" from node data if present, otherwise true + const [enabled, setEnabled] = useState( + typeof data?.enabled === "boolean" + ? data.enabled + : data?.enabled === "false" + ? false + : data?.enabled === "true" + ? true + : data?.enabled !== undefined + ? !!data.enabled + : true + ); + // Store last output value + const [outputValue, setOutputValue] = useState( + typeof data?.value !== "undefined" ? data.value : undefined + ); const outputRef = useRef(outputValue); - // Store enabled state persistently + // === Persist toggle state back to node data when toggled === useEffect(() => { - setNodes(nds => - nds.map(n => + setNodes((nds) => + nds.map((n) => n.id === id ? { ...n, data: { ...n.data, enabled } } : n ) ); }, [enabled, id, setNodes]); - // Main logic: propagate upstream if enabled, else always set downstream to "0" + // === On mount: restore BorealisValueBus from loaded node data if present === + useEffect(() => { + // Only run on first mount + if (typeof data?.value !== "undefined") { + window.BorealisValueBus[id] = data.value; + setOutputValue(data.value); + outputRef.current = data.value; + } + }, [id, data?.value]); + + // === Main interval logic: live propagate upstream/clear if off === useEffect(() => { let interval = null; let currentRate = window.BorealisUpdateRate || 100; const runNodeLogic = () => { - const inputEdge = edges.find(e => e.target === id); + const inputEdge = edges.find((e) => e.target === id); const hasInput = Boolean(inputEdge && inputEdge.source); if (enabled && hasInput) { @@ -44,8 +76,8 @@ const EdgeToggleNode = ({ id, data }) => { outputRef.current = upstreamValue; setOutputValue(upstreamValue); window.BorealisValueBus[id] = upstreamValue; - setNodes(nds => - nds.map(n => + setNodes((nds) => + nds.map((n) => n.id === id ? { ...n, data: { ...n.data, value: upstreamValue } } : n @@ -58,11 +90,9 @@ const EdgeToggleNode = ({ id, data }) => { outputRef.current = 0; setOutputValue(0); window.BorealisValueBus[id] = 0; - setNodes(nds => - nds.map(n => - n.id === id - ? { ...n, data: { ...n.data, value: 0 } } - : n + setNodes((nds) => + nds.map((n) => + n.id === id ? { ...n, data: { ...n.data, value: 0 } } : n ) ); } @@ -87,13 +117,17 @@ const EdgeToggleNode = ({ id, data }) => { }, [id, edges, enabled, setNodes]); // Edge input detection - const inputEdge = edges.find(e => e.target === id); + const inputEdge = edges.find((e) => e.target === id); const hasInput = Boolean(inputEdge && inputEdge.source); return (
{/* Input handle */} - + {/* Header */}
{data?.label || "Edge Toggle"} @@ -101,34 +135,43 @@ const EdgeToggleNode = ({ id, data }) => { {/* Content */}
- + setEnabled(e => !e)} + onChange={() => setEnabled((e) => !e)} sx={{ "& .MuiSwitch-switchBase.Mui-checked": { color: "#58a6ff", }, "& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track": { backgroundColor: "#58a6ff", - } + }, }} /> - + {enabled ? "Flow Enabled" : "Flow Disabled"}
{/* Output handle */} - +
); }; @@ -144,5 +187,32 @@ Toggles edge data flow ON/OFF using a switch. - Use to quickly enable/disable parts of your workflow without unlinking edges. `.trim(), content: "Toggle ON/OFF to allow or send zero downstream", - component: EdgeToggleNode -}; + component: EdgeToggleNode, + config: [ + { + key: "enabled", + label: "Toggle Enabled", + type: "select", + options: ["true", "false"], + defaultValue: "true" + } + ], + usage_documentation: ` +### Edge Toggle Node + +**Purpose:** +Allows you to control data flow along a workflow edge without disconnecting the wire. + +**Behavior:** +- When **Enabled**: passes upstream value downstream as usual. +- When **Disabled**: pushes \`0\` (zero) so that downstream logic always sees a cleared value (acts as an instant "mute" switch). + +**Persistence:** +- Toggle state is saved in the workflow and restored on load/import. + +**Tips:** +- Use for debug toggling, feature gating, or for rapid workflow prototyping. + +--- +`.trim() +}; \ No newline at end of file