🥳 feat(detail): unify uptime status handling & enhance availability card UI

Summary
• Centralized uptime status definition via `uptimeStatusMap`, containing color / label / text for each status.
• Generated `uptimeLegendData`, `getUptimeStatusColor`, `getUptimeStatusText` directly from the map, removing multiple switch-case blocks.

UI Improvements
1. Added statuses 2 (High Latency) & 3 (Maintenance) with dedicated colors.
2. Relocated status legend to a styled footer wrapped in a borderless sub-Card; header now only shows title + refresh button.
3. Footer (and its negative margin) renders only when `uptimeData` is present, preventing empty legend display.
4. Applied rounded, blurred badge style and always-on shadow to legend container for clearer separation.

Maintenance
• Simplified code paths, reduced duplication, and improved readability without breaking existing functionality.
This commit is contained in:
Apple\Apple
2025-06-11 03:12:34 +08:00
parent 4baaf456a7
commit 48817648c3
2 changed files with 50 additions and 47 deletions

View File

@@ -881,7 +881,6 @@
"你好,": "Hello,",
"线路监控": "line monitoring",
"查看全部": "View all",
"高延迟": "high latency",
"异常": "Abnormal",
"的未命名令牌": "unnamed token",
"令牌更新成功!": "Token updated successfully!",
@@ -1644,6 +1643,8 @@
"服务可用性": "Service Status",
"可用率": "Availability",
"有异常": "Abnormal",
"高延迟": "High latency",
"维护中": "Maintenance",
"暂无监控数据": "No monitoring data",
"请联系管理员在系统设置中配置Uptime": "Please contact the administrator to configure Uptime in the system settings."
}

View File

@@ -846,28 +846,27 @@ const Detail = (props) => {
{ color: 'red', label: t('异常'), type: 'error' }
], [t]);
const uptimeLegendData = useMemo(() => [
{ color: 'green', label: t('正常'), status: 1 },
{ color: 'red', label: t('异常'), status: 0 }
], [t]);
const uptimeStatusMap = useMemo(() => ({
1: { color: '#10b981', label: t('正常'), text: t('可用率') }, // UP
0: { color: '#ef4444', label: t('异常'), text: t('有异常') }, // DOWN
2: { color: '#f59e0b', label: t('高延迟'), text: t('高延迟') }, // PENDING
3: { color: '#3b82f6', label: t('维护中'), text: t('维护中') } // MAINTENANCE
}), [t]);
const getUptimeStatusColor = useCallback((status) => {
switch (status) {
case 1:
return '#10b981'; // 绿色 - 正常
default:
return '#ef4444'; // 红色 - 异常
}
}, []);
const uptimeLegendData = useMemo(() =>
Object.entries(uptimeStatusMap).map(([status, info]) => ({
status: Number(status),
color: info.color,
label: info.label
})), [uptimeStatusMap]);
const getUptimeStatusText = useCallback((status) => {
switch (status) {
case 1:
return t('可用率');
default:
return t('有异常');
}
}, [t]);
const getUptimeStatusColor = useCallback((status) =>
uptimeStatusMap[status]?.color || '#8b9aa7',
[uptimeStatusMap]);
const getUptimeStatusText = useCallback((status) =>
uptimeStatusMap[status]?.text || t('未知'),
[uptimeStatusMap, t]);
const apiInfoData = useMemo(() => {
return statusState?.status?.api_info || [];
@@ -1263,38 +1262,41 @@ const Detail = (props) => {
{...CARD_PROPS}
className="shadow-sm !rounded-2xl lg:col-span-1"
title={
<div className="flex flex-col lg:flex-row lg:items-center lg:justify-between gap-2 w-full">
<div className="flex items-center justify-between w-full gap-2">
<div className="flex items-center gap-2">
<Gauge size={16} />
{t('服务可用性')}
</div>
<div className="flex items-center gap-3">
{/* 图例 */}
<div className="flex flex-wrap gap-3 text-xs">
{uptimeLegendData.map((legend, index) => (
<div key={index} className="flex items-center gap-1">
<div
className="w-2 h-2 rounded-full"
style={{
backgroundColor: legend.color === 'green' ? '#10b981' :
legend.color === 'red' ? '#ef4444' : '#8b9aa7'
}}
/>
<span className="text-gray-600">{legend.label}</span>
</div>
))}
</div>
<IconButton
icon={<IconRefresh />}
onClick={loadUptimeData}
loading={uptimeLoading}
size="small"
theme="borderless"
className="text-gray-500 hover:text-blue-500 hover:bg-blue-50 !rounded-full"
/>
</div>
<IconButton
icon={<IconRefresh />}
onClick={loadUptimeData}
loading={uptimeLoading}
size="small"
theme="borderless"
className="text-gray-500 hover:text-blue-500 hover:bg-blue-50 !rounded-full"
/>
</div>
}
footer={uptimeData.length > 0 ? (
<Card
shadows="always"
bordered={false}
className="!rounded-full backdrop-blur"
>
<div className="flex flex-wrap gap-3 text-xs justify-center">
{uptimeLegendData.map((legend, index) => (
<div key={index} className="flex items-center gap-1">
<div
className="w-2 h-2 rounded-full"
style={{ backgroundColor: legend.color }}
/>
<span className="text-gray-600">{legend.label}</span>
</div>
))}
</div>
</Card>
) : null}
footerStyle={uptimeData.length > 0 ? { marginTop: '-100px' } : undefined}
>
<div className="card-content-container">
<Spin spinning={uptimeLoading}>