feat(nodes): 调整节点详情 Tab 并新增边缘部署命令

将数据看板并入概览,运行状态与配置合并为状态与部署;
边缘节点支持自动填充 Server URL 与 Agent Token 的 Docker 部署卡片。
This commit is contained in:
ryan
2026-07-19 15:01:38 +08:00
parent 7366832e12
commit c00ead9aa0
7 changed files with 81 additions and 55 deletions
@@ -14,7 +14,7 @@ import { NodeKpiCard } from './node-detail-primitives';
import { NodeStatusBadge } from './node-status-badge';
import type { StatusTone } from './node-utils';
export type NodeDetailTabId = 'overview' | 'dashboard' | 'manage';
export type NodeDetailTabId = 'overview' | 'manage';
export type NodeDetailTabConfig = {
id: NodeDetailTabId;
@@ -33,18 +33,20 @@ const TAB_CONFIGS: NodeDetailTabConfig[] = [
id: 'overview',
label: '概览',
},
{
id: 'dashboard',
label: '数据看板',
},
{
id: 'manage',
label: '配置与部署',
label: '状态与部署',
},
];
function isValidTab(value: string | null): value is NodeDetailTabId {
return value === 'overview' || value === 'dashboard' || value === 'manage';
function resolveTab(value: string | null): NodeDetailTabId | null {
if (value === 'overview' || value === 'dashboard') {
return 'overview';
}
if (value === 'manage') {
return 'manage';
}
return null;
}
export function NodeDetailShell({
@@ -55,7 +57,6 @@ export function NodeDetailShell({
actions,
kpis,
overview,
dashboard,
manage,
defaultTab = 'overview',
}: {
@@ -66,7 +67,6 @@ export function NodeDetailShell({
actions: ReactNode;
kpis: NodeDetailKpi[];
overview: ReactNode;
dashboard: ReactNode;
manage: ReactNode;
defaultTab?: NodeDetailTabId;
}) {
@@ -76,7 +76,7 @@ export function NodeDetailShell({
const activeTab = useMemo(() => {
const tab = searchParams.get('tab');
return isValidTab(tab) ? tab : defaultTab;
return resolveTab(tab) ?? defaultTab;
}, [defaultTab, searchParams]);
const setActiveTab = useCallback(
@@ -88,6 +88,16 @@ export function NodeDetailShell({
[pathname, router, searchParams],
);
const handleTabChange = useCallback(
(value: string) => {
const tab = resolveTab(value);
if (tab) {
setActiveTab(tab);
}
},
[setActiveTab],
);
return (
<div className='py-6 px-1 space-y-6'>
<section className='overflow-hidden rounded-2xl border bg-gradient-to-br from-card via-card to-muted/30'>
@@ -144,11 +154,7 @@ export function NodeDetailShell({
<Tabs
value={activeTab}
onValueChange={(value) => {
if (isValidTab(value)) {
setActiveTab(value);
}
}}
onValueChange={handleTabChange}
className='w-full gap-0'
>
<div className='space-y-3 pb-1'>
@@ -174,9 +180,6 @@ export function NodeDetailShell({
<TabsContent value='overview' className='mt-6 outline-none'>
{activeTab === 'overview' ? overview : null}
</TabsContent>
<TabsContent value='dashboard' className='mt-6 outline-none'>
{activeTab === 'dashboard' ? dashboard : null}
</TabsContent>
<TabsContent value='manage' className='mt-6 outline-none'>
{activeTab === 'manage' ? manage : null}
</TabsContent>