"use client"; import { HardDrive } from "@/components/icons/platform-icons"; import { formatBytesCompact } from "@/lib/client/format"; import type { DiskMediaType, DiskMonitorEntry } from "@/lib/shared/contracts/disks"; import { PANEL_INSET } from "@/lib/ui/surface-tokens"; import { cn } from "@/lib/utils"; const MEDIA_LABEL: Record = { ssd: "SSD", hdd: "HDD", nvme: "NVMe", removable: "Removable", unknown: "Disk", }; export function formatMegabytesPerSecond(value: number) { return `${value < 10 ? value.toFixed(2) : value.toFixed(1)} MB/s`; } function formatPowerOn(hours: number) { return hours >= 48 ? `${Math.round(hours / 24).toLocaleString()} days` : `${hours} h`; } function Badge({ children, className }: { children: React.ReactNode; className?: string }) { return ( {children} ); } function Row({ label, value }: { label: string; value: string }) { return (
{label} {value}
); } // VM disks report a PCI id such as 0x1af4 instead of a vendor or model name. function readableName(value: string | null) { return value && !/^0x[0-9a-f]+$/i.test(value) ? value : null; } export function DiskMonitorCard({ disk, inContainer = false }: { disk: DiskMonitorEntry; inContainer?: boolean }) { const health = disk.health === "healthy" ? { label: "Healthy", className: "bg-status-green/12 text-status-green" } : disk.health === "degraded" ? { label: "Failing", className: "bg-status-red/12 text-status-red" } : null; return (
{disk.device} {MEDIA_LABEL[disk.mediaType]} {/* NVMe disks report nvme as their bus too; one badge is enough. */} {disk.transport && disk.transport.toUpperCase() !== MEDIA_LABEL[disk.mediaType].toUpperCase() ? ( {disk.transport.toUpperCase()} ) : null}
{[readableName(disk.vendor), readableName(disk.model)].filter(Boolean).join(" ") || "Unknown model"}
{health ? {health.label} : null}
{[ { label: "Read", value: disk.readBytesPerSec, color: "text-chart-4" }, { label: "Write", value: disk.writeBytesPerSec, color: "text-status-amber" }, ].map(({ label, value, color }) => (
{label} {value === null ? "--" : formatMegabytesPerSecond(value / 1_000_000)}
))}
{disk.powerOnHours !== null ? : null} {disk.partitions.map((partition) => ( ))}
); }