fixed a bug with tabs
parent
40d8046617
commit
6fd5d1aed2
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import {
|
||||
Drawer,
|
||||
List,
|
||||
|
|
@ -35,11 +35,10 @@ const SidebarResizer = styled('div')(({ theme }) => ({
|
|||
const SidebarMenu = ({ data, onOpenTab, sidebarWidth, startResizing, collapsed, setCollapsed }) => {
|
||||
const [hovered, setHovered] = useState(false);
|
||||
const [menuData, setMenuData] = useState(data);
|
||||
const contentCache = useRef({});
|
||||
|
||||
// Обновляем статусы при изменении данных
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
// Создаем глубокую копию данных, чтобы не мутировать исходные
|
||||
const dataCopy = JSON.parse(JSON.stringify(data));
|
||||
statusManager1.updateStatuses(dataCopy);
|
||||
setMenuData(dataCopy);
|
||||
|
|
@ -51,9 +50,16 @@ const SidebarMenu = ({ data, onOpenTab, sidebarWidth, startResizing, collapsed,
|
|||
};
|
||||
|
||||
const handleSelectItem = (id, title, children) => {
|
||||
onOpenTab(id, title, children);
|
||||
onOpenTab(id, title);
|
||||
|
||||
contentCache.current = tabContent({ items: children }, contentCache.current);
|
||||
if (contentCache.current[id]) {
|
||||
onOpenTab(id, title, contentCache.current[id].content);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
const drawerWidth = collapsed ? 64 : sidebarWidth;
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -5,26 +5,23 @@ import Box from '@mui/material/Box';
|
|||
const PrometheusChart = lazy(() => import('../../Charts/PrometheusChart'));
|
||||
import LazyChartBatchRenderer from "../hooks/LazyChartBatchRender";
|
||||
|
||||
// Функция для генерации названия метрики на основе id
|
||||
const getMetricName = (id) => {
|
||||
return `zvks_apiforsnmp_measure_${id}`;
|
||||
};
|
||||
|
||||
// Функция для рекурсивного сбора всех id потомков
|
||||
const getAllChildIds = (node) => {
|
||||
let ids = [];
|
||||
if (node.id) {
|
||||
ids.push(node.id); // Добавляем id текущего узла
|
||||
ids.push(node.id);
|
||||
}
|
||||
if (node.items && node.items.length > 0) {
|
||||
node.items.forEach((child) => {
|
||||
ids = ids.concat(getAllChildIds(child)); // Рекурсивно собираем id потомков
|
||||
ids = ids.concat(getAllChildIds(child));
|
||||
});
|
||||
}
|
||||
return ids;
|
||||
};
|
||||
|
||||
// Компонент Skeleton для графика
|
||||
const ChartSkeleton = () => (
|
||||
<Box sx={{ width: '100%' }}>
|
||||
<Skeleton variant="text" width="60%" height={30} /> {/* Заголовок */}
|
||||
|
|
@ -32,7 +29,6 @@ const ChartSkeleton = () => (
|
|||
</Box>
|
||||
);
|
||||
|
||||
// Компонент Skeleton для родительского контейнера
|
||||
const ContainerSkeleton = () => (
|
||||
<Box sx={{ width: '100%' }}>
|
||||
<Skeleton variant="text" width="40%" height={40} /> {/* Заголовок */}
|
||||
|
|
@ -46,69 +42,52 @@ const ContainerSkeleton = () => (
|
|||
</Box>
|
||||
);
|
||||
|
||||
const tabContent = (data) => {
|
||||
const tabContent = {};
|
||||
const tabContent = (data, existingContent = {}) => {
|
||||
const tabContent = { ...existingContent };
|
||||
|
||||
// Функция для рекурсивного обхода и сбора данных
|
||||
// Функция для рекурсивного обхода и сбора данных
|
||||
const generateContent = (nodes) => {
|
||||
nodes.forEach((node) => {
|
||||
// Если у узла есть вложенные элементы, рекурсивно обрабатываем их
|
||||
if (tabContent[node.id]) return;
|
||||
|
||||
if (node.items && node.items.length > 0) {
|
||||
// Создаем контент для родителя
|
||||
const childrenContent = generateContent(node.items);
|
||||
generateContent(node.items);
|
||||
|
||||
const content = (
|
||||
<div>
|
||||
<div key={node.id}>
|
||||
<h2>{node.title}</h2>
|
||||
<Suspense fallback={<ContainerSkeleton />}>
|
||||
<LazyChartBatchRenderer charts={node.items.map((child) => tabContent[child.id].content)} />
|
||||
<LazyChartBatchRenderer
|
||||
charts={node.items.map(child => tabContent[child.id]?.content) || <ChartSkeleton />}
|
||||
/>
|
||||
</Suspense>
|
||||
<p>Контент для {node.title}.</p>
|
||||
{/*childrenContent*/}
|
||||
</div>
|
||||
);
|
||||
|
||||
// Сохраняем контент для текущего id
|
||||
tabContent[node.id] = {
|
||||
title: node.title,
|
||||
content: content,
|
||||
};
|
||||
} else {
|
||||
// Если у узла нет вложенных элементов, это самый нижний уровень
|
||||
const metricName = getMetricName(node.id);
|
||||
const content = (
|
||||
<div key={node.id}>
|
||||
<h3>{node.title}</h3> {/* Используем title узла */}
|
||||
<h3>{node.title}</h3>
|
||||
<Suspense fallback={<ChartSkeleton />}>
|
||||
<PrometheusChart metricName={metricName} />
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
|
||||
// Сохраняем контент для текущего id
|
||||
tabContent[node.id] = {
|
||||
title: node.title,
|
||||
content: content,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// Возвращаем контент для всех потомков
|
||||
return (
|
||||
<div>
|
||||
{nodes.map((node) => (
|
||||
<div key={node.id}>{tabContent[node.id].content}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Начинаем обработку с корневого уровня
|
||||
if (data.items && data.items.length > 0) {
|
||||
generateContent(data.items);
|
||||
} else {
|
||||
console.warn("Данные отсутствуют или массив items пуст");
|
||||
}
|
||||
|
||||
return tabContent;
|
||||
|
|
|
|||
|
|
@ -4,23 +4,63 @@ const useTabs = (initialTab) => {
|
|||
const [tabs, setTabs] = useState([]);
|
||||
const [activeTab, setActiveTab] = useState(initialTab);
|
||||
|
||||
const handleOpenTab = useCallback((id, title) => {
|
||||
setTabs((prevTabs) =>
|
||||
prevTabs.some((tab) => tab.id === id)
|
||||
? prevTabs
|
||||
: [...prevTabs, { id, title }]
|
||||
);
|
||||
const handleOpenTab = useCallback((id, title, content) => {
|
||||
setTabs((prevTabs) => {
|
||||
const existingTabIndex = prevTabs.findIndex(tab => tab.id === id);
|
||||
|
||||
if (existingTabIndex >= 0) {
|
||||
return prevTabs.map((tab, index) => ({
|
||||
...tab,
|
||||
content: content || tab.content,
|
||||
active: index === existingTabIndex
|
||||
}));
|
||||
}
|
||||
|
||||
// Добавляем новую вкладку
|
||||
return [
|
||||
...prevTabs.map(tab => ({ ...tab, active: false })),
|
||||
{
|
||||
id,
|
||||
title,
|
||||
content: content || <div>Loading...</div>,
|
||||
active: true
|
||||
}
|
||||
];
|
||||
});
|
||||
setActiveTab(id);
|
||||
}, []);
|
||||
|
||||
const handleCloseTab = useCallback((id) => {
|
||||
setTabs((prevTabs) => prevTabs.filter((tab) => tab.id !== id));
|
||||
if (activeTab === id) {
|
||||
setActiveTab(tabs.length > 1 ? tabs[tabs.length - 2].id : initialTab);
|
||||
}
|
||||
}, [activeTab, tabs, initialTab]);
|
||||
setTabs((prevTabs) => {
|
||||
const newTabs = prevTabs.filter((tab) => tab.id !== id);
|
||||
|
||||
return { tabs, activeTab, handleOpenTab, handleCloseTab, setActiveTab };
|
||||
if (activeTab === id) {
|
||||
setActiveTab(newTabs.length > 0
|
||||
? newTabs[newTabs.length - 1].id
|
||||
: initialTab
|
||||
);
|
||||
}
|
||||
|
||||
return newTabs;
|
||||
});
|
||||
}, [activeTab, initialTab]);
|
||||
|
||||
const updateTabContent = useCallback((id, content) => {
|
||||
setTabs(prevTabs =>
|
||||
prevTabs.map(tab =>
|
||||
tab.id === id ? { ...tab, content } : tab
|
||||
)
|
||||
);
|
||||
}, []);
|
||||
|
||||
return {
|
||||
tabs,
|
||||
activeTab,
|
||||
handleOpenTab,
|
||||
handleCloseTab,
|
||||
setActiveTab,
|
||||
updateTabContent
|
||||
};
|
||||
};
|
||||
|
||||
export default useTabs;
|
||||
Loading…
Reference in New Issue