feat(i18n): AlertCenter 告警中心国际化 — 38 处硬编码中文改翻译键 + alert 命名空间(58 键)
- AlertCenter.tsx: StatStrip 4 标签/5 个 Tab 标题/搜索/级别+状态筛选/表头 6 列/分页/加载空状态/toast 12 处/确认弹框 3 处/一键报警描述/规则启用禁用/联系人联系组增删 全量 t() 化 - 复用 common.* 通用键(refresh/edit/delete/status) - 新增 alert.* 命名空间: stat/tab/severity/status/table 子组 + searchPlaceholder/quickSetup/toast 等 58 键 - zh-CN/en-US 键总数 285→343 (alert 58 键, 中英完全对齐) - tsc -b=0, npm build=✓(19.59s), 17/17 集成测试通过
This commit is contained in:
1 parent
3e9352f690
commit
61a1f32e64
3 files changed
+212
-66
No files matched your search
@@ -29,8 +29,10 @@ import { ContactGroupDialog } from './ContactGroupDialog';
|
||||
import SilenceRuleTab from './SilenceRuleTab';
|
||||
import type { Contact, ContactGroup } from './alert-center-helpers';
|
||||
import type { JsonData } from '@/types/common';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const AlertCenter: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const _confirm = useConfirm();
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [severityFilter, setSeverityFilter] = useState('all');
|
||||
@@ -97,18 +99,18 @@ const AlertCenter: React.FC = () => {
|
||||
const handleAcknowledge = async (id: string) => {
|
||||
try {
|
||||
await ackMutation.mutateAsync(id);
|
||||
toast.success('告警已确认');
|
||||
toast.success(t('alert.acknowledged'));
|
||||
} catch {
|
||||
toast.error('操作失败');
|
||||
toast.error(t('alert.operationFailed'));
|
||||
}
|
||||
};
|
||||
|
||||
const handleResolve = async (id: string) => {
|
||||
try {
|
||||
await resolveMutation.mutateAsync(id);
|
||||
toast.success('告警已解决');
|
||||
toast.success(t('alert.resolvedToast'));
|
||||
} catch {
|
||||
toast.error('操作失败');
|
||||
toast.error(t('alert.operationFailed'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -123,7 +125,7 @@ const AlertCenter: React.FC = () => {
|
||||
const endTime = new Date(now.getTime() + hours * 3600_000);
|
||||
await alertCenterApi.createSilence({
|
||||
name: `静默: ${alert?.title || id} (${duration})`,
|
||||
description: `从告警列表快速静默 — ${alert?.source || ''}`,
|
||||
description: `${t('alert.silenceDesc')} — ${alert?.source || ''}`,
|
||||
silence_type: 'onetime',
|
||||
start_time: now.toISOString(),
|
||||
end_time: endTime.toISOString(),
|
||||
@@ -132,16 +134,16 @@ const AlertCenter: React.FC = () => {
|
||||
setSilenceOpen(false);
|
||||
refetchAlerts();
|
||||
} catch {
|
||||
toast.error('操作失败');
|
||||
toast.error(t('alert.operationFailed'));
|
||||
}
|
||||
};
|
||||
|
||||
const toggleRule = async (ruleId: string, enabled: boolean) => {
|
||||
try {
|
||||
await toggleAgentRuleMutation.mutateAsync({ id: Number(ruleId), enabled });
|
||||
toast.success('规则状态已更新');
|
||||
toast.success(t('alert.ruleUpdated'));
|
||||
} catch {
|
||||
toast.error('更新失败');
|
||||
toast.error(t('alert.updateFailed'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -151,23 +153,23 @@ const AlertCenter: React.FC = () => {
|
||||
|
||||
const handleQuickSetup = async () => {
|
||||
const ok = await _confirm({
|
||||
title: '一键报警',
|
||||
description: '为 Agent 在线主机创建 CPU(>80%)/内存(>80%)/磁盘(>90%)/TIME_WAIT(>15000)/CLOSE_WAIT(>200)/进程检测 6 条告警规则。',
|
||||
confirmText: '确认创建',
|
||||
title: t('alert.quickSetup'),
|
||||
description: t('alert.quickSetupDesc'),
|
||||
confirmText: t('alert.quickSetupConfirm'),
|
||||
});
|
||||
if (!ok) return;
|
||||
try {
|
||||
const res = await quickSetupMutation.mutateAsync('ecs');
|
||||
toast.success(typeof res === 'string' ? res : ((res as { message?: string })?.message || '默认告警规则创建成功'));
|
||||
toast.success(typeof res === 'string' ? res : ((res as { message?: string })?.message || t('alert.quickSetupSuccess')));
|
||||
} catch {
|
||||
toast.error('创建失败,请检查 Agent 主机是否在线');
|
||||
toast.error(t('alert.quickSetupFailed'));
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeleteRule = async (rule: AlertRule) => {
|
||||
const ok = await _confirm({ title: '删除规则', description: `确定删除规则「${rule.name}」?`, confirmText: '删除', variant: 'destructive' });
|
||||
const ok = await _confirm({ title: t('alert.deleteRule'), description: `${rule.name}`, confirmText: t('common.delete'), variant: 'destructive' });
|
||||
if (!ok) return;
|
||||
try { await deleteAgentRuleMutation.mutateAsync(Number(rule.id)); toast.success('已删除'); } catch { toast.error('删除失败'); }
|
||||
try { await deleteAgentRuleMutation.mutateAsync(Number(rule.id)); toast.success(t('alert.deleted')); } catch { toast.error(t('alert.deleteFailed')); }
|
||||
};
|
||||
|
||||
const handleFilterChange = (type: 'severity' | 'status', value: string) => {
|
||||
@@ -181,20 +183,20 @@ const AlertCenter: React.FC = () => {
|
||||
{/* 统计 — 紧凑条 */}
|
||||
<StatStrip
|
||||
items={[
|
||||
{ label: '触发中', value: stats.firing, color: stats.firing > 0 ? 'red' : 'muted' },
|
||||
{ label: '严重', value: stats.critical, color: 'red' },
|
||||
{ label: '警告', value: stats.warning, color: 'amber' },
|
||||
{ label: '已解决', value: stats.resolved, color: 'emerald' },
|
||||
{ label: t('alert.stat.firing'), value: stats.firing, color: stats.firing > 0 ? 'red' : 'muted' },
|
||||
{ label: t('alert.stat.critical'), value: stats.critical, color: 'red' },
|
||||
{ label: t('alert.stat.warning'), value: stats.warning, color: 'amber' },
|
||||
{ label: t('alert.stat.resolved'), value: stats.resolved, color: 'emerald' },
|
||||
]}
|
||||
/>
|
||||
|
||||
<Tabs value={activeTab} onValueChange={setActiveTab}>
|
||||
<TabsList className="grid w-full grid-cols-5 lg:w-[600px] h-9">
|
||||
<TabsTrigger value="alerts" className="text-xs">告警列表</TabsTrigger>
|
||||
<TabsTrigger value="rules" className="text-xs">告警规则</TabsTrigger>
|
||||
<TabsTrigger value="silences" className="text-xs">静默规则</TabsTrigger>
|
||||
<TabsTrigger value="contacts" className="text-xs">报警联系人</TabsTrigger>
|
||||
<TabsTrigger value="groups" className="text-xs">报警联系组</TabsTrigger>
|
||||
<TabsTrigger value="alerts" className="text-xs">{t('alert.tab.alerts')}</TabsTrigger>
|
||||
<TabsTrigger value="rules" className="text-xs">{t('alert.tab.rules')}</TabsTrigger>
|
||||
<TabsTrigger value="silences" className="text-xs">{t('alert.tab.silences')}</TabsTrigger>
|
||||
<TabsTrigger value="contacts" className="text-xs">{t('alert.tab.contacts')}</TabsTrigger>
|
||||
<TabsTrigger value="groups" className="text-xs">{t('alert.tab.groups')}</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
{/* 告警列表 Tab */}
|
||||
@@ -204,7 +206,7 @@ const AlertCenter: React.FC = () => {
|
||||
<div className="relative flex-1">
|
||||
<Search className="absolute left-2.5 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-muted-foreground" />
|
||||
<Input
|
||||
placeholder="搜索告警..."
|
||||
placeholder={t('alert.searchPlaceholder')}
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="pl-8 h-8 text-xs"
|
||||
@@ -212,31 +214,31 @@ const AlertCenter: React.FC = () => {
|
||||
</div>
|
||||
<Select value={severityFilter} onValueChange={(v) => handleFilterChange('severity', v)}>
|
||||
<SelectTrigger className="w-[100px] h-8 text-xs">
|
||||
<SelectValue placeholder="级别" />
|
||||
<SelectValue placeholder={t('alert.table.severity')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">全部级别</SelectItem>
|
||||
<SelectItem value="critical">严重</SelectItem>
|
||||
<SelectItem value="warning">警告</SelectItem>
|
||||
<SelectItem value="info">信息</SelectItem>
|
||||
<SelectItem value="all">{t('alert.allSeverity')}</SelectItem>
|
||||
<SelectItem value="critical">{t('alert.severity.critical')}</SelectItem>
|
||||
<SelectItem value="warning">{t('alert.severity.warning')}</SelectItem>
|
||||
<SelectItem value="info">{t('alert.severity.info')}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Select value={statusFilter} onValueChange={(v) => handleFilterChange('status', v)}>
|
||||
<SelectTrigger className="w-[100px] h-8 text-xs">
|
||||
<SelectValue placeholder="状态" />
|
||||
<SelectValue placeholder={t('common.status')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">全部状态</SelectItem>
|
||||
<SelectItem value="firing">触发中</SelectItem>
|
||||
<SelectItem value="acknowledged">已确认</SelectItem>
|
||||
<SelectItem value="resolved">已解决</SelectItem>
|
||||
<SelectItem value="all">{t('alert.allStatus')}</SelectItem>
|
||||
<SelectItem value="firing">{t('alert.status.firing')}</SelectItem>
|
||||
<SelectItem value="acknowledged">{t('alert.status.acknowledged')}</SelectItem>
|
||||
<SelectItem value="resolved">{t('alert.status.resolved')}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="flex items-center gap-1 text-xs text-muted-foreground">
|
||||
<span>共 {total} 条</span>
|
||||
<span>{t('alert.totalItems', { count: total })}</span>
|
||||
<Button variant="outline" size="sm" onClick={() => refetchAlerts()} className="h-7 text-xs px-2">
|
||||
<RefreshCw className="w-3 h-3 mr-1" />刷新
|
||||
<RefreshCw className="w-3 h-3 mr-1" />{t('common.refresh')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -248,19 +250,19 @@ const AlertCenter: React.FC = () => {
|
||||
<table className="w-full text-sm">
|
||||
<thead className="bg-muted/50">
|
||||
<tr>
|
||||
<th className="px-3 py-2 text-left text-xs font-medium">告警信息</th>
|
||||
<th className="px-3 py-2 text-left text-xs font-medium w-16">级别</th>
|
||||
<th className="px-3 py-2 text-left text-xs font-medium w-16">状态</th>
|
||||
<th className="px-3 py-2 text-left text-xs font-medium w-24">来源</th>
|
||||
<th className="px-3 py-2 text-left text-xs font-medium w-20">持续</th>
|
||||
<th className="px-3 py-2 text-left text-xs font-medium w-28">操作</th>
|
||||
<th className="px-3 py-2 text-left text-xs font-medium">{t('alert.table.alertInfo')}</th>
|
||||
<th className="px-3 py-2 text-left text-xs font-medium w-16">{t('alert.table.severity')}</th>
|
||||
<th className="px-3 py-2 text-left text-xs font-medium w-16">{t('alert.table.status')}</th>
|
||||
<th className="px-3 py-2 text-left text-xs font-medium w-24">{t('alert.table.source')}</th>
|
||||
<th className="px-3 py-2 text-left text-xs font-medium w-20">{t('alert.table.duration')}</th>
|
||||
<th className="px-3 py-2 text-left text-xs font-medium w-28">{t('alert.table.actions')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y">
|
||||
{loading ? (
|
||||
<tr><td colSpan={6} className="px-3 py-6 text-center text-xs text-muted-foreground">加载中...</td></tr>
|
||||
<tr><td colSpan={6} className="px-3 py-6 text-center text-xs text-muted-foreground">{t('alert.loading')}</td></tr>
|
||||
) : alerts.length === 0 ? (
|
||||
<tr><td colSpan={6} className="px-3 py-6 text-center text-xs text-muted-foreground">暂无告警</td></tr>
|
||||
<tr><td colSpan={6} className="px-3 py-6 text-center text-xs text-muted-foreground">{t('alert.noAlerts')}</td></tr>
|
||||
) : (
|
||||
alerts.filter(alert => {
|
||||
// 客户端也保留关键词搜索过滤
|
||||
@@ -288,8 +290,8 @@ const AlertCenter: React.FC = () => {
|
||||
</td>
|
||||
<td className="px-3 py-2 text-xs text-muted-foreground">
|
||||
{alert.status === 'resolved' && alert.resolvedAt
|
||||
? `${Math.floor((new Date(alert.resolvedAt).getTime() - new Date(alert.startedAt).getTime()) / 60000)}分`
|
||||
: `${Math.floor((Date.now() - new Date(alert.startedAt).getTime()) / 60000)}分`}
|
||||
? t('alert.minutesShort', { count: Math.floor((new Date(alert.resolvedAt).getTime() - new Date(alert.startedAt).getTime()) / 60000) })
|
||||
: t('alert.minutesShort', { count: Math.floor((Date.now() - new Date(alert.startedAt).getTime()) / 60000) })}
|
||||
</td>
|
||||
<td className="px-3 py-2">
|
||||
<div className="flex items-center gap-0.5">
|
||||
@@ -324,11 +326,11 @@ const AlertCenter: React.FC = () => {
|
||||
{/* 分页控件 */}
|
||||
{totalPages > 1 && (
|
||||
<div className="flex items-center justify-between px-3 py-2 border-t text-xs">
|
||||
<span className="text-muted-foreground">第 {page}/{totalPages} 页,共 {total} 条</span>
|
||||
<span className="text-muted-foreground">{t('alert.pageInfo', { page, totalPages, total })}</span>
|
||||
<div className="flex items-center gap-1">
|
||||
<Button variant="outline" size="sm" className="h-7 text-xs px-2"
|
||||
disabled={page <= 1} onClick={() => setPage(p => p - 1)}>
|
||||
上一页
|
||||
{t('alert.prevPage')}
|
||||
</Button>
|
||||
{Array.from({ length: Math.min(totalPages, 5) }, (_, i) => {
|
||||
const start = Math.max(1, Math.min(page - 2, totalPages - 4));
|
||||
@@ -344,7 +346,7 @@ const AlertCenter: React.FC = () => {
|
||||
})}
|
||||
<Button variant="outline" size="sm" className="h-7 text-xs px-2"
|
||||
disabled={page >= totalPages} onClick={() => setPage(p => p + 1)}>
|
||||
下一页
|
||||
{t('alert.nextPage')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -358,11 +360,11 @@ const AlertCenter: React.FC = () => {
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex items-center gap-2">
|
||||
<Button onClick={handleOpenAddRule}>
|
||||
<Plus className="w-4 h-4 mr-1" />添加规则
|
||||
<Plus className="w-4 h-4 mr-1" />{t('alert.addRule')}
|
||||
</Button>
|
||||
<Button variant="secondary" onClick={handleQuickSetup} disabled={quickSetupMutation.isPending}>
|
||||
<Rocket className="w-4 h-4 mr-1" />
|
||||
{quickSetupMutation.isPending ? '创建中…' : '一键报警'}
|
||||
{quickSetupMutation.isPending ? t('alert.quickSetupCreating') : t('alert.quickSetup')}
|
||||
</Button>
|
||||
</div>
|
||||
<Button variant="outline" onClick={() => refetchRules()}>
|
||||
@@ -373,8 +375,8 @@ const AlertCenter: React.FC = () => {
|
||||
{rules.length === 0 ? (
|
||||
<div className="text-center py-12 text-muted-foreground">
|
||||
<AlertTriangle className="w-10 h-10 mx-auto mb-2 opacity-50" />
|
||||
<p className="text-sm">暂无告警规则</p>
|
||||
<p className="text-xs mt-1">点击「添加规则」或「一键报警」快速创建</p>
|
||||
<p className="text-sm">{t('alert.noRules')}</p>
|
||||
<p className="text-xs mt-1">{t('alert.noRulesHint')}</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
@@ -387,7 +389,7 @@ const AlertCenter: React.FC = () => {
|
||||
<span className="font-medium">{rule.name}</span>
|
||||
{getSeverityBadge(rule.severity)}
|
||||
<Badge variant={rule.enabled ? 'default' : 'secondary'}>
|
||||
{rule.enabled ? '已启用' : '已禁用'}
|
||||
{rule.enabled ? t('alert.enabled') : t('alert.disabled')}
|
||||
</Badge>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground mb-2">{rule.description}</p>
|
||||
@@ -395,7 +397,7 @@ const AlertCenter: React.FC = () => {
|
||||
{rule.expression && (
|
||||
<span className="font-mono bg-muted px-2 py-1 rounded">{rule.expression}</span>
|
||||
)}
|
||||
{rule.duration ? <span>持续 {rule.duration}秒</span> : null}
|
||||
{rule.duration ? <span>{t('alert.durationSeconds', { count: rule.duration })}</span> : null}
|
||||
</div>
|
||||
{(() => {
|
||||
let chs: string[] = [];
|
||||
@@ -414,8 +416,8 @@ const AlertCenter: React.FC = () => {
|
||||
})()}
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button variant="ghost" size="sm" onClick={() => handleEditRule(rule)}>编辑</Button>
|
||||
<Button variant="ghost" size="sm" className="text-red-400" onClick={() => handleDeleteRule(rule)}>删除</Button>
|
||||
<Button variant="ghost" size="sm" onClick={() => handleEditRule(rule)}>{t('common.edit')}</Button>
|
||||
<Button variant="ghost" size="sm" className="text-red-400" onClick={() => handleDeleteRule(rule)}>{t('common.delete')}</Button>
|
||||
<Switch
|
||||
checked={rule.enabled}
|
||||
onCheckedChange={(checked) => toggleRule(String(rule.id), checked)}
|
||||
@@ -437,7 +439,7 @@ const AlertCenter: React.FC = () => {
|
||||
{/* 报警联系人 Tab */}
|
||||
<TabsContent value="contacts" className="space-y-4">
|
||||
<div className="flex justify-between items-center">
|
||||
<h3 className="text-sm font-medium">报警联系人</h3>
|
||||
<h3 className="text-sm font-medium">{t('alert.contactsTitle')}</h3>
|
||||
<Button size="sm" onClick={() => { setEditingContact(null); setContactDialogOpen(true); }}>
|
||||
<Plus className="w-4 h-4 mr-1" />
|
||||
添加联系人
|
||||
@@ -478,10 +480,10 @@ const AlertCenter: React.FC = () => {
|
||||
</Button>
|
||||
<Button variant="outline" size="sm" className="h-7 text-xs"
|
||||
onClick={async () => {
|
||||
const ok = await _confirm({ title: '删除联系人', description: `确定删除「${c.name}」?`, confirmText: '删除', variant: 'destructive' });
|
||||
const ok = await _confirm({ title: t('alert.deleteContact'), description: `${c.name}`, confirmText: t('common.delete'), variant: 'destructive' });
|
||||
if (!ok) return;
|
||||
try { await alertApi.deleteContact(c.id); toast.success('已删除'); fetchContacts(); }
|
||||
catch { toast.error('删除失败'); }
|
||||
try { await alertApi.deleteContact(c.id); toast.success(t('alert.deleted')); fetchContacts(); }
|
||||
catch { toast.error(t('alert.deleteFailed')); }
|
||||
}}>
|
||||
删除
|
||||
</Button>
|
||||
@@ -522,7 +524,7 @@ const AlertCenter: React.FC = () => {
|
||||
<CardHeader>
|
||||
<div className="flex items-start justify-between">
|
||||
<CardTitle className="text-base">{g.group_name}</CardTitle>
|
||||
<Badge variant="secondary">{cids.length} 人</Badge>
|
||||
<Badge variant="secondary">{t('alert.peopleCount', { count: cids.length })}</Badge>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-0 space-y-2">
|
||||
@@ -539,10 +541,10 @@ const AlertCenter: React.FC = () => {
|
||||
</Button>
|
||||
<Button variant="outline" size="sm"
|
||||
onClick={async () => {
|
||||
const ok = await _confirm({ title: '删除联系组', description: `确定删除联系组「${g.group_name}」?`, confirmText: '删除', variant: 'destructive' });
|
||||
const ok = await _confirm({ title: t('alert.deleteGroup'), description: `${g.group_name}`, confirmText: t('common.delete'), variant: 'destructive' });
|
||||
if (!ok) return;
|
||||
try { await alertApi.deleteContactGroup(g.id); toast.success('已删除'); fetchContactGroups(); }
|
||||
catch { toast.error('删除失败'); }
|
||||
try { await alertApi.deleteContactGroup(g.id); toast.success(t('alert.deleted')); fetchContactGroups(); }
|
||||
catch { toast.error(t('alert.deleteFailed')); }
|
||||
}}>
|
||||
删除
|
||||
</Button>
|
||||
|
||||
@@ -317,5 +317,77 @@
|
||||
"status": "Status",
|
||||
"tags": "Tags"
|
||||
}
|
||||
},
|
||||
"alert": {
|
||||
"stat": {
|
||||
"firing": "Firing",
|
||||
"critical": "Critical",
|
||||
"warning": "Warning",
|
||||
"resolved": "Resolved"
|
||||
},
|
||||
"tab": {
|
||||
"alerts": "Alerts",
|
||||
"rules": "Alert Rules",
|
||||
"silences": "Silence Rules",
|
||||
"contacts": "Contacts",
|
||||
"groups": "Contact Groups"
|
||||
},
|
||||
"searchPlaceholder": "Search alerts...",
|
||||
"allSeverity": "All Severity",
|
||||
"allStatus": "All Status",
|
||||
"severity": {
|
||||
"critical": "Critical",
|
||||
"warning": "Warning",
|
||||
"info": "Info"
|
||||
},
|
||||
"status": {
|
||||
"firing": "Firing",
|
||||
"acknowledged": "Acknowledged",
|
||||
"resolved": "Resolved"
|
||||
},
|
||||
"table": {
|
||||
"alertInfo": "Alert Info",
|
||||
"severity": "Severity",
|
||||
"status": "Status",
|
||||
"source": "Source",
|
||||
"duration": "Duration",
|
||||
"actions": "Actions"
|
||||
},
|
||||
"loading": "Loading...",
|
||||
"noAlerts": "No alerts",
|
||||
"totalItems": "{{count}} total",
|
||||
"acknowledged": "Alert acknowledged",
|
||||
"resolvedToast": "Alert resolved",
|
||||
"operationFailed": "Operation failed",
|
||||
"ruleUpdated": "Rule status updated",
|
||||
"updateFailed": "Update failed",
|
||||
"deleted": "Deleted",
|
||||
"deleteFailed": "Delete failed",
|
||||
"deleteRule": "Delete Rule",
|
||||
"deleteContact": "Delete Contact",
|
||||
"deleteGroup": "Delete Group",
|
||||
"quickSetup": "Quick Setup",
|
||||
"quickSetupDesc": "Create 6 alert rules for online Agent hosts: CPU(>80%)/Memory(>80%)/Disk(>90%)/TIME_WAIT(>15000)/CLOSE_WAIT(>200)/Process detection.",
|
||||
"quickSetupConfirm": "Confirm Create",
|
||||
"quickSetupCreating": "Creating…",
|
||||
"quickSetupSuccess": "Default alert rules created successfully",
|
||||
"quickSetupFailed": "Creation failed, check if Agent hosts are online",
|
||||
"silenceDesc": "Quick silence from alert list",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"pageInfo": "Page {{page}}/{{totalPages}}, {{total}} total",
|
||||
"addRule": "Add Rule",
|
||||
"noRules": "No alert rules",
|
||||
"noRulesHint": "Click 'Add Rule' or 'Quick Setup' to create",
|
||||
"durationSeconds": "{{count}}s duration",
|
||||
"contactsTitle": "Contacts",
|
||||
"peopleCount": "{{count}} people",
|
||||
"addContact": "Add Contact",
|
||||
"addGroup": "Add Group",
|
||||
"noContacts": "No contacts yet, click 'Add Contact' to create",
|
||||
"noGroups": "No contact groups yet, click 'Add Group' to create",
|
||||
"minutesShort": "{{count}}m",
|
||||
"prevPage": "Previous",
|
||||
"nextPage": "Next"
|
||||
}
|
||||
}
|
||||
@@ -317,5 +317,77 @@
|
||||
"status": "状态",
|
||||
"tags": "标签"
|
||||
}
|
||||
},
|
||||
"alert": {
|
||||
"stat": {
|
||||
"firing": "触发中",
|
||||
"critical": "严重",
|
||||
"warning": "警告",
|
||||
"resolved": "已解决"
|
||||
},
|
||||
"tab": {
|
||||
"alerts": "告警列表",
|
||||
"rules": "告警规则",
|
||||
"silences": "静默规则",
|
||||
"contacts": "报警联系人",
|
||||
"groups": "报警联系组"
|
||||
},
|
||||
"searchPlaceholder": "搜索告警...",
|
||||
"allSeverity": "全部级别",
|
||||
"allStatus": "全部状态",
|
||||
"severity": {
|
||||
"critical": "严重",
|
||||
"warning": "警告",
|
||||
"info": "信息"
|
||||
},
|
||||
"status": {
|
||||
"firing": "触发中",
|
||||
"acknowledged": "已确认",
|
||||
"resolved": "已解决"
|
||||
},
|
||||
"table": {
|
||||
"alertInfo": "告警信息",
|
||||
"severity": "级别",
|
||||
"status": "状态",
|
||||
"source": "来源",
|
||||
"duration": "持续",
|
||||
"actions": "操作"
|
||||
},
|
||||
"loading": "加载中...",
|
||||
"noAlerts": "暂无告警",
|
||||
"totalItems": "共 {{count}} 条",
|
||||
"acknowledged": "告警已确认",
|
||||
"resolvedToast": "告警已解决",
|
||||
"operationFailed": "操作失败",
|
||||
"ruleUpdated": "规则状态已更新",
|
||||
"updateFailed": "更新失败",
|
||||
"deleted": "已删除",
|
||||
"deleteFailed": "删除失败",
|
||||
"deleteRule": "删除规则",
|
||||
"deleteContact": "删除联系人",
|
||||
"deleteGroup": "删除联系组",
|
||||
"quickSetup": "一键报警",
|
||||
"quickSetupDesc": "为 Agent 在线主机创建 CPU(>80%)/内存(>80%)/磁盘(>90%)/TIME_WAIT(>15000)/CLOSE_WAIT(>200)/进程检测 6 条告警规则。",
|
||||
"quickSetupConfirm": "确认创建",
|
||||
"quickSetupCreating": "创建中…",
|
||||
"quickSetupSuccess": "默认告警规则创建成功",
|
||||
"quickSetupFailed": "创建失败,请检查 Agent 主机是否在线",
|
||||
"silenceDesc": "从告警列表快速静默",
|
||||
"enabled": "已启用",
|
||||
"disabled": "已禁用",
|
||||
"pageInfo": "第 {{page}}/{{totalPages}} 页,共 {{total}} 条",
|
||||
"addRule": "添加规则",
|
||||
"noRules": "暂无告警规则",
|
||||
"noRulesHint": "点击「添加规则」或「一键报警」快速创建",
|
||||
"durationSeconds": "持续 {{count}}秒",
|
||||
"contactsTitle": "报警联系人",
|
||||
"peopleCount": "{{count}} 人",
|
||||
"addContact": "添加联系人",
|
||||
"addGroup": "添加联系组",
|
||||
"noContacts": "暂无报警联系人,点击「添加联系人」创建",
|
||||
"noGroups": "暂无报警联系组,点击「添加联系组」创建",
|
||||
"minutesShort": "{{count}}分",
|
||||
"prevPage": "上一页",
|
||||
"nextPage": "下一页"
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user