fix: card sections with fixed min-height for perfect alignment
All checks were successful
Deploy Admin Frontend / build-and-deploy (push) Successful in 8s

This commit is contained in:
WangDL 2026-05-22 14:19:47 +08:00
parent 73fa2b57ff
commit 942a3b23d2

View File

@ -25,54 +25,60 @@ function ServerCard({ server }: { server: ServerInfo }) {
return (
<Card title={<Space><CloudServerOutlined />{server.name}<Tag color="blue">{server.role}</Tag></Space>} style={{ height: '100%' }}>
<div style={{ marginBottom: 12, minHeight: 28 }}>
<Space wrap size={[4, 4]}>
<CopyTag text={server.network.publicIp} icon="🌐 " color="cyan" />
<CopyTag text={server.network.privateIp} icon="🔒 " />
{server.network.domains.map(d => (
<CopyTag key={d} text={d} icon={<GlobalOutlined style={{ marginRight: 2 }} />} color="blue" />
))}
</Space>
{/* IP & domains — fixed height */}
<div style={{ marginBottom: 12, minHeight: 30 }}>
<Space wrap size={[4, 4]}>
<CopyTag text={server.network.publicIp} icon="🌐 " color="cyan" />
<CopyTag text={server.network.privateIp} icon="🔒 " />
{server.network.domains.map(d => (
<CopyTag key={d} text={d} icon={<GlobalOutlined style={{ marginRight: 2 }} />} color="blue" />
))}
</Space>
</div>
<Row gutter={[16, 12]}>
<Col xs={12} sm={6}>
<Text type="secondary" style={{ fontSize: 11 }}>CPU · {server.cpu.cores}</Text>
<Progress percent={server.cpu.usagePercent} strokeColor={cpuColor} size="small" format={p => `${p}%`} />
</Col>
<Col xs={12} sm={6}>
<Text type="secondary" style={{ fontSize: 11 }}></Text>
<Progress percent={server.memory.percent} strokeColor={memColor} size="small" format={p => `${p}%`} />
<Text style={{ fontSize: 10 }} type="secondary">{server.memory.used}/{server.memory.total}</Text>
</Col>
<Col xs={24} sm={12}>
<Text type="secondary" style={{ fontSize: 11, marginBottom: 4, display: 'block' }}></Text>
{(server.disks || []).map(d => (
<div key={d.mount} style={{ marginBottom: 4 }}>
<div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
<Text style={{ fontSize: 10, minWidth: 36 }} type="secondary">{d.mount}</Text>
<div style={{ flex: 1 }}><Progress percent={d.percent} size="small" strokeColor={d.percent > 80 ? '#ff4d4f' : '#1677ff'} style={{ margin: 0 }} /></div>
<Text style={{ fontSize: 10, whiteSpace: 'nowrap', minWidth: 70, textAlign: 'right' }}>{d.used} / {d.total}</Text>
{/* Metrics — fixed height grid */}
<div style={{ marginBottom: 10, minHeight: 72 }}>
<Row gutter={[16, 8]}>
<Col span={8}>
<Text type="secondary" style={{ fontSize: 11 }}>CPU · {server.cpu.cores}</Text>
<Progress percent={server.cpu.usagePercent} strokeColor={cpuColor} size="small" format={p => `${p}%`} />
</Col>
<Col span={8}>
<Text type="secondary" style={{ fontSize: 11 }}> {server.memory.percent}%</Text>
<Progress percent={server.memory.percent} strokeColor={memColor} size="small" />
<Text style={{ fontSize: 10 }} type="secondary">{server.memory.used}/{server.memory.total}</Text>
</Col>
<Col span={8}>
<Text type="secondary" style={{ fontSize: 11, marginBottom: 2 }}></Text>
{(server.disks || []).map(d => (
<div key={d.mount} style={{ marginBottom: 2, display: 'flex', alignItems: 'center', gap: 4 }}>
<Text style={{ fontSize: 10, width: 32 }} type="secondary">{d.mount}</Text>
<Progress percent={d.percent} size="small" strokeColor={d.percent > 80 ? '#ff4d4f' : '#1677ff'} style={{ flex: 1, margin: 0 }} />
<Text style={{ fontSize: 10, whiteSpace: 'nowrap' }}>{d.used}</Text>
</div>
</div>
))}
</Col>
<Col span={24}>
<Text style={{ fontSize: 14, fontWeight: 500 }}>🕐 {server.uptime}</Text>
</Col>
</Row>
))}
</Col>
</Row>
</div>
{/* Uptime */}
<div style={{ marginBottom: 12, minHeight: 22 }}>
<Text style={{ fontSize: 14, fontWeight: 500 }}>🕐 {server.uptime}</Text>
</div>
{/* Process table — fixed height */}
<Table
dataSource={server.processes || []}
rowKey="pid" size="small" pagination={false}
style={{ marginTop: 12 }}
scroll={{ y: 240 }}
style={{ marginTop: 0 }}
columns={[
{ title: '进程', dataIndex: 'name', width: 120, ellipsis: true, render: (name: string, r: ProcessInfo) => (
{ title: '进程', dataIndex: 'name', width: 110, ellipsis: true, render: (name: string, r: ProcessInfo) => (
<Tooltip title={r.desc ? `${r.desc}\n${r.command}` : r.command}><span>{name}</span></Tooltip>
)},
{ title: '说明', dataIndex: 'desc', width: 100, ellipsis: true, render: (d: string) => <Text type="secondary" style={{ fontSize: 12 }}>{d || '-'}</Text> },
{ title: 'CPU', dataIndex: 'cpu', width: 55 },
{ title: 'MEM', dataIndex: 'mem', width: 55 },
{ title: '说明', dataIndex: 'desc', width: 90, ellipsis: true, render: (d: string) => <Text type="secondary" style={{ fontSize: 12 }}>{d || '-'}</Text> },
{ title: 'CPU', dataIndex: 'cpu', width: 50 },
{ title: 'MEM', dataIndex: 'mem', width: 50 },
]}
locale={{ emptyText: '暂无' }}
/>