Files
Checkmate/src/Components/NotificationIntegrationModal/NotificationIntegrationModal.jsx
T

268 lines
7.4 KiB
React
Raw Normal View History

2025-03-01 22:36:07 -08:00
import { useState } from "react";
import {
Dialog,
DialogContent,
DialogActions,
Button,
Typography,
Box,
Tabs,
Tab
2025-03-01 22:36:07 -08:00
} from "@mui/material";
import { useTheme } from "@emotion/react";
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`);
//implement the test notification functionality
2025-03-01 22:36:07 -08:00
};
const handleSave = () => {
//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': {
width: `calc(90% - ${theme.spacing(40)})`,
maxWidth: theme.breakpoints.values.md
2025-03-01 22:36:07 -08:00
}
}}
>
<DialogContent>
<Box sx={{
display: 'flex',
height: `calc(26vh - ${theme.spacing(20)})`
}}>
2025-03-01 22:36:07 -08:00
{/* Left sidebar with tabs */}
<Box sx={{
borderRight: 1,
borderColor: theme.palette.primary.lowContrast,
width: '30%',
maxWidth: theme.spacing(120),
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: theme.typography.fontSize * 0.9,
color: theme.palette.primary.contrastTextSecondary,
pl: theme.spacing(4)
2025-03-06 17:56:30 -08:00
}}>
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) => (
<Tab
key={type.id}
label={type.label}
orientation="vertical"
disableRipple
/>
2025-03-07 17:25:28 -08:00
))}
2025-03-01 22:36:07 -08:00
</Tabs>
</Box>
{/* Right side content */}
<Box sx={{
flex: 1,
pl: theme.spacing(7.5),
overflowY: 'auto'
}}>
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>
<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}
sx={{
width: 'auto',
minWidth: theme.spacing(60),
px: theme.spacing(8)
}}
2025-03-01 22:36:07 -08:00
>
Save
</Button>
</DialogActions>
</Dialog>
);
};
export default NotificationIntegrationModal;