import { plural } from "@lingui/core/macro" import { useLingui } from "@lingui/react/macro" import { AppleIcon, ChevronRightSquareIcon, ClockArrowUp, CpuIcon, GlobeIcon, LayoutGridIcon, MemoryStickIcon, MonitorIcon, Rows, } from "lucide-react" import { useMemo } from "react" import ChartTimeSelect from "@/components/charts/chart-time-select" import { Button } from "@/components/ui/button" import { Card } from "@/components/ui/card" import { FreeBsdIcon, TuxIcon, WebSocketIcon, WindowsIcon } from "@/components/ui/icons" import { Separator } from "@/components/ui/separator" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" import { ConnectionType, connectionTypeLabels, Os, SystemStatus } from "@/lib/enums" import { cn, formatBytes, getHostDisplayValue, secondsToString, toFixedFloat } from "@/lib/utils" import type { ChartData, SystemDetailsRecord, SystemRecord } from "@/types" export default function InfoBar({ system, chartData, grid, setGrid, details, }: { system: SystemRecord chartData: ChartData grid: boolean setGrid: (grid: boolean) => void details: SystemDetailsRecord | null }) { const { t } = useLingui() // values for system info bar - use details with fallback to system.info const systemInfo = useMemo(() => { if (!system.info) { return [] } // Use details if available, otherwise fall back to system.info const hostname = details?.hostname ?? system.info.h const kernel = details?.kernel ?? system.info.k const cores = details?.cores ?? system.info.c const threads = details?.threads ?? system.info.t ?? 0 const cpuModel = details?.cpu ?? system.info.m const os = details?.os ?? system.info.os ?? Os.Linux const osName = details?.os_name const arch = details?.arch const memory = details?.memory const osInfo = { [Os.Linux]: { Icon: TuxIcon, // show kernel in tooltip if os name is available, otherwise show the kernel value: osName || kernel, label: osName ? kernel : undefined, }, [Os.Darwin]: { Icon: AppleIcon, value: osName || `macOS ${kernel}`, }, [Os.Windows]: { Icon: WindowsIcon, value: osName || kernel, label: osName ? kernel : undefined, }, [Os.FreeBSD]: { Icon: FreeBsdIcon, value: osName || kernel, label: osName ? kernel : undefined, }, } let uptime: string if (system.info.u < 3600) { uptime = secondsToString(system.info.u, "minute") } else if (system.info.u < 360000) { uptime = secondsToString(system.info.u, "hour") } else { uptime = secondsToString(system.info.u, "day") } const info = [ { value: getHostDisplayValue(system), Icon: GlobeIcon }, { value: hostname, Icon: MonitorIcon, label: "Hostname", // hide if hostname is same as host or name hide: hostname === system.host || hostname === system.name, }, { value: uptime, Icon: ClockArrowUp, label: t`Uptime`, hide: !system.info.u }, osInfo[os], { value: cpuModel, Icon: CpuIcon, hide: !cpuModel, label: `${plural(cores, { one: "# core", other: "# cores" })} / ${plural(threads, { one: "# thread", other: "# threads" })}${arch ? ` / ${arch}` : ""}`, }, ] as { value: string | number | undefined label?: string Icon: React.ElementType hide?: boolean }[] if (memory) { const memValue = formatBytes(memory, false, undefined, false) info.push({ value: `${toFixedFloat(memValue.value, memValue.value >= 10 ? 1 : 2)} ${memValue.unit}`, Icon: MemoryStickIcon, hide: !memory, label: t`Memory`, }) } return info }, [system, details, t]) let translatedStatus: string = system.status if (system.status === SystemStatus.Up) { translatedStatus = t({ message: "Up", comment: "Context: System is up" }) } else if (system.status === SystemStatus.Down) { translatedStatus = t({ message: "Down", comment: "Context: System is down" }) } return (

{system.name}

{system.status === SystemStatus.Up && ( )} {translatedStatus}
{system.info.ct && (
{system.info.ct === ConnectionType.WebSocket ? ( ) : ( )} {connectionTypeLabels[system.info.ct as ConnectionType]}
)}
{systemInfo.map(({ value, label, Icon, hide }) => { if (hide || !value) { return null } const content = (
{value}
) return (
{label ? ( {content} {label} ) : ( content )}
) })}
{t`Toggle grid`}
) }