feat(web): 首頁基礎架構加入拓撲圖 Toggle (主機/拓撲切換,串接真實 API)
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled

This commit is contained in:
OG T
2026-04-09 09:12:31 +08:00
parent d1ede7f989
commit 030f4f7c32

View File

@@ -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 } }) {
/>
</div>
{/* 基礎架構 Grid */}
{/* 基礎架構 — Toggle: 拓撲圖 / 主機網格 */}
<div style={{
background: '#fff',
border: '0.5px solid #e0ddd4',
@@ -984,18 +986,49 @@ export default function Home({ params }: { params: { locale: string } }) {
}}>
<div style={{ width: 6, height: 6, borderRadius: '50%', background: '#d97757', flexShrink: 0 }} />
{tDashboard('infrastructure')}
{/* Toggle 切換 */}
<div style={{ marginLeft: 'auto', display: 'flex', background: '#f5f4ed', borderRadius: 5, padding: 2 }}>
<button
onClick={() => setInfraView('host')}
style={{
padding: '3px 10px', borderRadius: 3, fontSize: 10, fontWeight: infraView === 'host' ? 600 : 400,
cursor: 'pointer', border: 'none',
background: infraView === 'host' ? '#fff' : 'transparent',
color: infraView === 'host' ? '#d97757' : '#87867f',
boxShadow: infraView === 'host' ? '0 1px 2px rgba(0,0,0,0.06)' : 'none',
}}
></button>
<button
onClick={() => setInfraView('topo')}
style={{
padding: '3px 10px', borderRadius: 3, fontSize: 10, fontWeight: infraView === 'topo' ? 600 : 400,
cursor: 'pointer', border: 'none',
background: infraView === 'topo' ? '#fff' : 'transparent',
color: infraView === 'topo' ? '#d97757' : '#87867f',
boxShadow: infraView === 'topo' ? '0 1px 2px rgba(0,0,0,0.06)' : 'none',
}}
></button>
</div>
</div>
<HostGrid hosts={(() => {
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' && (
<HostGrid hosts={(() => {
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' && (
<div style={{ height: 350 }}>
<ServiceTopology mode="compact" showControls={false} showMiniMap={false} height={350} />
</div>
)}
</div>
{/* 監控工具 — figma-v2 style: 左彩色條 + 可點擊 + meta行 */}