diff --git a/Client/src/Pages/AdvancedSettings/index.jsx b/Client/src/Pages/AdvancedSettings/index.jsx
index 12016889f..ce1c89250 100644
--- a/Client/src/Pages/AdvancedSettings/index.jsx
+++ b/Client/src/Pages/AdvancedSettings/index.jsx
@@ -12,47 +12,45 @@ import { useNavigate } from "react-router";
import { getAppSettings, updateAppSettings } from "../../Features/Settings/settingsSlice";
import { useState, useEffect } from "react";
import Select from "../../Components/Inputs/Select";
-import { advancedSettingsValidation } from "../../Validation/validation";
-import { buildErrors, hasValidationErrors } from "../../Validation/error";
const AdvancedSettings = ({ isAdmin }) => {
- const navigate = useNavigate();
- useEffect(() => {
- if (!isAdmin) {
- navigate("/");
- }
- }, [navigate, isAdmin]);
+ const navigate = useNavigate();
- const theme = useTheme();
- const { authToken } = useSelector((state) => state.auth);
- const dispatch = useDispatch();
- const settings = useSelector((state) => state.settings);
- const [localSettings, setLocalSettings] = useState({
- apiBaseUrl: "",
- logLevel: "debug",
- systemEmailHost: "",
- systemEmailPort: "",
- systemEmailAddress: "",
- systemEmailPassword: "",
- jwtTTL: "",
- dbType: "",
- redisHost: "",
- redisPort: "",
- pagespeedApiKey: "",
- });
- const [errors, setErrors] = useState({});
+ useEffect(() => {
+ if (!isAdmin) {
+ navigate("/");
+ }
+ }, [navigate, isAdmin]);
- useEffect(() => {
- const getSettings = async () => {
- const action = await dispatch(getAppSettings({ authToken }));
- if (action.payload?.success) {
- setLocalSettings(action.payload.data);
- } else {
- createToast({ body: "Failed to get settings" });
- }
- };
- getSettings();
- }, [authToken, dispatch]);
+ const theme = useTheme();
+ const { authToken } = useSelector((state) => state.auth);
+ const dispatch = useDispatch();
+ const settings = useSelector((state) => state.settings);
+ const [localSettings, setLocalSettings] = useState({
+ apiBaseUrl: "",
+ logLevel: "debug",
+ systemEmailHost: "",
+ systemEmailPort: "",
+ systemEmailAddress: "",
+ systemEmailPassword: "",
+ jwtTTL: "",
+ dbType: "",
+ redisHost: "",
+ redisPort: "",
+ pagespeedApiKey: "",
+ });
+
+ useEffect(() => {
+ const getSettings = async () => {
+ const action = await dispatch(getAppSettings({ authToken }));
+ if (action.payload.success) {
+ setLocalSettings(action.payload.data);
+ } else {
+ createToast({ body: "Failed to get settings" });
+ }
+ };
+ getSettings();
+ }, [authToken, dispatch]);
const logItems = [
{ _id: 1, name: "none" },
@@ -74,210 +72,189 @@ const AdvancedSettings = ({ isAdmin }) => {
setLocalSettings({ ...localSettings, logLevel: newLogLevel });
};
- const handleChange = (event) => {
- const { value, id } = event.target;
- setLocalSettings({ ...localSettings, [id]: value });
- const { error } = advancedSettingsValidation.validate(
- { [id]: value },
- {
- abortEarly: false,
- }
- );
- setErrors((prev) => {
- return buildErrors(prev, id, error);
- });
- };
+ const handleChange = (event) => {
+ const { value, id } = event.target;
+ setLocalSettings({ ...localSettings, [id]: value });
+ };
- const handleSave = async () => {
- if (hasValidationErrors(localSettings, advancedSettingsValidation, setErrors))
- return;
- const action = await dispatch(
- updateAppSettings({ settings: localSettings, authToken })
- );
- let body = "";
- if (action.payload.success) {
- console.log(action.payload.data);
- setLocalSettings(action.payload.data);
- body = "Settings saved successfully";
- } else {
- body = "Failed to save settings";
- }
- createToast({ body });
- };
+ const handleSave = async () => {
+ const action = await dispatch(
+ updateAppSettings({ settings: localSettings, authToken })
+ );
+ let body = "";
+ if (action.payload.success) {
+ console.log(action.payload.data);
+ setLocalSettings(action.payload.data);
+ body = "Settings saved successfully";
+ } else {
+ body = "Failed to save settings";
+ }
+ createToast({ body });
+ };
- return (
-
-
-
-
- Client settings
-
- Modify client settings here.
-
-
-
-
-
-
-
-
-
- Email settings
-
- Set your host email settings here. These settings are used for
- sending system emails.
-
-
-
-
-
-
-
-
-
-
-
- Server settings
-
- Modify server settings here.
-
-
-
-
-
-
-
-
-
-
-
-
- About
-
-
- BlueWave Uptime v1.0.0
-
- Developed by Bluewave Labs.
-
-
-
-
-
-
- Save
-
-
-
-
- );
+ return (
+
+
+
+
+ Client settings
+
+ Modify client settings here.
+
+
+
+
+
+
+
+
+
+ Email settings
+
+ Set your host email settings here. These settings are used for sending
+ system emails.
+
+
+
+
+
+
+
+
+
+
+
+ Server settings
+
+ Modify server settings here.
+
+
+
+
+
+
+
+
+
+
+
+
+ About
+
+
+ BlueWave Uptime v1.0.0
+
+ Developed by Bluewave Labs.
+
+
+
+
+
+
+ Save
+
+
+
+
+ );
};
AdvancedSettings.propTypes = {
diff --git a/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx b/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx
index d165523f9..4dbf8f747 100644
--- a/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx
+++ b/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx
@@ -28,7 +28,6 @@ import {
MS_PER_WEEK,
} from "../../../Utils/timeUtils";
import { useNavigate, useParams } from "react-router-dom";
-import { buildErrors, hasValidationErrors } from "../../../Validation/error";
const getDurationAndUnit = (durationInMs) => {
if (durationInMs % MS_PER_DAY === 0) {
@@ -146,36 +145,46 @@ const CreateMaintenance = () => {
return;
}
- const res = await networkService.getMaintenanceWindowById({
- authToken: authToken,
- maintenanceWindowId: maintenanceWindowId,
- });
- const maintenanceWindow = res.data.data;
- const { name, start, end, repeat, monitorId } = maintenanceWindow;
- const startTime = dayjs(start);
- const endTime = dayjs(end);
- const durationInMs = endTime.diff(startTime, "milliseconds").toString();
- const { duration, durationUnit } = getDurationAndUnit(durationInMs);
- const monitor = monitors.find((monitor) => monitor._id === monitorId);
- setForm({
- ...form,
- name,
- repeat: REVERSE_REPEAT_LOOKUP[repeat],
- startDate: startTime,
- startTime,
- duration,
- durationUnit,
- monitors: monitor ? [monitor] : [],
- });
- } catch (error) {
- createToast({ body: "Failed to fetch data" });
- logger.error("Failed to fetch monitors", error);
- } finally {
- setIsLoading(false);
- }
- };
- fetchMonitors();
- }, [authToken, user]);
+ const res = await networkService.getMaintenanceWindowById({
+ authToken: authToken,
+ maintenanceWindowId: maintenanceWindowId,
+ });
+ const maintenanceWindow = res.data.data;
+ const { name, start, end, repeat, monitorId } = maintenanceWindow;
+ const startTime = dayjs(start);
+ const endTime = dayjs(end);
+ const durationInMs = endTime.diff(startTime, "milliseconds").toString();
+ const { duration, durationUnit } = getDurationAndUnit(durationInMs);
+ const monitor = monitors.find((monitor) => monitor._id === monitorId);
+ setForm({
+ ...form,
+ name,
+ repeat: REVERSE_REPEAT_LOOKUP[repeat],
+ startDate: startTime,
+ startTime,
+ duration,
+ durationUnit,
+ monitors: monitor ? [monitor] : [],
+ });
+ } catch (error) {
+ createToast({ body: "Failed to fetch data" });
+ logger.error("Failed to fetch monitors", error);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+ fetchMonitors();
+ }, [authToken, user]);
+
+ const buildErrors = (prev, id, error) => {
+ const updatedErrors = { ...prev };
+ if (error) {
+ updatedErrors[id] = error.details[0].message;
+ } else {
+ delete updatedErrors[id];
+ }
+ return updatedErrors;
+ };
const handleSearch = (value) => {
setSearch(value);
@@ -214,17 +223,29 @@ const CreateMaintenance = () => {
});
};
- const handleSubmit = async () => {
- if(hasValidationErrors(form, maintenanceWindowValidation, setErrors))
- return;
- // Build timestamp for maintenance window from startDate and startTime
- const start = dayjs(form.startDate)
- .set("hour", form.startTime.hour())
- .set("minute", form.startTime.minute());
- // Build end timestamp for maintenance window
- const MS_MULTIPLIER = MS_LOOKUP[form.durationUnit];
- const durationInMs = form.duration * MS_MULTIPLIER;
- const end = start.add(durationInMs);
+ const handleSubmit = async () => {
+ const { error } = maintenanceWindowValidation.validate(form, {
+ abortEarly: false,
+ });
+
+ // If errors, return early
+ if (error) {
+ const newErrors = {};
+ error.details.forEach((err) => {
+ newErrors[err.path[0]] = err.message;
+ });
+ setErrors(newErrors);
+ logger.error(error);
+ return;
+ }
+ // Build timestamp for maintenance window from startDate and startTime
+ const start = dayjs(form.startDate)
+ .set("hour", form.startTime.hour())
+ .set("minute", form.startTime.minute());
+ // Build end timestamp for maintenance window
+ const MS_MULTIPLIER = MS_LOOKUP[form.durationUnit];
+ const durationInMs = form.duration * MS_MULTIPLIER;
+ const end = start.add(durationInMs);
// Get repeat value in milliseconds
const repeat = REPEAT_LOOKUP[form.repeat];
diff --git a/Client/src/Validation/error.js b/Client/src/Validation/error.js
deleted file mode 100644
index e205ce7d1..000000000
--- a/Client/src/Validation/error.js
+++ /dev/null
@@ -1,25 +0,0 @@
-const buildErrors = (prev, id, error) => {
- const updatedErrors = { ...prev };
- if (error) {
- updatedErrors[id] = error.details[0].message?? "Validation error";
- } else {
- delete updatedErrors[id];
- }
- return updatedErrors;
-};
-
-const hasValidationErrors = (form, validation, setErrors) => {
- const { error } = validation.validate(form, {
- abortEarly: false,
- });
- if (error) {
- const newErrors = {};
- error.details.forEach((err) => {
- newErrors[err.path[0]] = err.message?? "Validation error";
- });
- setErrors(newErrors);
- return true;
- }
- return false;
-};
-export { buildErrors, hasValidationErrors };
diff --git a/Client/src/Validation/validation.js b/Client/src/Validation/validation.js
index a6ec7688c..c620bdf43 100644
--- a/Client/src/Validation/validation.js
+++ b/Client/src/Validation/validation.js
@@ -128,43 +128,10 @@ const maintenanceWindowValidation = joi.object({
monitors: joi.array().min(1),
});
-const advancedSettingsValidation = joi.object({
- apiBaseUrl: joi.string().uri({ allowRelative: true }).trim().messages({
- "string.empty": "API base url is required.",
- "string.uri": "The URL you provided is not valid.",
- }),
- logLevel: joi.string().valid("debug", "none", "error", "warn").allow(""),
- systemEmailHost: joi.string().allow(''),
- systemEmailPort: joi.string().allow(''),
- systemEmailAddress: joi
- .string().allow(''),
- systemEmailPassword: joi.string().allow(''),
- jwtTTL: joi
- .string()
- .trim()
- .messages({
- "string.empty": "JWT TTL is required."
- }),
- dbType: joi.string().trim().messages({
- "string.empty": "DB type is required",
- }),
- redisHost: joi.string().trim().messages({
- "string.empty": "Redis host is required",
- }),
- redisPort: joi.string().allow('').custom((value, helpers) => {
- if(value && isNaN(parseInt(value))){
- return helpers.message("Redit port must be a number")
- }
- return value
- }),
- pagespeedApiKey: joi.string().allow('')
-});
-
export {
credentials,
imageValidation,
monitorValidation,
settingsValidation,
maintenanceWindowValidation,
- advancedSettingsValidation,
};