import { useState, useEffect } from 'react'; import { useConfirm } from '@/components/ui/confirm-dialog'; 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 { Badge } from '@/components/ui/badge'; import { Switch } from '@/components/ui/switch'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Plus, Trash2, Loader2 } from 'lucide-react'; import { alertApi } from '@/services/api'; import { CHANNEL_TYPES, getChannelTypeLabel } from './alertShared'; const defaultChannelForm = { name: '', type: 'dingtalk', config: '', enabled: true }; export function AlertChannelDialog({ open, onOpenChange, notifyChannels, onChannelsChanged, }: { open: boolean; onOpenChange: (open: boolean) => void; notifyChannels: any[]; onChannelsChanged: () => void; }) { const _confirm = useConfirm(); const [editingChannel, setEditingChannel] = useState(null); const [channelSaving, setChannelSaving] = useState(false); const [channelTesting, setChannelTesting] = useState(null); const [channelForm, setChannelForm] = useState({ ...defaultChannelForm }); // 打开时重置为新建模式 useEffect(() => { if (open) { setEditingChannel(null); setChannelForm({ ...defaultChannelForm }); } }, [open]); const openEditChannel = (ch: any) => { setEditingChannel(ch); setChannelForm({ name: ch.name || '', type: ch.type || 'dingtalk', config: ch.config || '', enabled: ch.enabled !== false, }); }; const resetChannelForm = () => { setEditingChannel(null); setChannelForm({ ...defaultChannelForm }); }; const handleSaveChannel = async () => { if (!channelForm.name.trim()) return; setChannelSaving(true); try { const payload = { name: channelForm.name.trim(), type: channelForm.type, config: channelForm.config.trim(), }; if (editingChannel) { await alertApi.updateNotifyChannel(editingChannel.id, { ...payload, enabled: channelForm.enabled }); } else { await alertApi.createNotifyChannel(payload); } resetChannelForm(); onChannelsChanged(); } catch (error) { console.error('Failed to save notify channel:', error); } finally { setChannelSaving(false); } }; const handleDeleteChannel = async (id: any) => { { const ok = await _confirm({ title: '删除通知渠道', description: '确定删除此通知渠道?', confirmText: '删除', variant: 'destructive' }); if (!ok) return; } try { await alertApi.deleteNotifyChannel(id); if (editingChannel && editingChannel.id === id) resetChannelForm(); onChannelsChanged(); } catch (error) { console.error('Failed to delete notify channel:', error); } }; const handleToggleChannel = async (ch: any) => { try { await alertApi.updateNotifyChannel(ch.id, { enabled: !ch.enabled }); onChannelsChanged(); } catch (error) { console.error('Failed to toggle notify channel:', error); } }; const handleTestChannel = async (id: any) => { setChannelTesting(id); try { await alertApi.testNotifyChannel(id); onChannelsChanged(); } catch (error) { console.error('Failed to test notify channel:', error); } finally { setChannelTesting(null); } }; return ( 通知渠道配置 管理告警通知渠道(钉钉/企业微信/邮件/短信/Webhook),配置后可在告警规则中引用
{/* 渠道列表 */}
{notifyChannels.length === 0 ? (
暂无通知渠道,请在右侧添加
) : (
{notifyChannels.map((ch) => (
openEditChannel(ch)} >
{ch.name} {getChannelTypeLabel(ch.type)}
handleToggleChannel(ch)} onClick={(e) => e.stopPropagation()} className="data-[state=checked]:bg-emerald-600 scale-90" />
{ch.test_status === 'success' ? ( 测试通过 ) : ( 未测试 )}
e.stopPropagation()}>
))}
)}
{/* 渠道表单 */}
setChannelForm({ ...channelForm, name: e.target.value })} placeholder="如:运维告警群" className="bg-slate-800/50 border-slate-700 text-slate-200 placeholder:text-slate-600 h-9" />