diff --git a/client/src/Pages/Settings/SettingsGlobalThresholds.jsx b/client/src/Pages/Settings/SettingsGlobalThresholds.jsx index b4d2581d2..acc101ab4 100644 --- a/client/src/Pages/Settings/SettingsGlobalThresholds.jsx +++ b/client/src/Pages/Settings/SettingsGlobalThresholds.jsx @@ -1,95 +1,95 @@ -import Box from "@mui/material/Box"; -import Stack from "@mui/material/Stack"; -import Typography from "@mui/material/Typography"; -import ConfigBox from "../../Components/ConfigBox"; -import TextInput from "../../Components/Inputs/TextInput"; - -import { useTheme } from "@emotion/react"; -import { PropTypes } from "prop-types"; -import { useTranslation } from "react-i18next"; - -const SettingsGlobalThresholds = ({ - isAdmin, - HEADING_SX, - settingsData, - setSettingsData, -}) => { - const { t } = useTranslation(); // For language translation - const theme = useTheme(); // MUI theme access - - // Handles input change and updates parent state - const handleChange = (e, min, max) => { - const { name, value } = e.target; - - const numValue = parseFloat(value); - const isValidNumber = - value === "" || - (!isNaN(numValue) && isFinite(numValue) && numValue >= min && numValue <= max); - - if (isValidNumber) { - setSettingsData((prev) => ({ - ...prev, - settings: { - ...prev.settings, - globalThresholds: { - ...prev.settings?.globalThresholds, - [name]: value, - }, - }, - })); - } - }; - - // Only render this section for admins - if (!isAdmin) return null; - - return ( - - {/* Header and description */} - - - {t("settingsPage.globalThresholds.title", "Global Thresholds")} - - - {t( - "settingsPage.globalThresholds.description", - "Configure global CPU, Memory, Disk, and Temperature thresholds." - )} - - - - {/* Threshold inputs */} - - {[ - ["CPU Threshold (%)", "cpu", 1, 100], - ["Memory Threshold (%)", "memory", 1, 100], - ["Disk Threshold (%)", "disk", 1, 100], - ["Temperature Threshold (°C)", "temperature", 1, 150], - ].map(([label, name, min, max]) => ( - handleChange(e, min, max)} - /> - ))} - - - ); -}; - -// Prop types -SettingsGlobalThresholds.propTypes = { - isAdmin: PropTypes.bool, - HEADING_SX: PropTypes.object, - settingsData: PropTypes.object, - setSettingsData: PropTypes.func, -}; - -export default SettingsGlobalThresholds; +import Box from "@mui/material/Box"; +import Stack from "@mui/material/Stack"; +import Typography from "@mui/material/Typography"; +import ConfigBox from "../../Components/ConfigBox"; +import TextInput from "../../Components/Inputs/TextInput"; + +import { useTheme } from "@emotion/react"; +import { PropTypes } from "prop-types"; +import { useTranslation } from "react-i18next"; + +const SettingsGlobalThresholds = ({ + isAdmin, + HEADING_SX, + settingsData, + setSettingsData, +}) => { + const { t } = useTranslation(); // For language translation + const theme = useTheme(); // MUI theme access + + // Handles input change and updates parent state + const handleChange = (e, min, max) => { + const { name, value } = e.target; + + const numValue = parseFloat(value); + const isValidNumber = + value === "" || + (!isNaN(numValue) && isFinite(numValue) && numValue >= min && numValue <= max); + + if (isValidNumber) { + setSettingsData((prev) => ({ + ...prev, + settings: { + ...prev.settings, + globalThresholds: { + ...prev.settings?.globalThresholds, + [name]: value, + }, + }, + })); + } + }; + + // Only render this section for admins + if (!isAdmin) return null; + + return ( + + {/* Header and description */} + + + {t("settingsPage.globalThresholds.title", "Global Thresholds")} + + + {t( + "settingsPage.globalThresholds.description", + "Configure global CPU, Memory, Disk, and Temperature thresholds." + )} + + + + {/* Threshold inputs */} + + {[ + ["CPU Threshold (%)", "cpu", 1, 100], + ["Memory Threshold (%)", "memory", 1, 100], + ["Disk Threshold (%)", "disk", 1, 100], + ["Temperature Threshold (°C)", "temperature", 1, 150], + ].map(([label, name, min, max]) => ( + handleChange(e, min, max)} + /> + ))} + + + ); +}; + +// Prop types +SettingsGlobalThresholds.propTypes = { + isAdmin: PropTypes.bool, + HEADING_SX: PropTypes.object, + settingsData: PropTypes.object, + setSettingsData: PropTypes.func, +}; + +export default SettingsGlobalThresholds; diff --git a/client/src/Pages/Settings/index.jsx b/client/src/Pages/Settings/index.jsx index ab529eb68..92f58b4c0 100644 --- a/client/src/Pages/Settings/index.jsx +++ b/client/src/Pages/Settings/index.jsx @@ -49,7 +49,7 @@ const Settings = () => { setIsApiKeySet, setIsEmailPasswordSet, }); - + const [addDemoMonitors, isAddingDemoMonitors] = useAddDemoMonitors(); const [isSaving, saveError, saveSettings] = useSaveSettings({ @@ -62,7 +62,6 @@ const Settings = () => { const [deleteAllMonitors, isDeletingMonitors] = useDeleteAllMonitors(); const [deleteMonitorStats, isDeletingMonitorStats] = useDeleteMonitorStats(); - // Setup const isAdmin = useIsAdmin(); const theme = useTheme(); @@ -152,7 +151,7 @@ const Settings = () => { error.details.forEach((err) => { newErrors[err.path[0]] = err.message; }); - + setErrors(newErrors); } saveSettings(settingsData?.settings); diff --git a/client/src/Validation/validation.js b/client/src/Validation/validation.js index 22ea042d7..9c6699d4b 100644 --- a/client/src/Validation/validation.js +++ b/client/src/Validation/validation.js @@ -302,15 +302,16 @@ const settingsValidation = joi.object({ systemEmailIgnoreTLS: joi.boolean(), systemEmailRequireTLS: joi.boolean(), systemEmailRejectUnauthorized: joi.boolean(), - globalThresholds: joi.object({ - cpu: joi.number().min(1).max(100).allow("").optional(), - memory: joi.number().min(1).max(100).allow("").optional(), - disk: joi.number().min(1).max(100).allow("").optional(), - temperature: joi.number().min(1).max(150).allow("").optional(), - }).optional(), + globalThresholds: joi + .object({ + cpu: joi.number().min(1).max(100).allow("").optional(), + memory: joi.number().min(1).max(100).allow("").optional(), + disk: joi.number().min(1).max(100).allow("").optional(), + temperature: joi.number().min(1).max(150).allow("").optional(), + }) + .optional(), }); - const dayjsValidator = (value, helpers) => { if (!dayjs(value).isValid()) { return helpers.error("any.invalid"); diff --git a/client/src/locales/en.json b/client/src/locales/en.json index 5c69ecd81..86362d3c7 100644 --- a/client/src/locales/en.json +++ b/client/src/locales/en.json @@ -838,8 +838,8 @@ }, "title": "Settings", "globalThresholds": { - "title": "Global Thresholds", - "description": "Configure global CPU, Memory, Disk, and Temperature thresholds. If a value is provided, it will automatically be enabled for monitoring." + "title": "Global Thresholds", + "description": "Configure global CPU, Memory, Disk, and Temperature thresholds. If a value is provided, it will automatically be enabled for monitoring." }, "uiSettings": { "description": "Switch between light and dark mode, or change user interface language.",