Files
NODEDC_MISSION_CORE/apps/node-agent/ui/src/BoardSummary.tsx
T

21 lines
2.9 KiB
TypeScript

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 <SettingsCard title="Сводка БК" description="Подключения и доступ к бортовому компьютеру.">
<ResourceList aria-label="Сводка подключений БК">
<li><ResourceRow icon={<Icon name="network" />} title="Сеть" description="Включённые интерфейсы с назначенными адресами" status={<StatusBadge tone={networkReadable && networks.length ? "neutral" : "warning"}>{networkReadable ? networks.length : "Нет сведений"}</StatusBadge>} actions={<Button onClick={() => openView("network")}>Открыть сеть</Button>} /></li>
<li><ResourceRow icon={<Icon name="camera" />} title="USB-устройства" description="Обнаружены операционной системой" status={<StatusBadge>{value.host.usb_readable ? value.host.usb.length : "Нет сведений"}</StatusBadge>} actions={<Button onClick={() => openView("usb")}>Открыть USB</Button>} /></li>
<li><ResourceRow icon={tailnet.checked ? <Icon name="globe" /> : <ActivityIndicator size="compact" />} title="Tailscale" description="Частная сеть" status={<StatusBadge tone={tailnet.value?.online ? "success" : "neutral"}>{tailscaleLabel(tailnet.value, tailnet.checked)}</StatusBadge>} actions={<Button onClick={() => openView("tailscale")}>Открыть Tailscale</Button>} /></li>
<li><ResourceRow icon={loading ? <ActivityIndicator size="compact" /> : <Icon name="key" />} title="SSH" description="Удалённое обслуживание БК" metadata={access ? `Разрешено ключей: ${access.keys.length}` : undefined} status={<StatusBadge tone={access?.ssh_ready ? "success" : "neutral"}>{loading ? "Проверяем" : !access ? "Нет сведений" : access.ssh_ready ? "Отвечает локально" : "Не отвечает"}</StatusBadge>} actions={<Button onClick={() => openView("ssh")}>Настроить SSH</Button>} /></li>
</ResourceList>
</SettingsCard>;
}