From e7f1ea238688c1353cd3db032f21b6fffdf9aff8 Mon Sep 17 00:00:00 2001 From: nikita Date: Sat, 4 Apr 2026 12:38:21 +0300 Subject: [PATCH] fix: graphs --- .../app/providers/layout/sidebar/sidebar.tsx | 537 ++++++++++-------- frontend/src/modules/graph/Graph.tsx | 38 +- .../modules/graph/components/ForceGraph.tsx | 295 +++++----- .../graph/components/GraphControls.tsx | 116 ++-- .../modules/graph/components/GraphStats.tsx | 23 + .../src/modules/graph/components/index.ts | 1 + 6 files changed, 544 insertions(+), 466 deletions(-) create mode 100644 frontend/src/modules/graph/components/GraphStats.tsx diff --git a/frontend/src/app/providers/layout/sidebar/sidebar.tsx b/frontend/src/app/providers/layout/sidebar/sidebar.tsx index 5685785..894824c 100644 --- a/frontend/src/app/providers/layout/sidebar/sidebar.tsx +++ b/frontend/src/app/providers/layout/sidebar/sidebar.tsx @@ -10,10 +10,11 @@ import { FaChevronDown, FaProjectDiagram, FaTrash, + FaArrowLeft, } from "react-icons/fa"; -import { useNavigate } from "react-router-dom"; import { useAgentStore } from "@/app/providers/layout/store/agent.store"; import { useAuthStore } from "@/modules/auth/store/useAuthStore"; +import { Graph, type GraphData } from "@/modules/graph"; interface SidebarProps { isOpen?: boolean; @@ -24,13 +25,13 @@ export const Sidebar: React.FC = ({ isOpen = true, onToggle, }) => { - const navigate = useNavigate(); const { agents, isLoading, error, fetchAgents, removeAgent } = useAgentStore(); const { token } = useAuthStore(); const [searchQuery, setSearchQuery] = useState(""); const [copied, setCopied] = useState(false); const [showTokenModal, setShowTokenModal] = useState(false); + const [showGraphs, setShowGraphs] = useState(false); const [expandedAgents, setExpandedAgents] = useState>( new Set(agents.map((a) => a.name)), ); @@ -54,6 +55,40 @@ export const Sidebar: React.FC = ({ ); }, [agents, searchQuery]); + const graphData: GraphData = useMemo(() => { + const nodes = []; + const links = []; + + agents.forEach((agent) => { + nodes.push({ + id: agent.name, + name: agent.name, + type: "agent" as const, + val: 8, + description: `Агент: ${agent.name}`, + }); + + agent.services.forEach((service) => { + const serviceId = `${agent.name}-${service.name}`; + nodes.push({ + id: serviceId, + name: service.name, + type: "service" as const, + val: 12, + description: `Сервис: ${service.name} (${service.status})`, + }); + + links.push({ + source: agent.name, + target: serviceId, + type: "hosts", + }); + }); + }); + + return { nodes, links }; + }, [agents]); + const handleCopyToken = () => { if (token) { navigator.clipboard.writeText(token); @@ -87,10 +122,12 @@ export const Sidebar: React.FC = ({ />