import { ActivityIndicator, Button, Icon, ResourceList, ResourceRow, SettingsCard, StatusBadge } from "@nodedc/ui-react"; import type { Status } from "./api"; import type { ViewId } from "./nodeModel"; import { useAccess } from "./useAccess"; import { tailscaleLabel, useTailscaleStatus } from "./useTailscaleStatus"; export function BoardSummary({ value, failure, openView }: { value: Status; failure: (error: unknown) => void; openView: (id: ViewId) => void }) { const { access, loading } = useAccess(value.host.collected_at, failure); const tailnet = useTailscaleStatus(failure, value.host.collected_at); const networks = value.host.networks.filter(item => item.name !== "lo" && item.name !== "lo0" && item.up && item.addresses.length > 0); const networkReadable = value.host.networks_readable && value.host.networks.every(item => item.addresses_readable); return
  • } title="Сеть" description="Включённые интерфейсы с назначенными адресами" status={{networkReadable ? networks.length : "Нет сведений"}} actions={} />
  • } title="USB-устройства" description="Обнаружены операционной системой" status={{value.host.usb_readable ? value.host.usb.length : "Нет сведений"}} actions={} />
  • : } title="Tailscale" description="Частная сеть" status={{tailscaleLabel(tailnet.value, tailnet.checked)}} actions={} />
  • : } title="SSH" description="Удалённое обслуживание БК" metadata={access ? `Разрешено ключей: ${access.keys.length}` : undefined} status={{loading ? "Проверяем" : !access ? "Нет сведений" : access.ssh_ready ? "Отвечает локально" : "Не отвечает"}} actions={} />
  • ; }