"use client"; import { Box, Card, Group, Stack, useMantineColorScheme } from "@mantine/core"; import { clientApi } from "@homarr/api/client"; import { useRequiredBoard } from "@homarr/boards/context"; import { humanFileSize } from "@homarr/common"; import { useI18n } from "@homarr/translation/client"; import { WidgetEmptyState } from "../common/empty-state"; import type { WidgetComponentProps } from "../definition"; import { NoIntegrationDataError } from "../errors/no-data-integration"; type DisplayMode = WidgetComponentProps<"systemDisks">["options"]["displayMode"]; const getDisplayText = (item: { used: string; available: string; percentage: number }, displayMode: DisplayMode) => { switch (displayMode) { case "percentage": return `${Math.round(item.percentage)}%`; case "absolute": { const availableInBytes = Number(item.available); const availableText = Number.isFinite(availableInBytes) ? humanFileSize(Math.round(availableInBytes)) : item.available; return `${item.used} / ${availableText}`; } case "free": return `${Math.round(100 - item.percentage)}% free`; default: return `${Math.round(item.percentage)}%`; } }; export default function SystemResources({ integrationIds, options }: WidgetComponentProps<"systemDisks">) { const queryInput = { integrationIds }; const { data = [] } = clientApi.widget.healthMonitoring.getSystemHealthStatus.useQuery(queryInput, { staleTime: 5 * 1000, }); const utils = clientApi.useUtils(); const board = useRequiredBoard(); const scheme = useMantineColorScheme(); const t = useI18n(); clientApi.widget.healthMonitoring.subscribeSystemHealthStatus.useSubscription(queryInput, { onData(data) { utils.widget.healthMonitoring.getSystemHealthStatus.setData(queryInput, (oldData) => oldData?.map((item) => (item.integrationId === data.integrationId ? { ...item, ...data } : item)), ); }, }); const lastItem = data.at(-1); if (!lastItem) return ; const { fileSystem, smart } = lastItem.healthInfo; if (fileSystem.length === 0) { throw new NoIntegrationDataError(); } return ( {fileSystem.map((item) => { const smartItem = smart.find((smart) => smart.deviceName === item.deviceName); const healthy = smartItem?.healthy ?? true; // fall back to healthy if no information is available return ( {item.deviceName} {getDisplayText(item, options.displayMode)} {!healthy && {t("widget.systemDisks.status.unhealthy")}} {smartItem?.temperature && options.showTemperatureIfAvailable ? ( {smartItem.temperature}°C ) : null} ); })} ); }
{item.deviceName}
{getDisplayText(item, options.displayMode)} {!healthy && {t("widget.systemDisks.status.unhealthy")}}
{smartItem.temperature}°C