diff --git a/frontend/src/components/dashboard/Dashboard.tsx b/frontend/src/components/dashboard/Dashboard.tsx index fe06506..afd2a8e 100644 --- a/frontend/src/components/dashboard/Dashboard.tsx +++ b/frontend/src/components/dashboard/Dashboard.tsx @@ -1,5 +1,6 @@ import { useCallback, useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; import { Button } from '@/components/ui/button'; import { cn } from '@/lib/utils'; import { Clock, Server, ArrowRight } from 'lucide-react'; @@ -34,6 +35,7 @@ import type { AlertEventRecord, CertExpiryRecord } from '@/types'; * 6. 添加页面标题区域的操作入口 */ export function Dashboard() { + const { t } = useTranslation(); const navigate = useNavigate(); const [initialLoading, setInitialLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); @@ -111,8 +113,8 @@ export function Dashboard() { {/* Page Header */}
-

仪表盘

-

实时监控和运维概览 · 最后更新: {new Date().toLocaleTimeString('zh-CN')}

+

{t('dashboard.title')}

+

{t('dashboard.subtitle')} · {t('dashboard.lastUpdated')}: {new Date().toLocaleTimeString()}

@@ -139,13 +141,13 @@ export function Dashboard() {
0 ? 'red' : 'muted' }, - { label: '严重', value: alertStats?.critical ?? 0, color: 'red' }, - { label: '本月成本', value: `¥${Number(costStats?.month_cost ?? 0).toLocaleString()}`, color: 'amber' }, + { label: t('dashboard.stat.servers'), value: serverStats?.total ?? 0, color: 'blue' }, + { label: t('dashboard.stat.running'), value: serverStats?.running ?? 0, color: 'emerald' }, + { label: t('dashboard.stat.k8sClusters'), value: k8sStats?.total ?? 0, color: 'purple' }, + { label: t('dashboard.stat.healthyClusters'), value: k8sStats?.healthy ?? 0, color: 'cyan' }, + { label: t('dashboard.stat.alerts'), value: alertStats?.firing ?? 0, color: alertStats?.firing > 0 ? 'red' : 'muted' }, + { label: t('dashboard.stat.critical'), value: alertStats?.critical ?? 0, color: 'red' }, + { label: t('dashboard.stat.monthlyCost'), value: `¥${Number(costStats?.month_cost ?? 0).toLocaleString()}`, color: 'amber' }, ]} />
diff --git a/frontend/src/components/dashboard/DashboardCharts.tsx b/frontend/src/components/dashboard/DashboardCharts.tsx index 1fa7db2..bb730d4 100644 --- a/frontend/src/components/dashboard/DashboardCharts.tsx +++ b/frontend/src/components/dashboard/DashboardCharts.tsx @@ -1,3 +1,5 @@ +import { useTranslation } from 'react-i18next'; +import i18n from '@/i18n'; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { @@ -39,16 +41,16 @@ export function computeMonthChange( monthTrend: JsonData[]): { direction: 'up' | 'down' | 'neutral'; } { if (!monthTrend || monthTrend.length < 2) { - return { pct: 0, label: '暂无数据', direction: 'neutral' }; + return { pct: 0, label: i18n.t('dashboard.cost.noData'), direction: 'neutral' }; } const cur = Number(monthTrend[monthTrend.length - 1].cost ?? 0); const prev = Number(monthTrend[monthTrend.length - 2].cost ?? 0); if (prev === 0) { - return { pct: 0, label: cur > 0 ? '新增费用' : '持平', direction: 'neutral' }; + return { pct: 0, label: cur > 0 ? i18n.t('dashboard.cost.newCost') : i18n.t('dashboard.cost.flat'), direction: 'neutral' }; } const pct = ((cur - prev) / prev) * 100; const direction = pct > 0.05 ? 'up' : pct < -0.05 ? 'down' : 'neutral'; - const label = `${pct > 0 ? '+' : ''}${pct.toFixed(1)}% 较上月`; + const label = `${pct > 0 ? '+' : ''}${pct.toFixed(1)}% ${i18n.t('dashboard.cost.vsLastMonth')}`; return { pct, label, direction }; } @@ -108,6 +110,7 @@ function CustomTooltip({ active, payload, label }: JsonData) { } export function CostOverviewCard({ costStats }: { costStats: JsonData }) { + const { t } = useTranslation(); const cloudCosts: JsonData[] = costStats?.cloud_costs ?? []; const monthTrend: JsonData[] = costStats?.month_trend ?? []; @@ -125,8 +128,8 @@ export function CostOverviewCard({ costStats }: { costStats: JsonData }) {
- 云成本概览 - 本月各云平台费用支出 + {t('dashboard.cost.title')} + {t('dashboard.cost.description')}

@@ -146,7 +149,7 @@ export function CostOverviewCard({ costStats }: { costStats: JsonData }) {

-

费用分布

+

{t('dashboard.cost.distribution')}

@@ -170,7 +173,7 @@ export function CostOverviewCard({ costStats }: { costStats: JsonData }) {
-

月度趋势

+

{t('dashboard.cost.monthlyTrend')}

@@ -203,6 +206,7 @@ export function CostOverviewCard({ costStats }: { costStats: JsonData }) { } export function TopResourceUsageCard({ topUsage }: { topUsage: JsonData}) { + const { t } = useTranslation(); const topCpuServers = (topUsage?.cpu ?? []).slice(0, 5); const topMemoryServers = (topUsage?.memory ?? []).slice(0, 5); const topDiskServers = (topUsage?.disk ?? []).slice(0, 5); @@ -257,15 +261,15 @@ export function TopResourceUsageCard({ topUsage }: { topUsage: JsonData}) {
- Top5 资源使用 - CPU、内存、磁盘使用率最高 + {t('dashboard.topUsage.title')} + {t('dashboard.topUsage.description')}
- {renderList(topCpuServers, 'blue', 'bg-[var(--dg-blue)]', , 'CPU')} - {renderList(topMemoryServers, 'emerald', 'bg-[var(--dg-green)]', , '内存')} - {renderList(topDiskServers, 'purple', 'bg-[var(--dg-purple)]', , '磁盘')} + {renderList(topCpuServers, 'blue', 'bg-[var(--dg-blue)]', , t('dashboard.topUsage.cpu'))} + {renderList(topMemoryServers, 'emerald', 'bg-[var(--dg-green)]', , t('dashboard.topUsage.memory'))} + {renderList(topDiskServers, 'purple', 'bg-[var(--dg-purple)]', , t('dashboard.topUsage.disk'))}
@@ -285,27 +289,28 @@ export function ResourceUsageCard({ }) { const realData = buildMetricsFromReal(metrics ?? [], avgDisk); const data = realData.length > 0 ? realData : generateMetricsData(avgCpu, avgMemory, avgDisk, 24); + const { t } = useTranslation(); return (
- 资源使用率趋势 - 过去24小时系统资源使用情况 + {t('dashboard.resourceUsage.title')} + {t('dashboard.resourceUsage.description')}
- CPU + {t('dashboard.resourceUsage.cpu')} - 内存 + {t('dashboard.resourceUsage.memory')} - 磁盘 + {t('dashboard.resourceUsage.disk')}
@@ -332,9 +337,9 @@ export function ResourceUsageCard({ } /> - - - + + +
diff --git a/frontend/src/components/dashboard/DashboardRecent.tsx b/frontend/src/components/dashboard/DashboardRecent.tsx index 46b408b..2d2a871 100644 --- a/frontend/src/components/dashboard/DashboardRecent.tsx +++ b/frontend/src/components/dashboard/DashboardRecent.tsx @@ -1,4 +1,5 @@ import { useNavigate } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; @@ -73,6 +74,7 @@ function StatusDot({ severity }: { severity: string }) { // Severity badge function SeverityBadge({ severity }: { severity: string }) { + const { t } = useTranslation(); return ( - {severity === 'critical' ? '严重' : severity === 'warning' ? '警告' : '提示'} + {severity === 'critical' ? t('common.error') : severity === 'warning' ? t('common.warning') : t('common.info')} ); } export function AlertMessagesCard({ alerts }: { alerts: AlertEventRecord[] }) { + const { t } = useTranslation(); const navigate = useNavigate(); const recentAlerts = alerts.filter((a) => a.status === 'firing').slice(0, 8); @@ -97,8 +100,8 @@ export function AlertMessagesCard({ alerts }: { alerts: AlertEventRecord[] }) {
- 告警消息 - 最近触发的告警事件 + {t('dashboard.alerts.title')} + {t('dashboard.alerts.description')}
@@ -116,8 +119,8 @@ export function AlertMessagesCard({ alerts }: { alerts: AlertEventRecord[] }) { {recentAlerts.length === 0 ? (
-

暂无告警事件

-

所有系统运行正常

+

{t('dashboard.alerts.empty')}

+

{t('dashboard.alerts.emptyHint')}

) : (
@@ -152,6 +155,7 @@ export function AlertMessagesCard({ alerts }: { alerts: AlertEventRecord[] }) { } export function CertificateExpiryCard({ expCerts }: { expCerts: CertExpiryRecord[] }) { + const { t } = useTranslation(); const expiringDomains = (expCerts ?? []) .map((d) => ({ ...d, @@ -167,19 +171,19 @@ export function CertificateExpiryCard({ expCerts }: { expCerts: CertExpiryRecord
- 证书到期提醒 - SSL证书到期时间监控 + {t('dashboard.certificates.title')} + {t('dashboard.certificates.description')}
{criticalCount > 0 && ( - {criticalCount} 即将过期 + {criticalCount} {t('dashboard.certificates.expiringSoon')} )} {warningCount > 0 && ( - {warningCount} 30天内过期 + {warningCount} {t('dashboard.certificates.expiringIn30Days')} )}
@@ -190,7 +194,7 @@ export function CertificateExpiryCard({ expCerts }: { expCerts: CertExpiryRecord {expiringDomains.length === 0 ? (
-

暂无证书数据

+

{t('dashboard.certificates.empty')}

) : (
@@ -217,7 +221,7 @@ export function CertificateExpiryCard({ expCerts }: { expCerts: CertExpiryRecord

{domain.name}

-

到期: {domain.expire_date?.substring(0, 10)}

+

{t('dashboard.certificates.expireDate')}: {domain.expire_date?.substring(0, 10)}

- {domain.daysUntilExpiry < 0 ? '已过期' : `${domain.daysUntilExpiry} 天`} + {domain.daysUntilExpiry < 0 ? t('dashboard.certificates.expired') : `${domain.daysUntilExpiry} ${t('dashboard.certificates.days')}`}
))} @@ -242,6 +246,7 @@ export function CertificateExpiryCard({ expCerts }: { expCerts: CertExpiryRecord } export function ReleaseHistoryCard({ releases }: { releases: DashboardRelease[] }) { + const { t } = useTranslation(); const navigate = useNavigate(); const releaseList = releases?.slice(0, 5) ?? []; @@ -250,8 +255,8 @@ export function ReleaseHistoryCard({ releases }: { releases: DashboardRelease[]
- 发布历史 - 今日应用发布记录 + {t('dashboard.releases.title')} + {t('dashboard.releases.description')}
@@ -268,7 +273,7 @@ export function ReleaseHistoryCard({ releases }: { releases: DashboardRelease[] {releaseList.length === 0 ? (
-

暂无发布记录

+

{t('dashboard.releases.empty')}

) : (
@@ -317,10 +322,10 @@ export function ReleaseHistoryCard({ releases }: { releases: DashboardRelease[] 'dg-badge-yellow border' )} > - {release.status === 'success' ? '成功' : - release.status === 'failed' ? '失败' : - release.status === 'deploying' ? '发布中' : - release.status === 'rolled_back' ? '已回滚' : '构建中'} + {release.status === 'success' ? t('dashboard.releases.success') : + release.status === 'failed' ? t('dashboard.releases.failed') : + release.status === 'deploying' ? t('dashboard.releases.deploying') : + release.status === 'rolled_back' ? t('dashboard.releases.rolledBack') : t('dashboard.releases.building')}
))} @@ -332,6 +337,7 @@ export function ReleaseHistoryCard({ releases }: { releases: DashboardRelease[] } export function ServerStatusCard({ servers }: { servers: DashboardServer[] }) { + const { t } = useTranslation(); const navigate = useNavigate(); const runningServers = servers.filter((s) => s.status === 'running').length; const stoppedServers = servers.filter((s) => s.status === 'stopped').length; @@ -342,8 +348,8 @@ export function ServerStatusCard({ servers }: { servers: DashboardServer[] }) {
- 服务器状态 - 服务器运行状态分布 + {t('dashboard.serversStatus.title')} + {t('dashboard.serversStatus.description')}
@@ -361,15 +367,15 @@ export function ServerStatusCard({ servers }: { servers: DashboardServer[] }) {
{runningServers}
-
运行中
+
{t('dashboard.serversStatus.running')}
{maintenanceServers}
-
维护中
+
{t('dashboard.serversStatus.maintenance')}
{stoppedServers}
-
已停止
+
{t('dashboard.serversStatus.stopped')}
@@ -394,10 +400,10 @@ export function ServerStatusCard({ servers }: { servers: DashboardServer[] }) {

- CPU {Number(server.cpu_usage ?? 0).toFixed(1)}% + {t('dashboard.serversStatus.cpu')} {Number(server.cpu_usage ?? 0).toFixed(1)}%

- 内存 {Number(server.memory_usage ?? 0).toFixed(1)}% + {t('dashboard.serversStatus.memory')} {Number(server.memory_usage ?? 0).toFixed(1)}%

@@ -405,7 +411,7 @@ export function ServerStatusCard({ servers }: { servers: DashboardServer[] }) { {servers.length === 0 && (
-

暂无服务器

+

{t('dashboard.serversStatus.empty')}

)}
@@ -415,6 +421,7 @@ export function ServerStatusCard({ servers }: { servers: DashboardServer[] }) { } export function KubernetesClusterCard({ clusters }: { clusters: DashboardCluster[] }) { + const { t } = useTranslation(); const navigate = useNavigate(); return ( @@ -422,8 +429,8 @@ export function KubernetesClusterCard({ clusters }: { clusters: DashboardCluster
- Kubernetes 集群 - Kubernetes集群健康状态 + {t('dashboard.clusters.title')} + {t('dashboard.clusters.description')}
@@ -440,7 +447,7 @@ export function KubernetesClusterCard({ clusters }: { clusters: DashboardCluster {clusters.length === 0 ? (
-

暂无集群数据

+

{t('dashboard.clusters.empty')}

) : (
@@ -467,15 +474,15 @@ export function KubernetesClusterCard({ clusters }: { clusters: DashboardCluster 'dg-badge-red border' )} > - {cluster.status === 'healthy' ? '健康' : cluster.status === 'warning' ? '警告' : '异常'} + {cluster.status === 'healthy' ? t('dashboard.clusters.healthy') : cluster.status === 'warning' ? t('dashboard.clusters.warning') : t('dashboard.clusters.error')}
{[ - { label: '节点', value: cluster.node_count ?? 0 }, - { label: 'Pod', value: cluster.pod_count ?? 0 }, - { label: 'CPU', value: `${cpuUsage.toFixed(1)}%` }, - { label: '内存', value: `${memoryUsage.toFixed(1)}%` }, + { label: t('dashboard.clusters.nodes'), value: cluster.node_count ?? 0 }, + { label: t('dashboard.clusters.pods'), value: cluster.pod_count ?? 0 }, + { label: t('dashboard.clusters.cpu'), value: `${cpuUsage.toFixed(1)}%` }, + { label: t('dashboard.clusters.memory'), value: `${memoryUsage.toFixed(1)}%` }, ].map((item) => (
{item.value}
diff --git a/frontend/src/locales/en-US.json b/frontend/src/locales/en-US.json index b6c8b86..cb65b52 100644 --- a/frontend/src/locales/en-US.json +++ b/frontend/src/locales/en-US.json @@ -179,20 +179,95 @@ }, "dashboard": { "title": "Dashboard", - "serverStats": "Server Statistics", - "totalServers": "Total Servers", - "onlineServers": "Online Servers", - "k8sClusters": "K8s Clusters", - "runningPods": "Running Pods", - "todayAlerts": "Today's Alerts", - "recentAlerts": "Recent Alerts", - "recentPipelines": "Recent Pipelines", - "recentReleases": "Recent Releases", - "systemOverview": "System Overview", - "resourceUsage": "Resource Usage", - "cpuUsage": "CPU Usage", - "memoryUsage": "Memory Usage", - "diskUsage": "Disk Usage", - "quickActions": "Quick Actions" + "subtitle": "Real-time monitoring & operations overview", + "lastUpdated": "Last updated", + "refresh": "Refresh", + "refreshing": "Refreshing", + "servers": "Servers", + "stat": { + "servers": "Servers", + "running": "Running", + "k8sClusters": "K8s Clusters", + "healthyClusters": "Healthy", + "alerts": "Alerts", + "critical": "Critical", + "monthlyCost": "Monthly Cost" + }, + "alerts": { + "title": "Alert Messages", + "description": "Recently triggered alert events", + "viewAll": "View All", + "empty": "No alert events", + "emptyHint": "All systems running normally" + }, + "certificates": { + "title": "Certificate Expiry", + "description": "SSL certificate expiration monitoring", + "expiringSoon": "expiring soon", + "expiringIn30Days": "within 30 days", + "empty": "No certificate data", + "expireDate": "Expires", + "expired": "Expired", + "days": "days" + }, + "releases": { + "title": "Release History", + "description": "Today's application release records", + "viewAll": "View All", + "empty": "No release records", + "success": "Success", + "failed": "Failed", + "deploying": "Deploying", + "rolledBack": "Rolled Back", + "building": "Building" + }, + "serversStatus": { + "title": "Server Status", + "description": "Server running status distribution", + "viewAll": "View All", + "running": "Running", + "maintenance": "Maintenance", + "stopped": "Stopped", + "cpu": "CPU", + "memory": "Memory", + "empty": "No servers" + }, + "clusters": { + "title": "Kubernetes Clusters", + "description": "Kubernetes cluster health status", + "viewAll": "View All", + "empty": "No cluster data", + "healthy": "Healthy", + "warning": "Warning", + "error": "Error", + "nodes": "Nodes", + "pods": "Pods", + "cpu": "CPU", + "memory": "Memory" + }, + "cost": { + "title": "Cloud Cost Overview", + "description": "Monthly cloud platform expenses", + "distribution": "Cost Distribution", + "monthlyTrend": "Monthly Trend", + "noData": "No data", + "newCost": "New cost", + "flat": "Flat", + "vsLastMonth": "vs last month" + }, + "topUsage": { + "title": "Top 5 Resource Usage", + "description": "Highest CPU, memory, and disk usage", + "cpu": "CPU", + "memory": "Memory", + "disk": "Disk" + }, + "resourceUsage": { + "title": "Resource Usage Trend", + "description": "System resource usage over the last 24 hours", + "cpu": "CPU", + "memory": "Memory", + "disk": "Disk" + } } } diff --git a/frontend/src/locales/zh-CN.json b/frontend/src/locales/zh-CN.json index 17a585a..1cad4d2 100644 --- a/frontend/src/locales/zh-CN.json +++ b/frontend/src/locales/zh-CN.json @@ -179,20 +179,95 @@ }, "dashboard": { "title": "仪表盘", - "serverStats": "服务器统计", - "totalServers": "服务器总数", - "onlineServers": "在线服务器", - "k8sClusters": "K8s集群", - "runningPods": "运行中Pod", - "todayAlerts": "今日告警", - "recentAlerts": "最近告警", - "recentPipelines": "最近流水线", - "recentReleases": "最近发布", - "systemOverview": "系统概览", - "resourceUsage": "资源使用率", - "cpuUsage": "CPU使用率", - "memoryUsage": "内存使用率", - "diskUsage": "磁盘使用率", - "quickActions": "快捷操作" + "subtitle": "实时监控和运维概览", + "lastUpdated": "最后更新", + "refresh": "刷新", + "refreshing": "刷新中", + "servers": "服务器", + "stat": { + "servers": "服务器", + "running": "运行中", + "k8sClusters": "K8s 集群", + "healthyClusters": "健康集群", + "alerts": "告警", + "critical": "严重", + "monthlyCost": "本月成本" + }, + "alerts": { + "title": "告警消息", + "description": "最近触发的告警事件", + "viewAll": "查看全部", + "empty": "暂无告警事件", + "emptyHint": "所有系统运行正常" + }, + "certificates": { + "title": "证书到期提醒", + "description": "SSL证书到期时间监控", + "expiringSoon": "即将过期", + "expiringIn30Days": "30天内过期", + "empty": "暂无证书数据", + "expireDate": "到期", + "expired": "已过期", + "days": "天" + }, + "releases": { + "title": "发布历史", + "description": "今日应用发布记录", + "viewAll": "查看全部", + "empty": "暂无发布记录", + "success": "成功", + "failed": "失败", + "deploying": "发布中", + "rolledBack": "已回滚", + "building": "构建中" + }, + "serversStatus": { + "title": "服务器状态", + "description": "服务器运行状态分布", + "viewAll": "查看全部", + "running": "运行中", + "maintenance": "维护中", + "stopped": "已停止", + "cpu": "CPU", + "memory": "内存", + "empty": "暂无服务器" + }, + "clusters": { + "title": "Kubernetes 集群", + "description": "Kubernetes集群健康状态", + "viewAll": "查看全部", + "empty": "暂无集群数据", + "healthy": "健康", + "warning": "警告", + "error": "异常", + "nodes": "节点", + "pods": "Pod", + "cpu": "CPU", + "memory": "内存" + }, + "cost": { + "title": "云成本概览", + "description": "本月各云平台费用支出", + "distribution": "费用分布", + "monthlyTrend": "月度趋势", + "noData": "暂无数据", + "newCost": "新增费用", + "flat": "持平", + "vsLastMonth": "较上月" + }, + "topUsage": { + "title": "Top5 资源使用", + "description": "CPU、内存、磁盘使用率最高", + "cpu": "CPU", + "memory": "内存", + "disk": "磁盘" + }, + "resourceUsage": { + "title": "资源使用率趋势", + "description": "过去24小时系统资源使用情况", + "cpu": "CPU", + "memory": "内存", + "disk": "磁盘" + } } }