import { useEffect, useRef, useState } from 'react'; import type { InstanceContext } from '../app-shell.js'; export type OverviewFieldValue = string | number | boolean | null; export type OverviewSection = Readonly>; export interface OverviewSnapshot { readonly observedAt?: string; readonly device: OverviewSection; readonly sim: OverviewSection; readonly network: OverviewSection; readonly stats: OverviewSection; readonly cpu: OverviewSection; readonly connectivity: OverviewSection; } export interface OverviewDataSource { /** Implementations are injected by the application owner; this component has no production endpoint. */ load(instanceId: string, signal: AbortSignal): Promise; } export interface OverviewSystemPageProps { readonly instance: InstanceContext; readonly dataSource?: OverviewDataSource; /** Change this value when an external owner has requested a refresh. */ readonly refreshSignal?: unknown; } type ReadState = | { kind: 'idle' } | { kind: 'loading'; snapshot?: OverviewSnapshot } | { kind: 'ready'; snapshot: OverviewSnapshot } | { kind: 'error'; message: string; snapshot?: OverviewSnapshot }; const SECTIONS = [ ['device', '设备'], ['sim', 'SIM'], ['network', '网络'], ['stats', '统计'], ['cpu', 'CPU'], ['connectivity', '连接状态'], ] as const; const FIELD_LABELS: Readonly> = { Model: '型号', Uptime: '运行时间', Slots: '卡槽数', Active: '活跃数', Operator: '运营商', Registration: '注册状态', 'Messages today': '今日消息数', Calls: '通话数', Usage: '使用率', Temperature: '温度', State: '状态', Latency: '延迟', }; const ENUM_LABELS: Readonly> = { connected: '已连接', disconnected: '未连接', connecting: '正在连接', registered: '已注册', unregistered: '未注册', searching: '正在搜索', roaming: '漫游中', online: '在线', offline: '离线', unknown: '未知', }; function displayFieldLabel(key: string): string { return FIELD_LABELS[key] ?? key; } function displayFieldValue(value: OverviewFieldValue): string { if (value == null) return '不可用'; if (typeof value === 'boolean') return value ? '是' : '否'; if (typeof value === 'string') return ENUM_LABELS[value.toLocaleLowerCase()] ?? value; return String(value); } function StructuredSection({ label, values }: { label: string; values: OverviewSection }) { const entries = Object.entries(values); return (

{label}

{entries.length ? (
{entries.map(([key, value]) => (
{displayFieldLabel(key)}
{displayFieldValue(value)}
))}
) : (

未提供{label}数据。

)}
); } export function OverviewSystemPage({ instance, dataSource, refreshSignal, }: OverviewSystemPageProps) { const requestOwner = useRef(0); const [retry, setRetry] = useState(0); const [state, setState] = useState({ kind: 'idle' }); useEffect(() => { const request = ++requestOwner.current; const controller = new AbortController(); if (instance.authentication === 'auth-required') { setState({ kind: 'idle' }); return () => controller.abort(); } if (!dataSource) { setState({ kind: 'idle' }); return () => controller.abort(); } setState((current) => ({ kind: 'loading', ...(current.kind === 'ready' || current.kind === 'error' ? current.snapshot ? { snapshot: current.snapshot } : {} : {}), })); void dataSource.load(instance.id, controller.signal).then( (snapshot) => { if (request === requestOwner.current && !controller.signal.aborted) setState({ kind: 'ready', snapshot }); }, (reason: unknown) => { void reason; if (request === requestOwner.current && !controller.signal.aborted) setState((current) => ({ kind: 'error', message: '无法加载概览数据。', ...(current.kind === 'loading' && current.snapshot ? { snapshot: current.snapshot } : {}), })); }, ); return () => controller.abort(); }, [dataSource, instance.authentication, instance.id, refreshSignal, retry]); if (instance.authentication === 'auth-required') return (
需要先完成认证,才能读取概览数据。
); if (!dataSource) return (
没有可用的安全概览只读数据源。此控制台不会臆造或调用未签订契约的生产端点。
); const retainedSnapshot = state.kind === 'loading' || state.kind === 'error' ? state.snapshot : undefined; if ((state.kind === 'loading' || state.kind === 'idle') && !retainedSnapshot) return (

正在加载概览…

); if (state.kind === 'error' && !state.snapshot) return (

无法加载概览: {state.message}

); const snapshot = state.kind === 'ready' ? state.snapshot : retainedSnapshot; if (!snapshot) return null; return (
{state.kind === 'loading' ?

正在刷新概览…

: null} {state.kind === 'error' ? (

刷新失败,正在显示上次已知的概览数据。

) : null} {instance.freshness !== 'fresh' ? (

概览数据可能已过期;使用这些值前请先核实数据新鲜度。

) : null} {snapshot.observedAt ?

观测时间:{snapshot.observedAt}

: null}
{SECTIONS.map(([key, label]) => ( ))}

系统操作

重启不可用,因为后端尚未实现 R3 重启操作,因此不提供任何操作。

); }