feat(web): redesign fleet cards and instance workspace

This commit is contained in:
chick
2026-07-19 18:54:26 +08:00
parent f2803896a8
commit 49ee4e6570
9 changed files with 458 additions and 74 deletions
+37 -13
View File
@@ -40,6 +40,16 @@ export const INSTANCE_MODULE_LABELS: Readonly<Record<InstanceModule, string>> =
};
const PRIMARY_MODULES = ['overview', 'messages'] as const satisfies readonly InstanceModule[];
const PRIMARY_LABELS: Readonly<Record<(typeof PRIMARY_MODULES)[number], string>> = {
overview: '仪表盘',
messages: '短信',
};
const AUTH_LABELS = { authenticated: '已认证', 'auth-required': '需要认证' } as const;
const FRESHNESS_LABELS = {
fresh: '数据最新',
stale: '数据可能过期',
expired: '数据已过期',
} as const;
const DEFAULT_EXPLANATIONS: Readonly<Record<Exclude<CapabilityState, 'supported'>, string>> = {
degraded: '此模块可用,但功能受限。',
@@ -126,23 +136,37 @@ export function InstanceDetail({
return (
<section className="instance-detail">
<aside className="instance-context" aria-label="当前实例">
<strong>{instance.name}</strong>
<code>{instance.id}</code>
<header className="instance-context" aria-label="当前实例">
<a className="instance-breadcrumb" href="/fleet">
</a>
<div className="instance-identity">
<div>
<h1>{instance.name}</h1>
<code>{instance.id}</code>
</div>
<div className="instance-context-badges">
{instance.status !== 'unknown' ? <span>{displayStatus(instance.status)}</span> : null}
{instance.authentication !== 'unknown' ? (
<span>{AUTH_LABELS[instance.authentication]}</span>
) : null}
{instance.freshness !== 'unknown' ? (
<span>{FRESHNESS_LABELS[instance.freshness]}</span>
) : null}
</div>
</div>
{instance.status !== 'unknown' ? (
<dl>
<dl className="visually-hidden">
<div>
<dt></dt>
<dd>{displayStatus(instance.status)}</dd>
</div>
</dl>
) : null}
{origin ? (
<a href={origin} target="_blank" rel="noopener noreferrer">
</a>
) : null}
<a href={`/settings/instances/${encodeURIComponent(instanceId)}`}></a>
<div className="instance-header-actions">
{origin ? <span title={origin}></span> : null}
<a href={`/settings/instances/${encodeURIComponent(instanceId)}`}></a>
</div>
<nav aria-label="实例模块">
<ul>
{PRIMARY_MODULES.map((item) => {
@@ -152,16 +176,16 @@ export function InstanceDetail({
href={`/instances/${encodeURIComponent(instanceId)}/${item}`}
aria-current={module === item ? 'page' : undefined}
>
{INSTANCE_MODULE_LABELS[item]}
{PRIMARY_LABELS[item]}
</a>
</li>
);
})}
</ul>
</nav>
</aside>
</header>
<div className="instance-module-detail">
<h1>{INSTANCE_MODULE_LABELS[module]}</h1>
<h2>{INSTANCE_MODULE_LABELS[module]}</h2>
{loading ? <p role="status"></p> : null}
{loadError ? <p role="alert">{loadError}</p> : null}
{!loading && canOpen(module, activeCapability) ? (