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:
@@ -1,19 +1,25 @@
|
||||
|
||||
import React, { useEffect } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Form } from "@/components/ui/form";
|
||||
import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { useTemplateForm } from "./hooks/useTemplateForm";
|
||||
import { BasicTemplateFields } from "./form/BasicTemplateFields";
|
||||
import { MessagesTabContent } from "./form/MessagesTabContent";
|
||||
import { PlaceholdersTabContent } from "./form/PlaceholdersTabContent";
|
||||
import { ServerTemplateFields } from "./form/ServerTemplateFields";
|
||||
import { ServiceTemplateFields } from "./form/ServiceTemplateFields";
|
||||
import { SslTemplateFields } from "./form/SslTemplateFields";
|
||||
import { Loader2, ChevronDown } from "lucide-react";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import { TemplateType, templateTypeConfigs } from "@/services/templateService";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
|
||||
interface TemplateDialogProps {
|
||||
open: boolean;
|
||||
templateId: string | null;
|
||||
templateType: TemplateType | null;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
onSuccess: () => void;
|
||||
}
|
||||
@@ -21,9 +27,12 @@ interface TemplateDialogProps {
|
||||
export const TemplateDialog: React.FC<TemplateDialogProps> = ({
|
||||
open,
|
||||
templateId,
|
||||
templateType: initialTemplateType,
|
||||
onOpenChange,
|
||||
onSuccess,
|
||||
}) => {
|
||||
const [selectedTemplateType, setSelectedTemplateType] = useState<TemplateType>(initialTemplateType || 'service');
|
||||
|
||||
const {
|
||||
form,
|
||||
isEditMode,
|
||||
@@ -32,28 +41,70 @@ export const TemplateDialog: React.FC<TemplateDialogProps> = ({
|
||||
onSubmit
|
||||
} = useTemplateForm({
|
||||
templateId,
|
||||
templateType: selectedTemplateType,
|
||||
open,
|
||||
onOpenChange,
|
||||
onSuccess
|
||||
});
|
||||
|
||||
// For debugging purposes
|
||||
// Update template type when prop changes or dialog opens
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
// console.log("Template dialog opened. Edit mode:", isEditMode, "Template ID:", templateId);
|
||||
|
||||
// Log form values when they change
|
||||
const subscription = form.watch((value) => {
|
||||
// console.log("Current form values:", value);
|
||||
});
|
||||
|
||||
return () => subscription.unsubscribe();
|
||||
if (initialTemplateType) {
|
||||
setSelectedTemplateType(initialTemplateType);
|
||||
} else if (open && !isEditMode) {
|
||||
setSelectedTemplateType('service');
|
||||
}
|
||||
}, [open, isEditMode, templateId, form]);
|
||||
}, [initialTemplateType, open, isEditMode]);
|
||||
|
||||
// Handle template type change
|
||||
const handleTemplateTypeChange = (newType: TemplateType) => {
|
||||
if (!isEditMode) {
|
||||
setSelectedTemplateType(newType);
|
||||
form.setValue('templateType', newType);
|
||||
}
|
||||
};
|
||||
|
||||
const renderTemplateFields = () => {
|
||||
switch (selectedTemplateType) {
|
||||
case 'server':
|
||||
return <ServerTemplateFields control={form.control} />;
|
||||
case 'service':
|
||||
return <ServiceTemplateFields control={form.control} />;
|
||||
case 'ssl':
|
||||
return <SslTemplateFields control={form.control} />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const renderPlaceholderGuide = () => {
|
||||
const config = templateTypeConfigs[selectedTemplateType];
|
||||
if (!config) return null;
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sm font-medium">Available Placeholders</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p className="text-sm text-muted-foreground mb-3">
|
||||
{config.description}. Use these placeholders in your messages:
|
||||
</p>
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-2 text-sm">
|
||||
{config.placeholders.map((placeholder) => (
|
||||
<div key={placeholder} className="bg-muted/30 p-2 rounded">
|
||||
<code className="text-xs">{placeholder}</code>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-2xl max-h-[90vh] flex flex-col overflow-hidden">
|
||||
<DialogContent className="max-w-4xl max-h-[90vh] flex flex-col overflow-hidden">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{isEditMode ? "Edit Template" : "Add Template"}</DialogTitle>
|
||||
</DialogHeader>
|
||||
@@ -69,7 +120,69 @@ export const TemplateDialog: React.FC<TemplateDialogProps> = ({
|
||||
<div className="relative flex-1">
|
||||
<ScrollArea className="pr-4 overflow-auto" style={{ height: "calc(80vh - 180px)" }}>
|
||||
<div className="space-y-6 pb-6 pr-4">
|
||||
<BasicTemplateFields control={form.control} />
|
||||
{/* Basic Fields */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="name"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Template Name</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder="Enter template name"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="templateType"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Template Type</FormLabel>
|
||||
<FormControl>
|
||||
<Select
|
||||
onValueChange={handleTemplateTypeChange}
|
||||
value={selectedTemplateType}
|
||||
disabled={isEditMode}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select template type" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="server">Server Monitoring</SelectItem>
|
||||
<SelectItem value="service">Service Uptime</SelectItem>
|
||||
<SelectItem value="ssl">SSL Certificate</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="placeholder"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Custom Placeholder</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder="Optional custom placeholder"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Tabs defaultValue="messages">
|
||||
<TabsList className="grid w-full grid-cols-2">
|
||||
@@ -78,11 +191,11 @@ export const TemplateDialog: React.FC<TemplateDialogProps> = ({
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="messages" className="pt-4">
|
||||
<MessagesTabContent control={form.control} />
|
||||
{renderTemplateFields()}
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="placeholders" className="pt-4">
|
||||
<PlaceholdersTabContent control={form.control} />
|
||||
{renderPlaceholderGuide()}
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
@@ -120,4 +233,4 @@ export const TemplateDialog: React.FC<TemplateDialogProps> = ({
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user