From 030f4f7c32ed061317712b6c16216a5ae80387b2 Mon Sep 17 00:00:00 2001 From: OG T Date: Thu, 9 Apr 2026 09:12:31 +0800 Subject: [PATCH] =?UTF-8?q?feat(web):=20=E9=A6=96=E9=A0=81=E5=9F=BA?= =?UTF-8?q?=E7=A4=8E=E6=9E=B6=E6=A7=8B=E5=8A=A0=E5=85=A5=E6=8B=93=E6=92=B2?= =?UTF-8?q?=E5=9C=96=20Toggle=20(=E4=B8=BB=E6=A9=9F/=E6=8B=93=E6=92=B2?= =?UTF-8?q?=E5=88=87=E6=8F=9B=EF=BC=8C=E4=B8=B2=E6=8E=A5=E7=9C=9F=E5=AF=A6?= =?UTF-8?q?=20API)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/src/app/[locale]/page.tsx | 57 +++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/apps/web/src/app/[locale]/page.tsx b/apps/web/src/app/[locale]/page.tsx index b558a7f4..8cf26c0c 100644 --- a/apps/web/src/app/[locale]/page.tsx +++ b/apps/web/src/app/[locale]/page.tsx @@ -26,6 +26,7 @@ import { HostGrid, type HostInfo, type HostService } from '@/components/infra/ho import { AppLayout } from '@/components/layout' import { PageTabs, type TabConfig } from '@/components/layout/page-tabs' import { LobsterLoading } from '@/components/shared/lobster-loading' +import { ServiceTopology } from '@/components/topology' const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? '' @@ -736,6 +737,7 @@ export default function Home({ params }: { params: { locale: string } }) { // Sprint 5: 從 URL 讀取當前 Tab const [activeTabId, setActiveTabId] = useState('overview') + const [infraView, setInfraView] = useState<'host' | 'topo'>('host') // 每 100ms 檢查 URL query 變化(PageTabs 用 router.push 更新) useEffect(() => { @@ -964,7 +966,7 @@ export default function Home({ params }: { params: { locale: string } }) { /> - {/* 基礎架構 Grid */} + {/* 基礎架構 — Toggle: 拓撲圖 / 主機網格 */}
{tDashboard('infrastructure')} + {/* Toggle 切換 */} +
+ + +
- { - const apiHosts = hosts.map(h => - buildHostInfo(h.ip, h.name, h.metrics?.cpu_percent ?? null, h.metrics?.memory_percent ?? null, h.services) - ) - // K3s #2 (121) 若 API 未回傳,補靜態卡 - const has121 = apiHosts.some(h => h.ip === '192.168.0.121') - if (!has121) { - apiHosts.push(buildHostInfo('192.168.0.121', 'K3s Server #2', null, null, [])) - } - return apiHosts - })()} /> + {/* 主機網格 (預設) */} + {infraView === 'host' && ( + { + const apiHosts = hosts.map(h => + buildHostInfo(h.ip, h.name, h.metrics?.cpu_percent ?? null, h.metrics?.memory_percent ?? null, h.services) + ) + const has121 = apiHosts.some(h => h.ip === '192.168.0.121') + if (!has121) { + apiHosts.push(buildHostInfo('192.168.0.121', 'K3s Server #2', null, null, [])) + } + return apiHosts + })()} /> + )} + {/* 拓撲圖 (React Flow) */} + {infraView === 'topo' && ( +
+ +
+ )}
{/* 監控工具 — figma-v2 style: 左彩色條 + 可點擊 + meta行 */}