diff --git a/frontend/src/GraphView.jsx b/frontend/src/GraphView.jsx index 48175af..46ff2c9 100644 --- a/frontend/src/GraphView.jsx +++ b/frontend/src/GraphView.jsx @@ -1,15 +1,17 @@ import React, { useState, useRef, useEffect } from 'react'; import * as d3 from 'd3'; -import { IconZoomIn, IconZoomOut, IconMaximize } from '@tabler/icons-react'; +import { IconZoomIn, IconZoomOut, IconMaximize, IconMinimize } from '@tabler/icons-react'; function GraphView({ servers, connections }) { const [nodePositions, setNodePositions] = useState({}); const [draggedNode, setDraggedNode] = useState(null); const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 }); const [hoveredLinkId, setHoveredLinkId] = useState(null); + const containerRef = useRef(null); const svgRef = useRef(null); const gRef = useRef(null); const zoomRef = useRef(null); + const [isFullscreen, setIsFullscreen] = useState(false); // Размеры карточки узла const NODE_WIDTH = 160; @@ -111,6 +113,23 @@ function GraphView({ servers, connections }) { d3.select(svgEl).transition().duration(250).call(zoomRef.current.transform, t); }; + // Полноэкранный режим + useEffect(() => { + const handler = () => setIsFullscreen(Boolean(document.fullscreenElement)); + document.addEventListener('fullscreenchange', handler); + return () => document.removeEventListener('fullscreenchange', handler); + }, []); + + const toggleFullscreen = () => { + const el = containerRef.current; + if (!el) return; + if (!document.fullscreenElement) { + el.requestFullscreen?.(); + } else { + document.exitFullscreen?.(); + } + }; + if (servers.length === 0) { return (
@@ -222,7 +241,7 @@ function GraphView({ servers, connections }) { }; return ( -
+
{flag} @@ -462,7 +482,7 @@ function GraphView({ servers, connections }) { {/* Контролы масштабирования */} -
+
-