feat: Support multiple notification channels

- Update the Notification Settings dashboard to allow users to select multiple notification channels for alerts.
- Add webhook to notification channels: Add webhook as a selectable option in the notification channel type dropdown.
- Implement template type selection in the Add Template dialog. Based on the selected type.
This commit is contained in:
Tola Leng
2025-08-02 16:53:15 +07:00
parent f7cf2fcc20
commit 914f1aba60
24 changed files with 1712 additions and 1049 deletions
@@ -0,0 +1,211 @@
import React from "react";
import { FormField, FormItem, FormLabel, FormControl, FormMessage, FormDescription } from "@/components/ui/form";
import { Textarea } from "@/components/ui/textarea";
import { Control } from "react-hook-form";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
interface ServerTemplateFieldsProps {
control: Control<any>;
}
export const ServerTemplateFields: React.FC<ServerTemplateFieldsProps> = ({ control }) => {
return (
<div className="space-y-6">
<Card>
<CardHeader className="pb-3">
<CardTitle className="text-sm font-medium">System Resource Messages</CardTitle>
</CardHeader>
<CardContent>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<FormField
control={control}
name="cpu_message"
render={({ field }) => (
<FormItem>
<FormLabel>CPU Alert Message</FormLabel>
<FormControl>
<Textarea
placeholder="CPU usage on ${server_name} is ${cpu_usage}% (threshold: ${threshold}%)"
className="min-h-20"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={control}
name="ram_message"
render={({ field }) => (
<FormItem>
<FormLabel>RAM Alert Message</FormLabel>
<FormControl>
<Textarea
placeholder="Memory usage on ${server_name} is ${ram_usage}% (threshold: ${threshold}%)"
className="min-h-20"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={control}
name="disk_message"
render={({ field }) => (
<FormItem>
<FormLabel>Disk Alert Message</FormLabel>
<FormControl>
<Textarea
placeholder="Disk usage on ${server_name} is ${disk_usage}% (threshold: ${threshold}%)"
className="min-h-20"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={control}
name="network_message"
render={({ field }) => (
<FormItem>
<FormLabel>Network Alert Message</FormLabel>
<FormControl>
<Textarea
placeholder="Network usage on ${server_name} is ${network_usage}% (threshold: ${threshold}%)"
className="min-h-20"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
</CardContent>
</Card>
<Card>
<CardContent className="pt-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<FormField
control={control}
name="up_message"
render={({ field }) => (
<FormItem>
<FormLabel>Server Up Message</FormLabel>
<FormControl>
<Textarea
placeholder="Server ${server_name} is UP and responding"
className="min-h-20"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={control}
name="down_message"
render={({ field }) => (
<FormItem>
<FormLabel>Server Down Message</FormLabel>
<FormControl>
<Textarea
placeholder="Server ${server_name} is DOWN"
className="min-h-20"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={control}
name="warning_message"
render={({ field }) => (
<FormItem>
<FormLabel>Warning Message</FormLabel>
<FormControl>
<Textarea
placeholder="Warning: Server ${server_name} requires attention"
className="min-h-20"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={control}
name="paused_message"
render={({ field }) => (
<FormItem>
<FormLabel>Paused Message</FormLabel>
<FormControl>
<Textarea
placeholder="Monitoring for server ${server_name} is paused"
className="min-h-20"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={control}
name="cpu_temp_message"
render={({ field }) => (
<FormItem>
<FormLabel>CPU Temperature Message</FormLabel>
<FormControl>
<Textarea
placeholder="CPU temperature on ${server_name} is ${cpu_temp}°C"
className="min-h-20"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={control}
name="disk_io_message"
render={({ field }) => (
<FormItem>
<FormLabel>Disk I/O Message</FormLabel>
<FormControl>
<Textarea
placeholder="Disk I/O on ${server_name} is ${disk_io} MB/s"
className="min-h-20"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
</CardContent>
</Card>
</div>
);
};
@@ -0,0 +1,133 @@
import React from "react";
import { FormField, FormItem, FormLabel, FormControl, FormMessage } from "@/components/ui/form";
import { Textarea } from "@/components/ui/textarea";
import { Control } from "react-hook-form";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
interface ServiceTemplateFieldsProps {
control: Control<any>;
}
export const ServiceTemplateFields: React.FC<ServiceTemplateFieldsProps> = ({ control }) => {
return (
<div className="space-y-6">
<Card>
<CardHeader className="pb-3">
<CardTitle className="text-sm font-medium">Service Status Messages</CardTitle>
</CardHeader>
<CardContent>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<FormField
control={control}
name="up_message"
render={({ field }) => (
<FormItem>
<FormLabel>Service Up Message</FormLabel>
<FormControl>
<Textarea
placeholder="Service ${service_name} is UP. Response time: ${response_time}ms"
className="min-h-20"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={control}
name="down_message"
render={({ field }) => (
<FormItem>
<FormLabel>Service Down Message</FormLabel>
<FormControl>
<Textarea
placeholder="Service ${service_name} is DOWN. Status: ${status}"
className="min-h-20"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={control}
name="maintenance_message"
render={({ field }) => (
<FormItem>
<FormLabel>Maintenance Message</FormLabel>
<FormControl>
<Textarea
placeholder="Service ${service_name} is under maintenance"
className="min-h-20"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={control}
name="incident_message"
render={({ field }) => (
<FormItem>
<FormLabel>Incident Message</FormLabel>
<FormControl>
<Textarea
placeholder="Service ${service_name} has an incident"
className="min-h-20"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={control}
name="resolved_message"
render={({ field }) => (
<FormItem>
<FormLabel>Resolved Message</FormLabel>
<FormControl>
<Textarea
placeholder="Issue with service ${service_name} has been resolved"
className="min-h-20"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={control}
name="warning_message"
render={({ field }) => (
<FormItem>
<FormLabel>Warning Message</FormLabel>
<FormControl>
<Textarea
placeholder="Warning: Service ${service_name} response time is high"
className="min-h-20"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
</CardContent>
</Card>
</div>
);
};
@@ -0,0 +1,79 @@
import React from "react";
import { FormField, FormItem, FormLabel, FormControl, FormMessage } from "@/components/ui/form";
import { Textarea } from "@/components/ui/textarea";
import { Control } from "react-hook-form";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
interface SslTemplateFieldsProps {
control: Control<any>;
}
export const SslTemplateFields: React.FC<SslTemplateFieldsProps> = ({ control }) => {
return (
<div className="space-y-6">
<Card>
<CardHeader className="pb-3">
<CardTitle className="text-sm font-medium">SSL Certificate Messages</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-4">
<FormField
control={control}
name="expired"
render={({ field }) => (
<FormItem>
<FormLabel>Certificate Expired Message</FormLabel>
<FormControl>
<Textarea
placeholder="SSL certificate for ${domain} has EXPIRED on ${expiry_date}"
className="min-h-24"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={control}
name="exiring_soon"
render={({ field }) => (
<FormItem>
<FormLabel>Certificate Expiring Soon Message</FormLabel>
<FormControl>
<Textarea
placeholder="SSL certificate for ${domain} will expire in ${days_left} days on ${expiry_date}"
className="min-h-24"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={control}
name="warning"
render={({ field }) => (
<FormItem>
<FormLabel>Certificate Warning Message</FormLabel>
<FormControl>
<Textarea
placeholder="Warning: SSL certificate for ${domain} requires attention"
className="min-h-24"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
</CardContent>
</Card>
</div>
);
};