import { useState, useEffect } from 'react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Textarea } from '@/components/ui/textarea'; import { Switch } from '@/components/ui/switch'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Loader2 } from 'lucide-react'; import { alertApi, logCenterApi, type LogDataSource } from '@/api'; import { parseChannels, getChannelIcon, getChannelTypeLabel } from './alertShared'; import type { JsonData } from '@/types/common'; import i18n from '@/i18n'; const emptyRuleForm = { name: '', description: '', type: 'metric', source: 'prometheus', expression: '', severity: 'warning', duration: 300, datasource_id: undefined as number | undefined, notify_channels: [] as string[], }; export function AlertRuleDialog({ open, onOpenChange, editingRule, notifyChannels, onSaved, defaultType = 'metric', }: { open: boolean; onOpenChange: (open: boolean) => void; editingRule?: JsonData; notifyChannels: JsonData[]; onSaved: () => void; /** 新建时默认规则类型 // Logan.Li */ defaultType?: 'metric' | 'log' | 'event'; }) { const [ruleForm, setRuleForm] = useState({ ...emptyRuleForm }); const [ruleSaving, setRuleSaving] = useState(false); const [logSources, setLogSources] = useState([]); // 日志规则打开时加载对应类型的数据源列表 // Logan.Li useEffect(() => { if (!open || ruleForm.type !== 'log') { setLogSources([]); return; } logCenterApi.listDatasources(ruleForm.source).then((res) => { setLogSources(res?.list || []); }).catch(() => setLogSources([])); }, [open, ruleForm.type, ruleForm.source]); // 打开时同步表单(编辑时填充,新建时重置) useEffect(() => { if (!open) return; if (editingRule) { setRuleForm({ name: editingRule.name || '', description: editingRule.description || '', type: editingRule.type || 'metric', source: editingRule.source || 'prometheus', expression: editingRule.expression || '', severity: editingRule.severity || 'warning', duration: editingRule.duration || 300, datasource_id: editingRule.datasource_id, notify_channels: parseChannels(editingRule.notify_channels), }); } else { const base = { ...emptyRuleForm, type: defaultType }; if (defaultType === 'log') { base.source = 'loki'; } setRuleForm(base); } }, [open, editingRule, defaultType]); const toggleNotifyChannel = (channel: string) => { setRuleForm((prev) => ({ ...prev, notify_channels: prev.notify_channels.includes(channel) ? prev.notify_channels.filter((c) => c !== channel) : [...prev.notify_channels, channel], })); }; const handleSaveRule = async () => { if (!ruleForm.name.trim() || !ruleForm.expression.trim()) return; setRuleSaving(true); try { const payload = { name: ruleForm.name.trim(), description: ruleForm.description.trim(), type: ruleForm.type, source: ruleForm.source, expression: ruleForm.expression.trim(), severity: ruleForm.severity, duration: Number(ruleForm.duration) || 0, datasource_id: ruleForm.datasource_id, notify_channels: ruleForm.notify_channels, }; if (editingRule) { await alertApi.updateRule(editingRule.id, payload); } else { await alertApi.createRule(payload); } onOpenChange(false); onSaved(); } catch (error) { console.error('Failed to save rule:', error); } finally { setRuleSaving(false); } }; return ( {editingRule ? i18n.t('monitor.alertruledialog.sb62c8bc1') : i18n.t('monitor.alertruledialog.s3564fa12')} {editingRule ? i18n.t('monitor.alertruledialog.s44a3bb2d') : i18n.t('monitor.alertruledialog.sb785eced')}
setRuleForm({ ...ruleForm, name: e.target.value })} placeholder={i18n.t('monitor.alertruledialog.sf111cd25')} className="dg-input" />