2025-03-01 22:36:07 -08:00
import { useState } from "react" ;
import {
Dialog ,
DialogContent ,
DialogActions ,
Button ,
Typography ,
Box ,
Tabs ,
2025-03-07 16:43:29 -08:00
Tab
2025-03-01 22:36:07 -08:00
} from "@mui/material" ;
import { useTheme } from "@emotion/react" ;
2025-03-07 16:56:00 -08:00
import TabPanel from "./TabPanel" ;
2025-03-08 13:01:28 -08:00
import TabComponent from "./TabComponent" ;
2025-03-01 22:36:07 -08:00
2025-03-07 17:25:28 -08:00
// Configuration for notification tabs
const NOTIFICATION_TYPES = [
{
id : 'slack' ,
label : 'Slack' ,
description : 'To enable Slack notifications, create a Slack app and enable incoming webhooks. After that, simply provide the webhook URL here.' ,
fields : [
{
id : 'webhook' ,
label : 'Webhook URL' ,
placeholder : 'https://hooks.slack.com/services/...' ,
type : 'text'
}
]
},
{
id : 'discord' ,
label : 'Discord' ,
description : 'To send data to a Discord channel from Checkmate via Discord notifications using webhooks, you can use Discord\'s incoming Webhooks feature.' ,
fields : [
{
id : 'webhook' ,
label : 'Discord Webhook URL' ,
placeholder : 'https://discord.com/api/webhooks/...' ,
type : 'text'
}
]
},
{
id : 'telegram' ,
label : 'Telegram' ,
description : 'To enable Telegram notifications, create a Telegram bot using BotFather, an official bot for creating and managing Telegram bots. Then, get the API token and chat ID and write them down here.' ,
fields : [
{
id : 'token' ,
label : 'Your bot token' ,
placeholder : '123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11' ,
type : 'text'
},
{
id : 'chatId' ,
label : 'Your Chat ID' ,
placeholder : '-1001234567890' ,
type : 'text'
}
]
},
{
id : 'webhook' ,
label : 'Webhooks' ,
description : 'You can set up a custom webhook to receive notifications when incidents occur.' ,
fields : [
{
id : 'url' ,
label : 'Webhook URL' ,
placeholder : 'https://your-server.com/webhook' ,
type : 'text'
}
]
}
];
2025-03-01 22:36:07 -08:00
const NotificationIntegrationModal = ({
open ,
onClose ,
monitor ,
2025-03-07 17:25:28 -08:00
setMonitor ,
// Optional prop to configure available notification types
notificationTypes = NOTIFICATION_TYPES
2025-03-01 22:36:07 -08:00
}) => {
const theme = useTheme ();
const [ tabValue , setTabValue ] = useState ( 0 );
2025-03-07 17:25:28 -08:00
// Initialize integrations state based on available notification types
const initializeIntegrationsState = () => {
const state = {};
notificationTypes . forEach ( type => {
// Add enabled flag for each notification type
state [ type . id ] = monitor ? . notifications ? . some ( n => n . type === type . id ) || false ;
// Add state for each field in the notification type
type . fields . forEach ( field => {
const fieldKey = ` ${ type . id }${ field . id . charAt ( 0 ). toUpperCase () + field . id . slice ( 1 ) } ` ;
state [ fieldKey ] = monitor ? . notifications ? . find ( n => n . type === type . id ) ? .[ field . id ] || "" ;
});
});
return state ;
};
const [ integrations , setIntegrations ] = useState ( initializeIntegrationsState ());
2025-03-01 22:36:07 -08:00
const handleChangeTab = ( event , newValue ) => {
setTabValue ( newValue );
};
const handleIntegrationChange = ( type , checked ) => {
setIntegrations ( prev => ({
... prev ,
[ type ] : checked
}));
};
const handleInputChange = ( type , value ) => {
setIntegrations ( prev => ({
... prev ,
[ type ] : value
}));
};
const handleTestNotification = ( type ) => {
console . log ( `Testing ${ type } notification` );
2025-03-04 15:56:09 -08:00
//implement the test notification functionality
2025-03-01 22:36:07 -08:00
};
const handleSave = () => {
2025-03-04 15:56:09 -08:00
//notifications array for selected integrations
2025-03-01 22:36:07 -08:00
const notifications = [...( monitor ? . notifications || [])];
2025-03-07 17:25:28 -08:00
// Get all notification types IDs
const existingTypes = notificationTypes . map ( type => type . id );
// Filter out notifications that are configurable in this modal
2025-03-01 22:36:07 -08:00
const filteredNotifications = notifications . filter (
notification => ! existingTypes . includes ( notification . type )
);
2025-03-07 17:25:28 -08:00
// Add each enabled notification with its configured fields
notificationTypes . forEach ( type => {
if ( integrations [ type . id ]) {
const notificationObject = {
type : type . id
};
// Add each field value to the notification object
type . fields . forEach ( field => {
const fieldKey = ` ${ type . id }${ field . id . charAt ( 0 ). toUpperCase () + field . id . slice ( 1 ) } ` ;
notificationObject [ field . id ] = integrations [ fieldKey ];
});
filteredNotifications . push ( notificationObject );
}
});
2025-03-01 22:36:07 -08:00
// Update monitor with new notifications
setMonitor ( prev => ({
... prev ,
notifications : filteredNotifications
}));
onClose ();
};
return (
< Dialog
open = { open }
onClose = { onClose }
fullWidth
maxWidth = "md"
sx = {{
'& .MuiDialog-paper' : {
2025-03-04 15:56:09 -08:00
maxWidth : '775px'
2025-03-01 22:36:07 -08:00
}
}}
>
< DialogContent >
2025-03-04 15:56:09 -08:00
< Box sx = {{ display : 'flex' , height : '300px' }}>
2025-03-01 22:36:07 -08:00
{ /* Left sidebar with tabs */ }
< Box sx = {{
borderRight : 1 ,
borderColor : 'divider' ,
minWidth : '200px' ,
2025-03-06 17:56:30 -08:00
pr : theme . spacing ( 10 )
2025-03-01 22:36:07 -08:00
}}>
2025-03-06 17:56:30 -08:00
< Typography variant = "subtitle1" sx = {{
my : theme . spacing ( 1 ),
fontWeight : 'bold' ,
fontSize : '0.9rem' ,
color : theme . palette . primary . contrastTextSecondary
}}>
Add or edit notifications
2025-03-01 22:36:07 -08:00
</ Typography >
< Tabs
orientation = "vertical"
variant = "scrollable"
value = { tabValue }
onChange = { handleChangeTab }
aria - label = "Notification tabs"
>
2025-03-08 13:01:28 -08:00
{ notificationTypes . map (( type ) => (
2025-03-07 17:25:28 -08:00
< Tab key = { type . id } label = { type . label } orientation = "vertical" />
))}
2025-03-01 22:36:07 -08:00
</ Tabs >
</ Box >
{ /* Right side content */ }
2025-03-06 17:56:30 -08:00
< Box sx = {{ flex : 1 , pl : theme . spacing ( 7.5 ) }}>
2025-03-07 17:25:28 -08:00
{ notificationTypes . map (( type , index ) => (
< TabPanel key = { type . id } value = { tabValue } index = { index }>
2025-03-08 13:01:28 -08:00
< TabComponent
type = { type }
integrations = { integrations }
handleIntegrationChange = { handleIntegrationChange }
handleInputChange = { handleInputChange }
handleTestNotification = { handleTestNotification }
/>
2025-03-07 17:25:28 -08:00
</ TabPanel >
))}
2025-03-01 22:36:07 -08:00
</ Box >
</ Box >
</ DialogContent >
2025-03-04 15:56:09 -08:00
< DialogActions sx = {{
p : theme . spacing ( 4 ),
display : 'flex' ,
justifyContent : 'flex-end' ,
2025-03-06 17:56:30 -08:00
mb : theme . spacing ( 5 ),
mr : theme . spacing ( 5 )
}}>
2025-03-01 22:36:07 -08:00
< Button
variant = "contained"
color = "accent"
onClick = { handleSave }
2025-03-04 15:56:09 -08:00
sx = {{
width : '120px'
}}
2025-03-01 22:36:07 -08:00
>
Save
</ Button >
</ DialogActions >
</ Dialog >
);
};
export default NotificationIntegrationModal ;