import { memo, useState } from "react" import { Trans } from "@lingui/react/macro" import { compareSemVer, parseSemVer } from "@/lib/utils" import type { GPUData } from "@/types" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import InfoBar from "./system/info-bar" import { useSystemData } from "./system/use-system-data" import { CpuChart, ContainerCpuChart } from "./system/charts/cpu-charts" import { MemoryChart, ContainerMemoryChart, SwapChart } from "./system/charts/memory-charts" import { DiskCharts } from "./system/charts/disk-charts" import { BandwidthChart, ContainerNetworkChart } from "./system/charts/network-charts" import { TemperatureChart, BatteryChart } from "./system/charts/sensor-charts" import { GpuPowerChart, GpuDetailCharts } from "./system/charts/gpu-charts" import { ExtraFsCharts } from "./system/charts/extra-fs-charts" import { LazyContainersTable, LazySmartTable, LazySystemdTable } from "./system/lazy-tables" import { LoadAverageChart } from "./system/charts/load-average-chart" import { ContainerIcon, CpuIcon, HardDriveIcon, TerminalSquareIcon } from "lucide-react" import { GpuIcon } from "../ui/icons" import SystemdTable from "../systemd-table/systemd-table" import ContainersTable from "../containers-table/containers-table" const SEMVER_0_14_0 = parseSemVer("0.14.0") const SEMVER_0_15_0 = parseSemVer("0.15.0") export default memo(function SystemDetail({ id }: { id: string }) { const { system, systemStats, containerData, chartData, containerChartConfigs, details, grid, setGrid, displayMode, setDisplayMode, activeTab, setActiveTab, mountedTabs, tabsRef, maxValues, isLongerChart, showMax, dataEmpty, isPodman, lastGpus, hasGpuData, hasGpuEnginesData, hasGpuPowerData, } = useSystemData(id) // extra margin to add to bottom of page, specifically for temperature chart, // where the tooltip can go past the bottom of the page if lots of sensors const [pageBottomExtraMargin, setPageBottomExtraMargin] = useState(0) if (!system.id) { return null } const hasContainers = containerData.length > 0 const maybeHasSmartData = compareSemVer(chartData.agentVersion, SEMVER_0_15_0) >= 0 const hasContainersTable = hasContainers && compareSemVer(chartData.agentVersion, SEMVER_0_14_0) >= 0 const hasSystemd = system.info.sv const hasGpu = hasGpuData || hasGpuPowerData // keep tabsRef in sync for keyboard navigation const tabs = ["core", "disk"] if (hasGpu) tabs.push("gpu") if (hasContainers) tabs.push("containers") if (hasSystemd) tabs.push("services") tabsRef.current = tabs // shared chart props const coreProps = { chartData, grid, dataEmpty, showMax, isLongerChart, maxValues } function defaultLayout() { return ( <> {/* main charts */}
{hasContainers && ( )} {hasContainers && ( )} {hasContainers && ( )} {hasGpuPowerData && }
{hasGpuData && lastGpus && ( } hasGpuEnginesData={hasGpuEnginesData} /> )} {maybeHasSmartData && } {hasContainersTable && } {hasSystemd && } ) } function tabbedLayout() { return ( Core Disk {hasGpu && ( GPU )} {hasContainers && ( Containers )} {hasSystemd && ( Services )}
{pageBottomExtraMargin > 0 &&
}
{mountedTabs.has("disk") && ( <>
{maybeHasSmartData && } )}
{hasGpu && (
{hasGpuPowerData && }
{hasGpuData && lastGpus && ( } hasGpuEnginesData={hasGpuEnginesData} /> )}
)} {hasContainers && ( {mountedTabs.has("containers") && ( <>
{hasContainersTable && } )}
)} {hasSystemd && ( {mountedTabs.has("services") && } )}
) } return (
{/* system info */} {displayMode === "tabs" ? tabbedLayout() : defaultLayout()}
) })