feat(node): consolidate board system views and plan fleet pairing

This commit is contained in:
DCCONSTRUCTIONS
2026-09-05 18:35:57 +03:00
parent d696842f5d
commit 79911eb316
13 changed files with 278 additions and 73 deletions
+9 -6
View File
@@ -1,9 +1,11 @@
import { useEffect, useState } from "react";
import { Button, SettingsCard, StatusBadge, TextField } from "@nodedc/ui-react";
import { Button, SettingsCard, TextField } from "@nodedc/ui-react";
import { request, type Status } from "./api";
import type { ViewId } from "./nodeModel";
import { BoardSummary } from "./BoardSummary";
const memory = (value: number | null) => value === null ? "Недоступно" : `${(value / 1048576).toFixed(1)} ГиБ`;
export function NodeOverview({ value, refresh, failure }: { value: Status; refresh: () => Promise<void>; failure: (error: unknown) => void }) {
export function NodeOverview({ value, refresh, failure, openView }: { value: Status; refresh: () => Promise<void>; failure: (error: unknown) => void; openView: (id: ViewId) => void }) {
const [name, setName] = useState(value.name);
const [saving, setSaving] = useState(false);
useEffect(() => setName(value.name), [value.name]);
@@ -12,16 +14,17 @@ export function NodeOverview({ value, refresh, failure }: { value: Status; refre
try { await request("/api/name", "PUT", { name }); await refresh(); } catch (error) { failure(error); } finally { setSaving(false); }
}
return <div className="node-content">
<SettingsCard title={value.name} eyebrow="БОРТОВОЙ КОМПЬЮТЕР" description={value.host.hostname} actions={<StatusBadge tone="success">Node работает</StatusBadge>}>
<SettingsCard title={value.name} eyebrow="БОРТОВОЙ КОМПЬЮТЕР" description={value.host.hostname}>
<dl className="node-facts"><div><dt>Операционная система</dt><dd>{value.host.os}</dd></div><div><dt>Архитектура</dt><dd>{value.host.architecture}</dd></div><div><dt>Логических процессоров</dt><dd>{value.host.cpus}</dd></div><div><dt>Оперативная память</dt><dd>{memory(value.host.memory_kib)}</dd></div><div><dt>Доступно памяти</dt><dd>{memory(value.host.available_kib)}</dd></div><div><dt>Mission Core Node</dt><dd>{value.version}</dd></div></dl>
</SettingsCard>
<SettingsCard title="Название компьютера" description="Название, по которому вы узнаёте этот борт в Node.">
<SettingsCard title="Название БК" description="Название бортового компьютера.">
<form onSubmit={save} className="node-form" aria-busy={saving}>
<TextField label="Название ноды" value={name} maxLength={64} disabled={saving} onChange={event => setName(event.target.value)} autoComplete="off" />
<TextField label="Название БК" value={name} maxLength={64} disabled={saving} onChange={event => setName(event.target.value)} autoComplete="off" />
<Button type="submit" disabled={saving || !name.trim() || name.trim() === value.name}>{saving ? "Сохраняем…" : "Сохранить"}</Button>
</form>
<dl className="node-facts"><div><dt>ID ноды</dt><dd>{value.node_id}</dd></div></dl>
<dl className="node-facts"><div><dt>ID БК</dt><dd>{value.node_id}</dd></div></dl>
</SettingsCard>
<BoardSummary value={value} failure={failure} openView={openView} />
<p className="node-note">Сведения обновлены {new Date(value.host.collected_at).toLocaleString("ru-RU")}.</p>
</div>;
}