diff --git a/client/src/Components/NotificationIntegrationModal/Components/NotificationIntegrationModal.jsx b/client/src/Components/NotificationIntegrationModal/Components/NotificationIntegrationModal.jsx
index 67502d9a0..dc94ee731 100644
--- a/client/src/Components/NotificationIntegrationModal/Components/NotificationIntegrationModal.jsx
+++ b/client/src/Components/NotificationIntegrationModal/Components/NotificationIntegrationModal.jsx
@@ -1,17 +1,17 @@
-import { useState, useMemo, useEffect, useCallback} from "react";
+import { useState, useMemo, useEffect, useCallback } from "react";
import { useTranslation } from "react-i18next";
import PropTypes from "prop-types";
-import {
- Dialog,
- DialogContent,
- DialogActions,
- Button,
- Typography,
- Box,
- Tabs,
- Tab,
- Stack,
+import {
+ Dialog,
+ DialogContent,
+ DialogActions,
+ Button,
+ Typography,
+ Box,
+ Tabs,
+ Tab,
+ Stack,
} from "@mui/material";
import { useTheme } from "@emotion/react";
import TabPanel from "./TabPanel";
@@ -20,115 +20,118 @@ import useNotifications from "../Hooks/useNotification";
// Define constants for notification types to avoid magic values
const NOTIFICATION_TYPES = {
- SLACK: 'slack',
- DISCORD: 'discord',
- TELEGRAM: 'telegram',
- WEBHOOK: 'webhook'
+ SLACK: "slack",
+ DISCORD: "discord",
+ TELEGRAM: "telegram",
+ WEBHOOK: "webhook",
};
// Define constants for field IDs
const FIELD_IDS = {
- WEBHOOK: 'webhook',
- TOKEN: 'token',
- CHAT_ID: 'chatId',
- URL: 'url'
+ WEBHOOK: "webhook",
+ TOKEN: "token",
+ CHAT_ID: "chatId",
+ URL: "url",
};
-const NotificationIntegrationModal = ({
- open,
- onClose,
- monitor,
- setMonitor,
- // Optional prop to configure available notification types
- notificationTypes = null
+const NotificationIntegrationModal = ({
+ open,
+ onClose,
+ monitor,
+ setMonitor,
+ // Optional prop to configure available notification types
+ notificationTypes = null,
}) => {
- const { t } = useTranslation();
- const theme = useTheme();
- const [tabValue, setTabValue] = useState(0);
-
- const [loading, _, sendTestNotification] = useNotifications();
-
- // Helper to get the field state key with error handling
- const getFieldKey = useCallback((typeId, fieldId) => {
- if (typeof typeId !== 'string' || typeId === '') {
- throw new Error(t('errorInvalidTypeId'));
- }
-
- if (typeof fieldId !== 'string' || fieldId === '') {
- throw new Error(t('errorInvalidFieldId'));
- }
-
- return `${typeId}${fieldId.charAt(0).toUpperCase() + fieldId.slice(1)}`;
- });
-
- // Define notification types
- const DEFAULT_NOTIFICATION_TYPES = [
- {
- id: NOTIFICATION_TYPES.SLACK,
- label: t('notifications.slack.label'),
- description: t('notifications.slack.description'),
- fields: [
- {
- id: FIELD_IDS.WEBHOOK,
- label: t('notifications.slack.webhookLabel'),
- placeholder: t('notifications.slack.webhookPlaceholder'),
- type: 'text'
- }
- ]
- },
- {
- id: NOTIFICATION_TYPES.DISCORD,
- label: t('notifications.discord.label'),
- description: t('notifications.discord.description'),
- fields: [
- {
- id: FIELD_IDS.WEBHOOK,
- label: t('notifications.discord.webhookLabel'),
- placeholder: t('notifications.discord.webhookPlaceholder'),
- type: 'text'
- }
- ]
- },
- {
- id: NOTIFICATION_TYPES.TELEGRAM,
- label: t('notifications.telegram.label'),
- description: t('notifications.telegram.description'),
- fields: [
- {
- id: FIELD_IDS.TOKEN,
- label: t('notifications.telegram.tokenLabel'),
- placeholder: t('notifications.telegram.tokenPlaceholder'),
- type: 'text'
- },
- {
- id: FIELD_IDS.CHAT_ID,
- label: t('notifications.telegram.chatIdLabel'),
- placeholder: t('notifications.telegram.chatIdPlaceholder'),
- type: 'text'
- }
- ]
- },
- {
- id: NOTIFICATION_TYPES.WEBHOOK,
- label: t('notifications.webhook.label'),
- description: t('notifications.webhook.description'),
- fields: [
- {
- id: FIELD_IDS.URL,
- label: t('notifications.webhook.urlLabel'),
- placeholder: t('notifications.webhook.urlPlaceholder'),
- type: 'text'
- }
- ]
- }
- ];
+ const { t } = useTranslation();
+ const theme = useTheme();
+ const [tabValue, setTabValue] = useState(0);
- // Use provided notification types or default to our translated ones
- const activeNotificationTypes = notificationTypes || DEFAULT_NOTIFICATION_TYPES;
-
- // Memoized function to initialize integrations state
- const initialIntegrationsState = useMemo(() => {
- const state = {};
+ const [loading, _, sendTestNotification] = useNotifications();
+
+ // Helper to get the field state key with error handling
+ const getFieldKey = useCallback(
+ (typeId, fieldId) => {
+ if (typeof typeId !== "string" || typeId === "") {
+ throw new Error(t("errorInvalidTypeId"));
+ }
+
+ if (typeof fieldId !== "string" || fieldId === "") {
+ throw new Error(t("errorInvalidFieldId"));
+ }
+
+ return `${typeId}${fieldId.charAt(0).toUpperCase() + fieldId.slice(1)}`;
+ },
+ [t]
+ );
+
+ // Define notification types
+ const DEFAULT_NOTIFICATION_TYPES = [
+ {
+ id: NOTIFICATION_TYPES.SLACK,
+ label: t("notifications.slack.label"),
+ description: t("notifications.slack.description"),
+ fields: [
+ {
+ id: FIELD_IDS.WEBHOOK,
+ label: t("notifications.slack.webhookLabel"),
+ placeholder: t("notifications.slack.webhookPlaceholder"),
+ type: "text",
+ },
+ ],
+ },
+ {
+ id: NOTIFICATION_TYPES.DISCORD,
+ label: t("notifications.discord.label"),
+ description: t("notifications.discord.description"),
+ fields: [
+ {
+ id: FIELD_IDS.WEBHOOK,
+ label: t("notifications.discord.webhookLabel"),
+ placeholder: t("notifications.discord.webhookPlaceholder"),
+ type: "text",
+ },
+ ],
+ },
+ {
+ id: NOTIFICATION_TYPES.TELEGRAM,
+ label: t("notifications.telegram.label"),
+ description: t("notifications.telegram.description"),
+ fields: [
+ {
+ id: FIELD_IDS.TOKEN,
+ label: t("notifications.telegram.tokenLabel"),
+ placeholder: t("notifications.telegram.tokenPlaceholder"),
+ type: "text",
+ },
+ {
+ id: FIELD_IDS.CHAT_ID,
+ label: t("notifications.telegram.chatIdLabel"),
+ placeholder: t("notifications.telegram.chatIdPlaceholder"),
+ type: "text",
+ },
+ ],
+ },
+ {
+ id: NOTIFICATION_TYPES.WEBHOOK,
+ label: t("notifications.webhook.label"),
+ description: t("notifications.webhook.description"),
+ fields: [
+ {
+ id: FIELD_IDS.URL,
+ label: t("notifications.webhook.urlLabel"),
+ placeholder: t("notifications.webhook.urlPlaceholder"),
+ type: "text",
+ },
+ ],
+ },
+ ];
+
+ // Use provided notification types or default to our translated ones
+ const activeNotificationTypes = notificationTypes || DEFAULT_NOTIFICATION_TYPES;
+
+ // Memoized function to initialize integrations state
+ const initialIntegrationsState = useMemo(() => {
+ const state = {};
activeNotificationTypes.forEach((type) => {
// Add enabled flag for each notification type
@@ -140,13 +143,13 @@ const NotificationIntegrationModal = ({
state[fieldKey] = "";
});
});
-
- return state;
- }, [activeNotificationTypes, getFieldKey]); // Only recompute when these dependencies change
-
- const [integrations, setIntegrations] = useState(initialIntegrationsState);
- useEffect(() => {
+ return state;
+ }, [activeNotificationTypes, getFieldKey]); // Only recompute when these dependencies change
+
+ const [integrations, setIntegrations] = useState(initialIntegrationsState);
+
+ useEffect(() => {
if (open) {
const extractNotificationValues = () => {
const values = {};
@@ -202,204 +205,215 @@ const NotificationIntegrationModal = ({
}
}, [open, monitor, getFieldKey]);
- const handleChangeTab = (event, newValue) => {
- setTabValue(newValue);
- };
+ const handleChangeTab = (event, newValue) => {
+ setTabValue(newValue);
+ };
- const handleIntegrationChange = (type, checked) => {
- setIntegrations(prev => ({
- ...prev,
- [type]: checked
- }));
- };
+ const handleIntegrationChange = (type, checked) => {
+ setIntegrations((prev) => ({
+ ...prev,
+ [type]: checked,
+ }));
+ };
- const handleInputChange = (type, value) => {
- setIntegrations(prev => ({
- ...prev,
- [type]: value
- }));
- };
+ const handleInputChange = (type, value) => {
+ setIntegrations((prev) => ({
+ ...prev,
+ [type]: value,
+ }));
+ };
- const handleTestNotification = async (type) => {
- // Get the notification type details
- const notificationType = activeNotificationTypes.find(t => t.id === type);
-
- if (typeof notificationType === "undefined") {
- return;
- }
-
- // Prepare config object based on notification type
- const config = {};
-
- // Add each field value to the config object
- notificationType.fields.forEach(field => {
- const fieldKey = getFieldKey(type, field.id);
- config[field.id] = integrations[fieldKey];
- });
-
- await sendTestNotification(type, config);
- };
-
- // In NotificationIntegrationModal.jsx, update the handleSave function:
+ const handleTestNotification = async (type) => {
+ // Get the notification type details
+ const notificationType = activeNotificationTypes.find((t) => t.id === type);
-const handleSave = () => {
- // Get existing notifications
- const notifications = [...(monitor?.notifications || [])];
-
- // Get all notification types IDs
- const existingTypes = activeNotificationTypes.map(type => type.id);
-
- // Filter out notifications that are configurable in this modal
- const filteredNotifications = notifications.filter(
- notification => {
-
- if (notification.platform) {
- return !existingTypes.includes(notification.platform);
- }
-
- return !existingTypes.includes(notification.type);
- }
- );
+ if (typeof notificationType === "undefined") {
+ return;
+ }
- // Add each enabled notification with its configured fields
- activeNotificationTypes.forEach(type => {
- if (integrations[type.id]) {
+ // Prepare config object based on notification type
+ const config = {};
- let notificationObject = {
- type: "webhook",
- platform: type.id, // Set platform to identify the specific service
- config: {}
- };
-
- // Configure based on notification type
- switch(type.id) {
- case "slack":
- case "discord":
- notificationObject.config.webhookUrl = integrations[getFieldKey(type.id, 'webhook')];
- break;
- case "telegram":
- notificationObject.config.botToken = integrations[getFieldKey(type.id, 'token')];
- notificationObject.config.chatId = integrations[getFieldKey(type.id, 'chatId')];
- break;
- case "webhook":
- notificationObject.config.webhookUrl = integrations[getFieldKey(type.id, 'url')];
- break;
- }
-
- filteredNotifications.push(notificationObject);
- }
- });
+ // Add each field value to the config object
+ notificationType.fields.forEach((field) => {
+ const fieldKey = getFieldKey(type, field.id);
+ config[field.id] = integrations[fieldKey];
+ });
- // Update monitor with new notifications
- setMonitor(prev => ({
- ...prev,
- notifications: filteredNotifications
- }));
-
- onClose();
-};
+ await sendTestNotification(type, config);
+ };
- return (
-
- );
+ const handleSave = () => {
+ // Get existing notifications
+ const notifications = [...(monitor?.notifications || [])];
+
+ // Get all notification types IDs
+ const existingTypes = activeNotificationTypes.map((type) => type.id);
+
+ // Filter out notifications that are configurable in this modal
+ const filteredNotifications = notifications.filter((notification) => {
+ if (notification.platform) {
+ return !existingTypes.includes(notification.platform);
+ }
+
+ return !existingTypes.includes(notification.type);
+ });
+
+ // Add each enabled notification with its configured fields
+ activeNotificationTypes.forEach((type) => {
+ if (integrations[type.id]) {
+ let notificationObject = {
+ type: "webhook",
+ platform: type.id, // Set platform to identify the specific service
+ config: {},
+ };
+
+ // Configure based on notification type
+ switch (type.id) {
+ case "slack":
+ case "discord":
+ notificationObject.config.webhookUrl =
+ integrations[getFieldKey(type.id, "webhook")];
+ break;
+ case "telegram":
+ notificationObject.config.botToken =
+ integrations[getFieldKey(type.id, "token")];
+ notificationObject.config.chatId =
+ integrations[getFieldKey(type.id, "chatId")];
+ break;
+ case "webhook":
+ notificationObject.config.webhookUrl =
+ integrations[getFieldKey(type.id, "url")];
+ break;
+ }
+
+ filteredNotifications.push(notificationObject);
+ }
+ });
+
+ // Update monitor with new notifications
+ setMonitor((prev) => ({
+ ...prev,
+ notifications: filteredNotifications,
+ }));
+
+ onClose();
+ };
+
+ return (
+
+ );
};
NotificationIntegrationModal.propTypes = {
- open: PropTypes.bool.isRequired,
- onClose: PropTypes.func.isRequired,
- monitor: PropTypes.object.isRequired,
- setMonitor: PropTypes.func.isRequired,
- notificationTypes: PropTypes.array
+ open: PropTypes.bool.isRequired,
+ onClose: PropTypes.func.isRequired,
+ monitor: PropTypes.object.isRequired,
+ setMonitor: PropTypes.func.isRequired,
+ notificationTypes: PropTypes.array,
};
-export default NotificationIntegrationModal;
\ No newline at end of file
+export default NotificationIntegrationModal;