diff --git a/Data/Server/WebUI/src/nodes/Agent/Node_Agent.jsx b/Data/Server/WebUI/src/nodes/Agent/Node_Agent.jsx index 36658cb..2dd39db 100644 --- a/Data/Server/WebUI/src/nodes/Agent/Node_Agent.jsx +++ b/Data/Server/WebUI/src/nodes/Agent/Node_Agent.jsx @@ -2,6 +2,7 @@ import React, { useEffect, useState, useCallback, useMemo, useRef } from "react"; import { Handle, Position, useReactFlow, useStore } from "reactflow"; +// Modern Node: Borealis Agent (Sidebar Config Enabled) const BorealisAgentNode = ({ id, data }) => { const { getNodes, setNodes } = useReactFlow(); const edges = useStore((state) => state.edges); @@ -10,7 +11,7 @@ const BorealisAgentNode = ({ id, data }) => { const [isConnected, setIsConnected] = useState(false); const prevRolesRef = useRef([]); - // ---------------- Agent List & Sorting ---------------- + // Agent List Sorted (Online First) const agentList = useMemo(() => { if (!agents || typeof agents !== "object") return []; return Object.entries(agents) @@ -23,7 +24,7 @@ const BorealisAgentNode = ({ id, data }) => { .sort((a, b) => b.last_seen - a.last_seen); }, [agents]); - // ---------------- Periodic Agent Fetching ---------------- + // Fetch Agents Periodically useEffect(() => { const fetchAgents = () => { fetch("/api/agents") @@ -36,7 +37,7 @@ const BorealisAgentNode = ({ id, data }) => { return () => clearInterval(interval); }, []); - // ---------------- Node Data Sync ---------------- + // Sync node data with sidebar changes useEffect(() => { setNodes((nds) => nds.map((n) => @@ -44,9 +45,9 @@ const BorealisAgentNode = ({ id, data }) => { ) ); setIsConnected(false); - }, [selectedAgent]); + }, [selectedAgent, setNodes, id]); - // ---------------- Attached Role Collection ---------------- + // Attached Roles logic const attachedRoleIds = useMemo( () => edges @@ -54,7 +55,6 @@ const BorealisAgentNode = ({ id, data }) => { .map((e) => e.target), [edges, id] ); - const getAttachedRoles = useCallback(() => { const allNodes = getNodes(); return attachedRoleIds @@ -65,9 +65,9 @@ const BorealisAgentNode = ({ id, data }) => { .filter((r) => r); }, [attachedRoleIds, getNodes]); - // ---------------- Provision Role Logic ---------------- + // Provision Roles to Agent const provisionRoles = useCallback((roles) => { - if (!selectedAgent) return; // Allow empty roles but require agent + if (!selectedAgent) return; fetch("/api/agent/provision", { method: "POST", headers: { "Content-Type": "application/json" }, @@ -79,12 +79,10 @@ const BorealisAgentNode = ({ id, data }) => { }) .catch(() => {}); }, [selectedAgent]); - const handleConnect = useCallback(() => { const roles = getAttachedRoles(); - provisionRoles(roles); // Always call even with empty roles + provisionRoles(roles); }, [getAttachedRoles, provisionRoles]); - const handleDisconnect = useCallback(() => { if (!selectedAgent) return; fetch("/api/agent/provision", { @@ -99,7 +97,7 @@ const BorealisAgentNode = ({ id, data }) => { .catch(() => {}); }, [selectedAgent]); - // ---------------- Auto-Provision When Roles Change ---------------- + // Auto-provision on role change useEffect(() => { const newRoles = getAttachedRoles(); const prevSerialized = JSON.stringify(prevRolesRef.current || []); @@ -109,7 +107,7 @@ const BorealisAgentNode = ({ id, data }) => { } }, [attachedRoleIds, isConnected, getAttachedRoles, provisionRoles]); - // ---------------- Status Label ---------------- + // Status Label const selectedAgentStatus = useMemo(() => { if (!selectedAgent) return "Unassigned"; const agent = agents[selectedAgent]; @@ -117,7 +115,7 @@ const BorealisAgentNode = ({ id, data }) => { return agent.status === "provisioned" ? "Connected" : "Available"; }, [agents, selectedAgent]); - // ---------------- Render ---------------- + // Render (Sidebar handles config) return (