feat(web): 首頁基礎架構加入拓撲圖 Toggle (主機/拓撲切換,串接真實 API)
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
This commit is contained in:
@@ -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行 */}
|
||||
|
||||
Reference in New Issue
Block a user