diff --git a/Client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js b/Client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js index ac3ce1d6f..a8b1ea737 100644 --- a/Client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js +++ b/Client/src/Features/UptimeMonitors/uptimeMonitorsSlice.js @@ -164,6 +164,44 @@ export const deleteMonitorChecksByTeamId = createAsyncThunk( } } ); +export const addDemoMonitors = createAsyncThunk( + "monitors/addDemoMonitors", + async (data, thunkApi) => { + try { + const { authToken } = data; + const res = await networkService.addDemoMonitors(authToken); + return res.data; + } catch (error) { + if (error.response && error.response.data) { + return thunkApi.rejectWithValue(error.response.data); + } + const payload = { + status: false, + msg: error.message ? error.message : "Unknown error", + }; + return thunkApi.rejectWithValue(payload); + } + } +); +export const deleteAllMonitors = createAsyncThunk( + "monitors/deleteAllMonitors", + async (data, thunkApi) => { + try { + const { authToken } = data; + const res = await networkService.deleteAllMonitors(authToken); + return res.data; + } catch (error) { + if (error.response && error.response.data) { + return thunkApi.rejectWithValue(error.response.data); + } + const payload = { + status: false, + msg: error.message ? error.message : "Unknown error", + }; + return thunkApi.rejectWithValue(payload); + } + } +); const uptimeMonitorsSlice = createSlice({ name: "uptimeMonitors", @@ -306,6 +344,42 @@ const uptimeMonitorsSlice = createSlice({ state.msg = action.payload ? action.payload.msg : "Failed to pause uptime monitor"; + }) + // ***************************************************** + // Add Demo Monitors + // ***************************************************** + .addCase(addDemoMonitors.pending, (state) => { + state.isLoading = true; + }) + .addCase(addDemoMonitors.fulfilled, (state, action) => { + state.isLoading = false; + state.success = action.payload.success; + state.msg = action.payload.msg; + }) + .addCase(addDemoMonitors.rejected, (state, action) => { + state.isLoading = false; + state.success = false; + state.msg = action.payload + ? action.payload.msg + : "Failed to add demo uptime monitors"; + }) + // ***************************************************** + // Delete all Monitors + // ***************************************************** + .addCase(deleteAllMonitors.pending, (state) => { + state.isLoading = true; + }) + .addCase(deleteAllMonitors.fulfilled, (state, action) => { + state.isLoading = false; + state.success = action.payload.success; + state.msg = action.payload.msg; + }) + .addCase(deleteAllMonitors.rejected, (state, action) => { + state.isLoading = false; + state.success = false; + state.msg = action.payload + ? action.payload.msg + : "Failed to delete all monitors"; }); }, }); diff --git a/Client/src/Pages/Settings/index.jsx b/Client/src/Pages/Settings/index.jsx index 5f27abe26..cd00f440f 100644 --- a/Client/src/Pages/Settings/index.jsx +++ b/Client/src/Pages/Settings/index.jsx @@ -7,7 +7,11 @@ import { logger } from "../../Utils/Logger"; import "./index.css"; import { useDispatch, useSelector } from "react-redux"; import { createToast } from "../../Utils/toastUtils"; -import { deleteMonitorChecksByTeamId } from "../../Features/UptimeMonitors/uptimeMonitorsSlice"; +import { + deleteMonitorChecksByTeamId, + addDemoMonitors, + deleteAllMonitors, +} from "../../Features/UptimeMonitors/uptimeMonitorsSlice"; import PropTypes from "prop-types"; import LoadingButton from "@mui/lab/LoadingButton"; const Settings = ({ isAdmin }) => { @@ -36,8 +40,32 @@ const Settings = ({ isAdmin }) => { } }; - const addDemoMonitors = () => { - logger.warn("Click"); + const handleInsertDemoMonitors = async () => { + try { + const action = await dispatch(addDemoMonitors({ authToken })); + if (addDemoMonitors.fulfilled.match(action)) { + createToast({ body: "Successfully added demo monitors" }); + } else { + createToast({ body: "Failed to add demo monitors" }); + } + } catch (error) { + logger.error(error); + createToast({ Body: "Failed to add demo monitors" }); + } + }; + + const handleDeleteAllMonitors = async () => { + try { + const action = await dispatch(deleteAllMonitors({ authToken })); + if (deleteAllMonitors.fulfilled.match(action)) { + createToast({ body: "Successfully deleted all monitors" }); + } else { + createToast({ body: "Failed to add demo monitors" }); + } + } catch (error) { + logger.error(error); + createToast({ Body: "Failed to delete all monitors" }); + } }; const ConfigBox = styled("div")({ @@ -159,7 +187,7 @@ const Settings = ({ isAdmin }) => { variant="contained" color="primary" loading={isLoading} - onClick={addDemoMonitors} + onClick={handleInsertDemoMonitors} sx={{ mt: theme.spacing(4) }} > Add demo monitors @@ -169,9 +197,9 @@ const Settings = ({ isAdmin }) => { Remove all monitors {}} + onClick={handleDeleteAllMonitors} sx={{ mt: theme.spacing(4) }} > Remove all monitors diff --git a/Client/src/Utils/NetworkService.js b/Client/src/Utils/NetworkService.js index e4b7be526..a9d93b301 100644 --- a/Client/src/Utils/NetworkService.js +++ b/Client/src/Utils/NetworkService.js @@ -274,6 +274,46 @@ class NetworkService { ); } + /** + * ************************************ + * Adds demo monitors + * ************************************ + * + * @async + * @param {string} authToken - The authorization token to be used in the request header. + * @returns {Promise} The response from the axios POST request. + */ + async addDemoMonitors(authToken) { + return this.axiosInstance.post( + `/monitors/demo`, + {}, + { + headers: { + Authorization: `Bearer ${authToken}`, + "Content-Type": "application/json", + }, + } + ); + } + + /** + * ************************************ + * Deletes all monitors for a team by team ID + * ************************************ + * + * @async + * @param {string} authToken - The authorization token to be used in the request header. + * @returns {Promise} The response from the axios DELETE request. + */ + async deleteAllMonitors(authToken) { + return this.axiosInstance.delete(`/monitors/`, { + headers: { + Authorization: `Bearer ${authToken}`, + "Content-Type": "application/json", + }, + }); + } + /** * ************************************ * Gets the certificate expiry for a monitor diff --git a/Server/controllers/monitorController.js b/Server/controllers/monitorController.js index 27f306178..c40135cdb 100644 --- a/Server/controllers/monitorController.js +++ b/Server/controllers/monitorController.js @@ -368,6 +368,7 @@ const deleteMonitor = async (req, res, next) => { const deleteAllMonitors = async (req, res) => { try { + console.log("WTF"); const token = getTokenFromHeaders(req.headers); const { teamId } = jwt.verify(token, process.env.JWT_SECRET); const { monitors, deletedCount } = await req.db.deleteAllMonitors(teamId); @@ -384,6 +385,7 @@ const deleteAllMonitors = async (req, res) => { .json({ success: true, msg: `Deleted ${deletedCount} monitors` }); } catch (error) { error.service = SERVICE_NAME; + error.method === undefined && error.method === "deleteAllMonitors"; next(error); } };