feat(web): localize and redesign operations console

This commit is contained in:
chick
2026-07-18 22:22:41 +08:00
parent d575ab4d9d
commit abfd07f8a3
34 changed files with 1536 additions and 1058 deletions
+25 -29
View File
@@ -3,6 +3,7 @@ import { useEffect, useRef, useState } from 'react';
import type { InstanceContext, InstanceModule } from '../app-shell.js';
import { canonicalHttpOrigin } from '../fleet/fleet-page.js';
import { displayStatus } from '../ui/locale.js';
export type CapabilityState = 'supported' | 'degraded' | 'unsupported' | 'unknown';
@@ -27,23 +28,23 @@ export interface InstanceDetailProps {
}
export const INSTANCE_MODULE_LABELS: Readonly<Record<InstanceModule, string>> = {
overview: 'Overview',
cellular: 'Cellular',
'device-network': 'Device Network',
messages: 'Messages',
calls: 'Calls',
overview: '概览',
cellular: '蜂窝网络',
'device-network': '设备网络',
messages: '消息',
calls: '通话',
esim: 'eSIM',
notifications: 'Notifications',
automation: 'Automation',
notifications: '通知',
automation: '自动化',
ota: 'OTA',
};
const MODULES = Object.keys(INSTANCE_MODULE_LABELS) as readonly InstanceModule[];
const DEFAULT_EXPLANATIONS: Readonly<Record<Exclude<CapabilityState, 'supported'>, string>> = {
degraded: 'This module is available with limited functionality.',
unsupported: 'This instance does not support this module.',
unknown: 'Capability state is unknown.',
degraded: '此模块可用,但功能受限。',
unsupported: '此实例不支持该模块。',
unknown: '能力状态未知。',
};
function capabilityFor(map: InstanceCapabilityMap, module: InstanceModule): InstanceCapability {
@@ -99,7 +100,7 @@ export function InstanceDetail({
(error: unknown) => {
void error;
if (!controller.signal.aborted && requestRef.current === request) {
setLoadError('Capability discovery failed.');
setLoadError('能力探测失败。');
setLoading(false);
}
},
@@ -111,7 +112,7 @@ export function InstanceDetail({
return (
<section>
<h1>{INSTANCE_MODULE_LABELS[module]}</h1>
<p>Instance context is unavailable for this route.</p>
<p></p>
</section>
);
}
@@ -122,29 +123,29 @@ export function InstanceDetail({
return (
<section className="instance-detail">
<aside className="instance-context" aria-label="Current instance">
<aside className="instance-context" aria-label="当前实例">
<strong>{instance.name}</strong>
<code>{instance.id}</code>
<dl>
<div>
<dt>Status</dt>
<dd>{instance.status}</dd>
<dt></dt>
<dd>{displayStatus(instance.status)}</dd>
</div>
<div>
<dt>Authentication</dt>
<dd>{instance.authentication}</dd>
<dt></dt>
<dd>{displayStatus(instance.authentication)}</dd>
</div>
<div>
<dt>Freshness</dt>
<dd>{instance.freshness}</dd>
<dt></dt>
<dd>{displayStatus(instance.freshness)}</dd>
</div>
</dl>
{origin ? (
<a href={origin} target="_blank" rel="noopener noreferrer">
Open original site
</a>
) : null}
<nav aria-label="Instance modules">
<nav aria-label="实例模块">
<ul>
{MODULES.map((item) => {
const capability = capabilityFor(map, item);
@@ -172,19 +173,14 @@ export function InstanceDetail({
</aside>
<div className="instance-module-detail">
<h1>{INSTANCE_MODULE_LABELS[module]}</h1>
{loading ? <p role="status">Loading capabilities</p> : null}
{loadError ? <p role="alert">Capabilities unavailable: {loadError}</p> : null}
{loading ? <p role="status"></p> : null}
{loadError ? <p role="alert">{loadError}</p> : null}
{!loading && canRender(activeCapability) ? (
<>
{activeCapability.state === 'degraded' ? (
<p data-capability-state="degraded">{explanation(activeCapability)}</p>
) : null}
{moduleContent ?? (
<p>
Inspect {INSTANCE_MODULE_LABELS[module].toLowerCase()} data and available
operations.
</p>
)}
{moduleContent ?? <p>{INSTANCE_MODULE_LABELS[module]}</p>}
</>
) : null}
{!loading && !canRender(activeCapability) ? (