diff --git a/client/src/Hooks/settingsHooks.js b/client/src/Hooks/settingsHooks.js index 8c4bef385..4693d8daa 100644 --- a/client/src/Hooks/settingsHooks.js +++ b/client/src/Hooks/settingsHooks.js @@ -56,6 +56,7 @@ const useSaveSettings = ({ setEmailPasswordHasBeenReset(false); } setSettingsData(settingsResponse.data.data); + createToast({ body: t("settingsSuccessSaved") }); } catch (error) { createToast({ body: t("settingsFailedToSave") }); diff --git a/client/src/Pages/Settings/index.jsx b/client/src/Pages/Settings/index.jsx index 27cc6bb21..793dd9ac9 100644 --- a/client/src/Pages/Settings/index.jsx +++ b/client/src/Pages/Settings/index.jsx @@ -75,11 +75,6 @@ const Settings = () => { const handleChange = async (e) => { const { name, value, checked } = e.target; - // Special case for showURL until handled properly in the backend - if (name === "showURL") { - dispatch(setShowURL(value)); - return; - } let newValue; if ( name === "systemEmailIgnoreTLS" || @@ -90,6 +85,12 @@ const Settings = () => { ) { newValue = checked; } + + // Ensure showURL is a proper boolean + if (name === "showURL") { + newValue = value === true || value === "true"; + } + // Build next state early const newSettingsData = { ...settingsData, @@ -147,29 +148,22 @@ const Settings = () => { return; } - // Validate - const { error } = settingsValidation.validate(newSettingsData.settings, { - abortEarly: false, - }); - if (!error || error.details.length === 0) { - setErrors({}); - } else { - const newErrors = {}; - error.details.forEach((err) => { - newErrors[err.path[0]] = err.message; - }); - setErrors(newErrors); - } - setSettingsData(newSettingsData); + + // Update Redux immediately for UI feedback + if (name === "showURL") { + dispatch(setShowURL(newValue)); + } }; const handleSave = () => { + // Validate const { error } = settingsValidation.validate(settingsData.settings, { abortEarly: false, }); if (!error || error.details.length === 0) { setErrors({}); + saveSettings(settingsData?.settings); } else { const newErrors = {}; error.details.forEach((err) => { @@ -178,7 +172,6 @@ const Settings = () => { setErrors(newErrors); } - saveSettings(settingsData?.settings); }; return ( diff --git a/client/src/Validation/validation.js b/client/src/Validation/validation.js index 9a84e2e39..27d585074 100644 --- a/client/src/Validation/validation.js +++ b/client/src/Validation/validation.js @@ -328,6 +328,7 @@ const settingsValidation = joi.object({ systemEmailIgnoreTLS: joi.boolean(), systemEmailRequireTLS: joi.boolean(), systemEmailRejectUnauthorized: joi.boolean(), + showURL: joi.boolean().optional(), globalThresholds: joi .object({ cpu: joi.number().min(1).max(100).allow("").optional(), diff --git a/server/src/config/services.ts b/server/src/config/services.ts index daa576bf8..c526a8abb 100644 --- a/server/src/config/services.ts +++ b/server/src/config/services.ts @@ -129,7 +129,7 @@ export const initializeServices = async ({ // Create DB const checkModule = new CheckModule({ logger, Monitor, User }); const inviteModule = new InviteModule({ InviteToken, crypto, stringService }); - const statusPageModule = new StatusPageModule({ StatusPage, NormalizeData, stringService }); + const statusPageModule = new StatusPageModule({ StatusPage, NormalizeData, stringService, AppSettings }); const userModule = new UserModule({ User, Team, GenerateAvatarImage, ParseBoolean, stringService }); const maintenanceWindowModule = new MaintenanceWindowModule({ MaintenanceWindow }); const notificationModule = new NotificationModule({ Notification, Monitor }); diff --git a/server/src/db/models/AppSettings.js b/server/src/db/models/AppSettings.js index 2313d638c..a1a9964f2 100755 --- a/server/src/db/models/AppSettings.js +++ b/server/src/db/models/AppSettings.js @@ -55,6 +55,10 @@ const AppSettingsSchema = mongoose.Schema( type: Boolean, default: true, }, + showURL: { + type: Boolean, + default: false, + }, singleton: { type: Boolean, required: true, diff --git a/server/src/db/modules/statusPageModule.js b/server/src/db/modules/statusPageModule.js index 081d3bea5..152f9efc5 100755 --- a/server/src/db/modules/statusPageModule.js +++ b/server/src/db/modules/statusPageModule.js @@ -1,4 +1,3 @@ -// import StatusPage from "../../models/StatusPage.js"; // import { NormalizeData } from "../../../utils/dataUtils.js"; // import ServiceRegistry from "../../../service/system/serviceRegistry.js"; // import StringService from "../../../service/system/stringService.js"; @@ -6,10 +5,11 @@ const SERVICE_NAME = "statusPageModule"; class StatusPageModule { - constructor({ StatusPage, NormalizeData, stringService }) { + constructor({ StatusPage, NormalizeData, stringService, AppSettings }) { this.StatusPage = StatusPage; this.NormalizeData = NormalizeData; this.stringService = stringService; + this.AppSettings = AppSettings; } createStatusPage = async ({ statusPageData, image, userId, teamId }) => { @@ -260,11 +260,16 @@ class StatusPageModule { const { statusPage, monitors } = statusPageQuery[0]; + const appSettings = await this.AppSettings.findOne({ singleton: true }).lean(); + const showURL = appSettings?.showURL === true; + const normalizedMonitors = monitors.map((monitor) => { - return { - ...monitor, - checks: this.NormalizeData(monitor.checks, 10, 100), - }; + const normalizedChecks = this.NormalizeData(monitor.checks, 10, 100); + if (!showURL) { + const { url, port, secret, notifications, ...rest } = monitor; + return { ...rest, checks: normalizedChecks }; + } + return { ...monitor, checks: normalizedChecks }; }); return { statusPage, monitors: normalizedMonitors }; diff --git a/server/src/service/system/settingsService.js b/server/src/service/system/settingsService.js index 70d8d192c..cea46f7ed 100755 --- a/server/src/service/system/settingsService.js +++ b/server/src/service/system/settingsService.js @@ -60,6 +60,7 @@ class SettingsService { await this.AppSettings.create({}); settings = await this.AppSettings.findOne({ singleton: true }).select("-__v -_id -createdAt -updatedAt -singleton").lean(); } + return settings; } } diff --git a/server/src/validation/joi.js b/server/src/validation/joi.js index c09ac88b9..b143d08be 100755 --- a/server/src/validation/joi.js +++ b/server/src/validation/joi.js @@ -413,7 +413,7 @@ const updateAppSettingsBodyValidation = joi.object({ pagespeedApiKey: joi.string().allow(""), language: joi.string().allow(""), timezone: joi.string().allow(""), - // showURL: joi.bool().required(), + showURL: joi.bool().optional(), systemEmailHost: joi.string().allow(""), systemEmailPort: joi.number().allow(""), systemEmailAddress: joi.string().allow(""),