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
+100 -80
View File
@@ -1,100 +1,120 @@
import { pb } from "@/lib/pocketbase";
import {
serverNotificationTemplateService,
ServerNotificationTemplate,
CreateUpdateServerNotificationTemplateData
} from "./serverNotificationTemplateService";
import {
serviceNotificationTemplateService,
ServiceNotificationTemplate,
CreateUpdateServiceNotificationTemplateData
} from "./serviceNotificationTemplateService";
import {
sslNotificationTemplateService,
SslNotificationTemplate,
CreateUpdateSslNotificationTemplateData
} from "./sslNotificationTemplateService";
export interface NotificationTemplate {
id: string;
collectionId: string;
collectionName: string;
name: string;
up_message: string;
down_message: string;
service_name_placeholder: string;
response_time_placeholder: string;
status_placeholder: string;
threshold_placeholder: string;
type: string;
maintenance_message: string;
incident_message: string;
resolved_message: string;
created: string;
updated: string;
}
export type TemplateType = 'server' | 'service' | 'ssl';
export interface CreateUpdateTemplateData {
name: string;
up_message: string;
down_message: string;
service_name_placeholder: string;
response_time_placeholder: string;
status_placeholder: string;
threshold_placeholder: string;
type: string;
maintenance_message: string;
incident_message: string;
resolved_message: string;
}
export type AnyTemplate = ServerNotificationTemplate | ServiceNotificationTemplate | SslNotificationTemplate;
export type AnyTemplateData = CreateUpdateServerNotificationTemplateData | CreateUpdateServiceNotificationTemplateData | CreateUpdateSslNotificationTemplateData;
// Export individual template types
export type { ServerNotificationTemplate, ServiceNotificationTemplate, SslNotificationTemplate };
export type { CreateUpdateServerNotificationTemplateData, CreateUpdateServiceNotificationTemplateData, CreateUpdateSslNotificationTemplateData };
export const templateService = {
async getTemplates(): Promise<NotificationTemplate[]> {
try {
// console.log("Fetching server notification templates");
const response = await pb.collection('server_notification_templates').getList(1, 50, {
sort: '-created',
});
// console.log("Server templates response:", response);
return response.items as unknown as NotificationTemplate[];
} catch (error) {
// console.error("Error fetching server templates:", error);
throw error;
async getTemplates(type: TemplateType): Promise<AnyTemplate[]> {
switch (type) {
case 'server':
return serverNotificationTemplateService.getTemplates();
case 'service':
return serviceNotificationTemplateService.getTemplates();
case 'ssl':
return sslNotificationTemplateService.getTemplates();
default:
throw new Error(`Unknown template type: ${type}`);
}
},
async getTemplate(id: string): Promise<NotificationTemplate> {
try {
// console.log(`Fetching server template with id: ${id}`);
const response = await pb.collection('server_notification_templates').getOne(id);
// console.log("Server template response:", response);
return response as unknown as NotificationTemplate;
} catch (error) {
// console.error(`Error fetching server template with id ${id}:`, error);
throw error;
async getTemplate(id: string, type: TemplateType): Promise<AnyTemplate> {
switch (type) {
case 'server':
return serverNotificationTemplateService.getTemplate(id);
case 'service':
return serviceNotificationTemplateService.getTemplate(id);
case 'ssl':
return sslNotificationTemplateService.getTemplate(id);
default:
throw new Error(`Unknown template type: ${type}`);
}
},
async createTemplate(data: CreateUpdateTemplateData): Promise<NotificationTemplate> {
try {
// console.log("Creating new server template with data:", data);
const response = await pb.collection('server_notification_templates').create(data);
// console.log("Create server template response:", response);
return response as unknown as NotificationTemplate;
} catch (error) {
// console.error("Error creating server template:", error);
throw error;
async createTemplate(data: AnyTemplateData, type: TemplateType): Promise<AnyTemplate> {
switch (type) {
case 'server':
return serverNotificationTemplateService.createTemplate(data as CreateUpdateServerNotificationTemplateData);
case 'service':
return serviceNotificationTemplateService.createTemplate(data as CreateUpdateServiceNotificationTemplateData);
case 'ssl':
return sslNotificationTemplateService.createTemplate(data as CreateUpdateSslNotificationTemplateData);
default:
throw new Error(`Unknown template type: ${type}`);
}
},
async updateTemplate(id: string, data: Partial<CreateUpdateTemplateData>): Promise<NotificationTemplate> {
try {
// console.log(`Updating server template with id: ${id}`, data);
const response = await pb.collection('server_notification_templates').update(id, data);
// console.log("Update server template response:", response);
return response as unknown as NotificationTemplate;
} catch (error) {
// console.error(`Error updating server template with id ${id}:`, error);
throw error;
async updateTemplate(id: string, data: Partial<AnyTemplateData>, type: TemplateType): Promise<AnyTemplate> {
switch (type) {
case 'server':
return serverNotificationTemplateService.updateTemplate(id, data as Partial<CreateUpdateServerNotificationTemplateData>);
case 'service':
return serviceNotificationTemplateService.updateTemplate(id, data as Partial<CreateUpdateServiceNotificationTemplateData>);
case 'ssl':
return sslNotificationTemplateService.updateTemplate(id, data as Partial<CreateUpdateSslNotificationTemplateData>);
default:
throw new Error(`Unknown template type: ${type}`);
}
},
async deleteTemplate(id: string): Promise<boolean> {
try {
// console.log(`Deleting server template with id: ${id}`);
await pb.collection('server_notification_templates').delete(id);
// console.log("Server template deleted successfully");
return true;
} catch (error) {
// console.error(`Error deleting server template with id ${id}:`, error);
throw error;
async deleteTemplate(id: string, type: TemplateType): Promise<boolean> {
switch (type) {
case 'server':
return serverNotificationTemplateService.deleteTemplate(id);
case 'service':
return serviceNotificationTemplateService.deleteTemplate(id);
case 'ssl':
return sslNotificationTemplateService.deleteTemplate(id);
default:
throw new Error(`Unknown template type: ${type}`);
}
}
};
// Template type configurations
export const templateTypeConfigs = {
server: {
label: 'Server Monitoring',
description: 'Templates for server resource monitoring alerts',
placeholders: [
'${server_name}', '${cpu_usage}', '${ram_usage}', '${disk_usage}',
'${network_usage}', '${cpu_temp}', '${disk_io}', '${threshold}', '${time}'
]
},
service: {
label: 'Service Uptime',
description: 'Templates for service uptime monitoring alerts',
placeholders: [
'${service_name}', '${status}', '${response_time}', '${url}',
'${uptime}', '${downtime}', '${time}'
]
},
ssl: {
label: 'SSL Certificate',
description: 'Templates for SSL certificate monitoring alerts',
placeholders: [
'${domain}', '${certificate_name}', '${expiry_date}', '${days_left}',
'${issuer}', '${serial_number}', '${time}'
]
}
};