/** * Monitoring shell — exact port of Angular monitoring-shell.component. * Tab container with 4 tabs: Pulse, Profiler, PubSub, Analysis. * Starts/stops profiler & pubsub services on mount/unmount. */ import { useState, useEffect } from 'react' import { Outlet, useLocation, useNavigate } from 'react-router-dom' import { Tabs, Tab, Box } from '@mui/material' import { useI18nStore } from '../../stores/i18n.store' import { useRedisStateStore } from '../../stores/redis-state.store' import { useCommonStore } from '../../stores/common.store' import { initMonitoringData, startProfiler, stopProfiler, startPubSub, stopPubSub, destroyMonitoringData, } from '../../stores/monitoring-data.store' const routes = ['/monitoring', '/monitoring/profiler', '/monitoring/pubsub', '/monitoring/analysis'] function syncTab(pathname: string): number { if (pathname.startsWith('/monitoring/profiler')) return 1 if (pathname.startsWith('/monitoring/pubsub')) return 2 if (pathname.startsWith('/monitoring/analysis')) return 3 return 0 } export default function MonitoringShell() { const strings = useI18nStore(s => s.strings) const currentLang = useI18nStore(s => s.currentLang) const connection = useRedisStateStore(s => s.connection) const { generalHandleError } = useCommonStore() const location = useLocation() const navigate = useNavigate() const [selectedTab, setSelectedTab] = useState(() => syncTab(location.pathname)) useEffect(() => { setSelectedTab(syncTab(location.pathname)) }, [location.pathname]) // Init services when connection is available useEffect(() => { if (!connection) return initMonitoringData(() => useI18nStore.getState().currentLang) const initServices = async () => { try { await startProfiler() } catch (e) { generalHandleError(e) } try { await startPubSub() } catch (e) { generalHandleError(e) } } initServices() return () => { stopProfiler() stopPubSub() destroyMonitoringData() } }, [connection]) // eslint-disable-line react-hooks/exhaustive-deps const onTabChange = (_: any, index: number) => { if (index >= 0 && index < routes.length) { setSelectedTab(index) navigate(routes[index]) } } return ( ) }