From ed5d5986ff487c64839d0939855333006bc79556 Mon Sep 17 00:00:00 2001 From: mohadeseh safari Date: Tue, 27 May 2025 20:28:53 -0400 Subject: [PATCH 1/3] Fix #2343: Enable Save button when timezone changes - Added timezone field to frontend validation schema - Added timezone field to backend validation schema - Fixed state synchronization in Settings component --- client/src/Pages/Settings/index.jsx | 2 ++ client/src/Validation/validation.js | 1 + server/validation/joi.js | 1 + 3 files changed, 4 insertions(+) diff --git a/client/src/Pages/Settings/index.jsx b/client/src/Pages/Settings/index.jsx index 0f586b391..b86deaf8c 100644 --- a/client/src/Pages/Settings/index.jsx +++ b/client/src/Pages/Settings/index.jsx @@ -85,6 +85,8 @@ const Settings = () => { if (name === "timezone") { dispatch(setTimezone({ timezone: value })); + // Make sure to update settingsData with the new timezone value + setSettingsData(newSettingsData); } if (name === "mode") { diff --git a/client/src/Validation/validation.js b/client/src/Validation/validation.js index 068340ba8..211e62995 100644 --- a/client/src/Validation/validation.js +++ b/client/src/Validation/validation.js @@ -277,6 +277,7 @@ const settingsValidation = joi.object({ }), pagespeedApiKey: joi.string().allow("").optional(), language: joi.string().required(), + timezone: joi.string().allow("").optional(), systemEmailHost: joi.string().allow(""), systemEmailPort: joi.number().allow(null, ""), systemEmailAddress: joi.string().allow(""), diff --git a/server/validation/joi.js b/server/validation/joi.js index 1f4b1c35c..e0e563e84 100755 --- a/server/validation/joi.js +++ b/server/validation/joi.js @@ -427,6 +427,7 @@ const updateAppSettingsBodyValidation = joi.object({ checkTTL: joi.number().allow(""), pagespeedApiKey: joi.string().allow(""), language: joi.string().allow(""), + timezone: joi.string().allow(""), // showURL: joi.bool().required(), systemEmailHost: joi.string().allow(""), systemEmailPort: joi.number().allow(""), From 126fda6bc06b568100b35a516988c6e8c2b1c8f3 Mon Sep 17 00:00:00 2001 From: mohadeseh safari Date: Thu, 29 May 2025 19:34:21 -0400 Subject: [PATCH 2/3] remove call --- client/src/Pages/Settings/index.jsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/src/Pages/Settings/index.jsx b/client/src/Pages/Settings/index.jsx index b86deaf8c..0f586b391 100644 --- a/client/src/Pages/Settings/index.jsx +++ b/client/src/Pages/Settings/index.jsx @@ -85,8 +85,6 @@ const Settings = () => { if (name === "timezone") { dispatch(setTimezone({ timezone: value })); - // Make sure to update settingsData with the new timezone value - setSettingsData(newSettingsData); } if (name === "mode") { From 70055c712b0cc2caacfcfaaf0acfb0e2138dae23 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Fri, 30 May 2025 15:03:32 -0700 Subject: [PATCH 3/3] refactor i18n --- client/src/Components/I18nLoader/index.jsx | 16 ++++++++++++++++ client/src/Components/Inputs/Select/index.jsx | 3 ++- client/src/Components/LanguageSelector.jsx | 7 ++++--- client/src/Features/Settings/settingsSlice.js | 1 - client/src/Features/UI/uiSlice.js | 4 ++-- client/src/Pages/Settings/SettingsURL.jsx | 2 +- client/src/Pages/Settings/index.jsx | 1 - .../Monitors/Components/StatusBoxes/index.jsx | 3 +++ .../Components/StatusBoxes/statusBox.jsx | 12 ++++++------ client/src/Utils/NetworkService.js | 1 - client/src/Utils/i18n.js | 12 ++---------- client/src/main.jsx | 3 ++- 12 files changed, 38 insertions(+), 27 deletions(-) create mode 100644 client/src/Components/I18nLoader/index.jsx diff --git a/client/src/Components/I18nLoader/index.jsx b/client/src/Components/I18nLoader/index.jsx new file mode 100644 index 000000000..7c3cbfb85 --- /dev/null +++ b/client/src/Components/I18nLoader/index.jsx @@ -0,0 +1,16 @@ +import i18n from "../../Utils/i18n"; +import { useSelector } from "react-redux"; +import { useEffect } from "react"; +const I18nLoader = () => { + const language = useSelector((state) => state.ui.language); + + useEffect(() => { + if (language && i18n.language !== language) { + i18n.changeLanguage(language); + } + }, [language]); + + return null; +}; + +export default I18nLoader; diff --git a/client/src/Components/Inputs/Select/index.jsx b/client/src/Components/Inputs/Select/index.jsx index 927247d77..a31fedf66 100644 --- a/client/src/Components/Inputs/Select/index.jsx +++ b/client/src/Components/Inputs/Select/index.jsx @@ -164,7 +164,8 @@ Select.propTypes = { value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, items: PropTypes.arrayOf( PropTypes.shape({ - _id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, + _id: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool]) + .isRequired, name: PropTypes.string.isRequired, }) ).isRequired, diff --git a/client/src/Components/LanguageSelector.jsx b/client/src/Components/LanguageSelector.jsx index 66faf78ac..284d0db05 100644 --- a/client/src/Components/LanguageSelector.jsx +++ b/client/src/Components/LanguageSelector.jsx @@ -3,15 +3,17 @@ import { Box, MenuItem, Select, Stack } from "@mui/material"; import { useTheme } from "@emotion/react"; import "flag-icons/css/flag-icons.min.css"; import { useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; +import { setLanguage } from "../Features/UI/uiSlice"; const LanguageSelector = () => { const { i18n } = useTranslation(); const theme = useTheme(); const { language } = useSelector((state) => state.ui); - + const dispatch = useDispatch(); const handleChange = (event) => { const newLang = event.target.value; - i18n.changeLanguage(newLang); + dispatch(setLanguage(newLang)); }; const languages = Object.keys(i18n.options.resources || {}); @@ -32,7 +34,6 @@ const LanguageSelector = () => { } if (parsedLang.includes("-")) { parsedLang = parsedLang.split("-")[1].toLowerCase(); - console.log("parsedLang", parsedLang); } const flag = parsedLang ? `fi fi-${parsedLang}` : null; diff --git a/client/src/Features/Settings/settingsSlice.js b/client/src/Features/Settings/settingsSlice.js index 02724af02..d0725627a 100644 --- a/client/src/Features/Settings/settingsSlice.js +++ b/client/src/Features/Settings/settingsSlice.js @@ -5,7 +5,6 @@ const initialState = { isLoading: false, apiBaseUrl: "", logLevel: "debug", - language: "gb", pagespeedApiKey: "", }; diff --git a/client/src/Features/UI/uiSlice.js b/client/src/Features/UI/uiSlice.js index bd6e92804..3addfbb7a 100644 --- a/client/src/Features/UI/uiSlice.js +++ b/client/src/Features/UI/uiSlice.js @@ -24,7 +24,7 @@ const initialState = { greeting: { index: 0, lastUpdate: null }, timezone: "America/Toronto", distributedUptimeEnabled: false, - language: "gb", + language: "en", starPromptOpen: true, }; @@ -57,7 +57,7 @@ const uiSlice = createSlice({ setTimezone(state, action) { state.timezone = action.payload.timezone; }, - setLanguage(state, action) { + setLanguage: (state, action) => { state.language = action.payload; }, setStarPromptOpen: (state, action) => { diff --git a/client/src/Pages/Settings/SettingsURL.jsx b/client/src/Pages/Settings/SettingsURL.jsx index 64804c903..4b4cf7683 100644 --- a/client/src/Pages/Settings/SettingsURL.jsx +++ b/client/src/Pages/Settings/SettingsURL.jsx @@ -22,7 +22,7 @@ const SettingsURL = ({ HEADING_SX, handleChange, showURL }) => {