152 lines
5.7 KiB
JavaScript
152 lines
5.7 KiB
JavaScript
import React, { useState, useEffect, useRef } from "react";
|
|
import SidebarMenu from "./SidebarMenu";
|
|
import TreeChart from "../TreeChart/TreeChart";
|
|
import "../../Style/Dashboard.css";
|
|
import SystemStatusChart from "../../Charts/SystemStatusChart";
|
|
import Tabs from "../UI/Tabs";
|
|
import menuData from "../TreeChart/menuData.json"; // Импортируем JSON-данные
|
|
import TreeTable from "../UI/TreeTable";
|
|
import { updateStatuses } from "../TreeChart/dataUtils"; // Функция обновления статусов
|
|
import generateTabContent from "../TreeChart/tabContent"; // Импортируем функцию generateTabContent
|
|
|
|
const Dashboard = () => {
|
|
const [tabs, setTabs] = useState([]);
|
|
const [activeTab, setActiveTab] = useState("Главная");
|
|
const [tabContent, setTabContent] = useState({}); // Состояние для контента вкладок
|
|
const [treeData, setTreeData] = useState(menuData); // Загружаем меню в state
|
|
const [sidebarWidth, setSidebarWidth] = useState(250); // Начальная ширина сайдбара
|
|
const [isResizing, setIsResizing] = useState(false); // Состояние перетаскивания
|
|
const [statusHistory, setStatusHistory] = useState([]); // История статусов для графика
|
|
const sidebarRef = useRef(null); // Референс на сайдбар
|
|
|
|
// Генерация контента для вкладок на основе menuData
|
|
useEffect(() => {
|
|
const generatedTabContent = generateTabContent(menuData);
|
|
setTabContent(generatedTabContent);
|
|
}, []);
|
|
|
|
// Обновление treeData каждые 30 секунд
|
|
useEffect(() => {
|
|
const interval = setInterval(() => {
|
|
setTreeData((prevData) => {
|
|
const updatedData = JSON.parse(JSON.stringify(prevData)); // Клонируем данные
|
|
const averageStatusValue = updateStatuses(updatedData); // Обновляем статусы и получаем среднее значение
|
|
|
|
// Преобразуем среднее значение в проценты (0% - 100%)
|
|
const statusPercentage = (1 - (averageStatusValue / 3)) * 100;
|
|
|
|
// Добавляем новое состояние в историю
|
|
setStatusHistory((prevHistory) => [
|
|
...prevHistory,
|
|
{ time: new Date().toLocaleTimeString(), status: statusPercentage }
|
|
]);
|
|
|
|
return updatedData;
|
|
});
|
|
}, 30000);
|
|
|
|
return () => clearInterval(interval);
|
|
}, []);
|
|
|
|
// Обработчик начала перетаскивания
|
|
const startResizing = (e) => {
|
|
e.preventDefault();
|
|
setIsResizing(true);
|
|
};
|
|
|
|
// Обработчик движения мыши
|
|
const resize = (e) => {
|
|
if (isResizing) {
|
|
const newWidth = e.clientX; // Новая ширина сайдбара
|
|
if (newWidth > 100 && newWidth < 400) { // Ограничиваем минимальную и максимальную ширину
|
|
setSidebarWidth(newWidth);
|
|
}
|
|
}
|
|
};
|
|
|
|
// Обработчик окончания перетаскивания
|
|
const stopResizing = () => {
|
|
setIsResizing(false);
|
|
};
|
|
|
|
// Добавляем обработчики событий
|
|
useEffect(() => {
|
|
const handleMouseMove = (e) => resize(e);
|
|
const handleMouseUp = () => stopResizing();
|
|
|
|
if (isResizing) {
|
|
window.addEventListener("mousemove", handleMouseMove);
|
|
window.addEventListener("mouseup", handleMouseUp);
|
|
}
|
|
|
|
return () => {
|
|
window.removeEventListener("mousemove", handleMouseMove);
|
|
window.removeEventListener("mouseup", handleMouseUp);
|
|
};
|
|
}, [isResizing]);
|
|
|
|
const handleOpenTab = (id, title) => {
|
|
if (!tabs.some((tab) => tab.id === id)) {
|
|
setTabs([...tabs, { id, title }]);
|
|
}
|
|
setActiveTab(id);
|
|
};
|
|
|
|
const handleCloseTab = (id) => {
|
|
const newTabs = tabs.filter((tab) => tab.id !== id);
|
|
setTabs(newTabs);
|
|
if (activeTab === id) {
|
|
setActiveTab(newTabs.length > 0 ? newTabs[newTabs.length - 1].id : "Главная");
|
|
}
|
|
};
|
|
|
|
const renderTabContent = () => {
|
|
if (activeTab === "Главная") {
|
|
return (
|
|
<div>
|
|
<h2>Общий мониторинг состояния системы</h2>
|
|
<label>Процент доверия системы </label>
|
|
<SystemStatusChart data={statusHistory} /> {/* График состояния системы */}
|
|
<label>Статус компонентов системы </label>
|
|
<TreeTable data={treeData} /> {/* Используем актуальные данные */}
|
|
</div>
|
|
);
|
|
} else if (activeTab === "Визуализация") {
|
|
return <TreeChart data={treeData} onNodeClick={(id, title) => handleOpenTab(id, title)} />;
|
|
} else {
|
|
const tabData = tabContent[activeTab];
|
|
return tabData ? tabData.content : <p>Нет данных</p>;
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="dashboard-container">
|
|
<div
|
|
className="sidebar"
|
|
ref={sidebarRef}
|
|
style={{ width: sidebarWidth }} // Динамическая ширина сайдбара
|
|
>
|
|
<SidebarMenu data={treeData} onOpenTab={handleOpenTab} sidebarWidth={sidebarWidth} />
|
|
{/* Элемент для перетаскивания */}
|
|
<div
|
|
className="sidebar-resizer"
|
|
onMouseDown={startResizing}
|
|
/>
|
|
</div>
|
|
|
|
<div className="main-content" style={{ marginLeft: sidebarWidth }}>
|
|
<Tabs
|
|
tabs={tabs}
|
|
activeTab={activeTab}
|
|
onTabClick={(id) => setActiveTab(id)}
|
|
onCloseTab={handleCloseTab}
|
|
/>
|
|
<div className="content">
|
|
{renderTabContent()}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Dashboard; |