import { useCallback, useState } from "react"; import { LayoutGrid } from "lucide-react"; import { useTranslation } from "react-i18next"; import { registerWidget } from "./WidgetRegistry"; import type { HostGridConfig, WidgetComponentProps, } from "@/types/homepage-types"; import { GRID_SIZE } from "@/types/homepage-types"; import { getSSHHosts } from "@/api/ssh-host-management-api"; import type { SSHHostWithStatus } from "@/main-axios"; import { WidgetTitle } from "./WidgetTitle"; import { usePageVisibleInterval } from "@/hooks/use-page-visible-interval"; function getAccentColor(): string { return ( getComputedStyle(document.documentElement) .getPropertyValue("--accent-brand") .trim() || "#f59145" ); } function StatusDot({ status }: { status: string }) { const color = status === "online" ? getAccentColor() : status === "offline" ? "#ef4444" : "#6b7280"; return ( ); } function HostGridWidget({ widget, config, }: WidgetComponentProps) { const { t } = useTranslation(); const { hostIds, showIp, columns } = config; const [hosts, setHosts] = useState([]); const [loading, setLoading] = useState(true); // getSSHHosts already attaches cached server status — no second /status call. const fetchData = useCallback(async () => { try { const allHosts = await getSSHHosts(); const filtered = hostIds.length > 0 ? allHosts.filter((h) => hostIds.includes(h.id)) : allHosts; setHosts(filtered); } catch { /* ignore */ } finally { setLoading(false); } }, [hostIds.join(",")]); // Align with global status cadence; pause when the tab is hidden. usePageVisibleInterval(() => { void fetchData(); }, 30_000); if (loading) { return ( {t("homepage.loading")} ); } if (hosts.length === 0) { return ( {t("homepage.noHosts")} ); } const gridCols = columns === 2 ? "grid-cols-2" : columns === 3 ? "grid-cols-3" : "grid-cols-4"; return ( } /> {hosts.map((host) => ( {host.name} {showIp && ( {host.ip} )} ))} ); } registerWidget({ id: "host_grid", name: "Host Grid", description: "Live status overview grid for all your SSH hosts", category: "monitoring", icon: , defaultConfig: { hostIds: [], showIp: false, columns: 3 }, defaultSize: { w: GRID_SIZE * 12, h: GRID_SIZE * 8 }, minSize: { w: GRID_SIZE * 4, h: GRID_SIZE * 3 }, component: HostGridWidget, }); export { HostGridWidget };