Merge branch 'bluewave-labs:master' into backend-completion
This commit is contained in:
18 files changed
+80
-120
No files matched your search
@@ -1,38 +0,0 @@
|
||||
import SearchTextField from "../TextFields/Search/SearchTextField";
|
||||
import "./index.css";
|
||||
import HostsTable from "../HostsTable";
|
||||
import Pagination from "../Pagination";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
/**
|
||||
* CurrentMonitors displays the current status of monitor
|
||||
*
|
||||
* @component
|
||||
* @param {Array<Monitor>} monitors - An array of monitor objects to be displayed.
|
||||
*/
|
||||
|
||||
const CurrentMonitors = ({ monitors }) => {
|
||||
return (
|
||||
<div className="current-monitors">
|
||||
<div className="current-monitors-bar">
|
||||
<div className="current-monitors-title-holder">
|
||||
<div className="current-monitors-title">Current monitors</div>
|
||||
<div className="current-monitors-counter">{monitors.length}</div>
|
||||
</div>
|
||||
<div className="current-monitors-search-bar">
|
||||
<SearchTextField />
|
||||
</div>
|
||||
</div>
|
||||
<div className="monitors-v-gaping"></div>
|
||||
<HostsTable monitors={monitors} />
|
||||
<div className="monitors-v-gaping"></div>
|
||||
<Pagination />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
CurrentMonitors.propTypes = {
|
||||
monitors: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
};
|
||||
|
||||
export default CurrentMonitors;
|
||||
@@ -1,6 +1,7 @@
|
||||
import TabPanel from "@mui/lab/TabPanel";
|
||||
import React, { useState } from "react";
|
||||
import AnnouncementsDualButtonWithIcon from "../../Announcements/AnnouncementsDualButtonWithIcon/AnnouncementsDualButtonWithIcon";
|
||||
// import AnnouncementsDualButtonWithIcon from "../../Announcements/AnnouncementsDualButtonWithIcon/AnnouncementsDualButtonWithIcon";
|
||||
import AnnouncementsDualButtonWithIcon from "../../Toast/AnnouncementsDualButtonWithIcon/AnnouncementsDualButtonWithIcon";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { Box, Divider, Stack, Typography } from "@mui/material";
|
||||
import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined";
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,6 +1,6 @@
|
||||
import PropTypes from "prop-types";
|
||||
import ComplexAlert from "../../Components/Icons/ComplexAlert/ComplexAlert";
|
||||
import AnnouncementsDualButtonWithIcon from "../../Components/Announcements/AnnouncementsDualButtonWithIcon/AnnouncementsDualButtonWithIcon";
|
||||
import AnnouncementsDualButtonWithIcon from "./AnnouncementsDualButtonWithIcon/AnnouncementsDualButtonWithIcon";
|
||||
import "react-toastify/dist/ReactToastify.css";
|
||||
import { toast, ToastContainer } from "react-toastify";
|
||||
import "./index.css";
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
import Button from "../../Components/Button";
|
||||
import ServerStatus from "../../Components/Charts/Servers/ServerStatus";
|
||||
import CurrentMonitors from "../../Components/CurrentMonitors";
|
||||
import PropTypes from "prop-types";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
/**
|
||||
* CurrentStats displays the current status of monitor
|
||||
*
|
||||
* @component
|
||||
* @param {Array<Monitor>} monitors - An array of monitor objects to be displayed.
|
||||
*/
|
||||
|
||||
const CurrentStats = ({ monitors }) => {
|
||||
const navigate = useNavigate();
|
||||
const authState = useSelector((state) => state.auth);
|
||||
const up = monitors.reduce((acc, cur) => {
|
||||
if (cur.checks.length > 0) {
|
||||
return cur.checks[cur.checks.length - 1].status === true ? acc + 1 : acc;
|
||||
}
|
||||
return 0;
|
||||
}, 0);
|
||||
|
||||
const down = monitors.reduce((acc, cur) => {
|
||||
if (cur.checks.length > 0) {
|
||||
return cur.checks[cur.checks.length - 1].status === false ? acc + 1 : acc;
|
||||
}
|
||||
return 0;
|
||||
}, 0);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="monitors-gaps-medium"></div>
|
||||
<div className="monitors-gaps-medium"></div>
|
||||
<div className="monitors-bar">
|
||||
<div className="monitors-bar-title">
|
||||
Hello, {authState.user.firstname}
|
||||
</div>
|
||||
<Button
|
||||
level="primary"
|
||||
label="Create new monitor"
|
||||
onClick={() => {
|
||||
navigate("/monitors/create");
|
||||
}}
|
||||
sx={{ padding: "10px 20px", fontSize: "13px" }}
|
||||
/>
|
||||
</div>
|
||||
<div className="monitors-gaps-medium"></div>
|
||||
<div className="monitors-stats">
|
||||
<ServerStatus title="Up" value={up} state="up" />
|
||||
<ServerStatus title="Down" value={down} state="down" />
|
||||
<ServerStatus title="Paused" value={0} state="pause" />
|
||||
</div>
|
||||
<div className="monitors-gaps-medium"></div>
|
||||
<CurrentMonitors monitors={monitors} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
CurrentStats.propTypes = {
|
||||
monitors: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
};
|
||||
|
||||
export default CurrentStats;
|
||||
@@ -9,6 +9,7 @@
|
||||
}
|
||||
|
||||
.monitors-bar {
|
||||
margin-top: calc(2 * var(--env-var-spacing-2));
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
@@ -20,6 +21,7 @@
|
||||
}
|
||||
|
||||
.monitors-stats {
|
||||
margin-top: var(--env-var-spacing-2);
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,69 @@
|
||||
import CurrentStats from "./CurrentStats";
|
||||
import "./index.css";
|
||||
import "./monitors.css";
|
||||
import { useEffect } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { getMonitorsByUserId } from "../../Features/Monitors/monitorsSlice";
|
||||
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Button from "../../Components/Button";
|
||||
import ServerStatus from "../../Components/Charts/Servers/ServerStatus";
|
||||
import SearchTextField from "../../Components/TextFields/Search/SearchTextField";
|
||||
import HostsTable from "../../Components/HostsTable";
|
||||
import Pagination from "../../Components/Pagination";
|
||||
const Monitors = () => {
|
||||
const navigate = useNavigate();
|
||||
const monitorState = useSelector((state) => state.monitors);
|
||||
const authstate = useSelector((state) => state.auth);
|
||||
const authState = useSelector((state) => state.auth);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(getMonitorsByUserId(authstate.authToken));
|
||||
dispatch(getMonitorsByUserId(authState.authToken));
|
||||
}, []);
|
||||
|
||||
const up = monitorState.monitors.reduce((acc, cur) => {
|
||||
return cur.status === true ? acc + 1 : acc;
|
||||
}, 0);
|
||||
|
||||
const down = monitorState.monitors.length - up;
|
||||
|
||||
return (
|
||||
<div className="monitors">
|
||||
<CurrentStats monitors={monitorState.monitors} />
|
||||
<div className="monitors-bar">
|
||||
<div className="monitors-bar-title">
|
||||
Hello, {authState.user.firstname}
|
||||
</div>
|
||||
<Button
|
||||
level="primary"
|
||||
label="Create new monitor"
|
||||
onClick={() => {
|
||||
navigate("/monitors/create");
|
||||
}}
|
||||
sx={{ padding: "10px 20px", fontSize: "13px" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="monitors-stats">
|
||||
<ServerStatus title="Up" value={up} state="up" />
|
||||
<ServerStatus title="Down" value={down} state="down" />
|
||||
<ServerStatus title="Paused" value={0} state="pause" />
|
||||
</div>
|
||||
|
||||
<div className="current-monitors">
|
||||
<div className="current-monitors-bar">
|
||||
<div className="current-monitors-title-holder">
|
||||
<div className="current-monitors-title">Current monitors</div>
|
||||
<div className="current-monitors-counter">
|
||||
{monitorState.monitors.length}
|
||||
</div>
|
||||
</div>
|
||||
<div className="current-monitors-search-bar">
|
||||
<SearchTextField />
|
||||
</div>
|
||||
</div>
|
||||
<div className="monitors-v-gaping"></div>
|
||||
<HostsTable monitors={monitorState.monitors} />
|
||||
<div className="monitors-v-gaping"></div>
|
||||
<Pagination />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
+1
@@ -1,4 +1,5 @@
|
||||
.current-monitors {
|
||||
margin-top: var(--env-var-spacing-2);
|
||||
border: 1px solid #eaecf0;
|
||||
padding: 40px;
|
||||
border-radius: 4px;
|
||||
@@ -4,12 +4,12 @@ import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline";
|
||||
import HelpOutlineIcon from "@mui/icons-material/HelpOutline";
|
||||
import WebsiteTextField from "../../Components/TextFields/Website/WebsiteTextField";
|
||||
import DescriptionTextField from "../../Components/TextFields/Description/DescriptionTextField";
|
||||
import AnnouncementsDualButton from "../../Components/Announcements/AnnouncementsDualButton/AnnouncementsDualButton";
|
||||
import AnnouncementsDualButtonWithIcon from "../../Components/Announcements/AnnouncementsDualButtonWithIcon/AnnouncementsDualButtonWithIcon";
|
||||
import AnnouncementsDualButton from "../../Components/Toast/AnnouncementsDualButton/AnnouncementsDualButton";
|
||||
import AnnouncementsDualButtonWithIcon from "../../Components/Toast/AnnouncementsDualButtonWithIcon/AnnouncementsDualButtonWithIcon";
|
||||
import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined";
|
||||
import ComplexAlert from "../../Components/Icons/ComplexAlert/ComplexAlert";
|
||||
import AnnouncementsMessageBar from "../../Components/Announcements/AnnouncementsMessageBar/AnnouncementsMessageBar";
|
||||
import AnnouncementUpdateSubscription from "../../Components/Announcements/AnnouncementUpdateSubscription/AnnouncementUpdateSubscription";
|
||||
import AnnouncementsMessageBar from "../../Components/Toast/AnnouncementsMessageBar/AnnouncementsMessageBar";
|
||||
import AnnouncementUpdateSubscription from "../../Components/Toast/AnnouncementUpdateSubscription/AnnouncementUpdateSubscription";
|
||||
import PlayGroundCharts from "./PlayGround-Charts";
|
||||
import PlayGroundPopupModals from "./PlayGround-Popup-Modals";
|
||||
import PlayGroundTooltips from "./PlayGround-Tooltips";
|
||||
|
||||
@@ -214,6 +214,10 @@ const editMonitor = async (req, res, next) => {
|
||||
|
||||
try {
|
||||
const editedMonitor = await req.db.editMonitor(req, res);
|
||||
// Delete the old job(editedMonitor has the same ID as the old monitor)
|
||||
await req.jobQueue.deleteJob(editedMonitor);
|
||||
// Add the new job back to the queue
|
||||
await req.jobQueue.addJob(editedMonitor._id, editedMonitor);
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
msg: successMessages.MONITOR_EDIT,
|
||||
|
||||
+12
-4
@@ -42,7 +42,9 @@ const insertUser = async (req, res) => {
|
||||
}
|
||||
const newUser = new UserModel(userData);
|
||||
await newUser.save();
|
||||
return await UserModel.findOne({ _id: newUser._id }).select("-password"); // .select() doesn't work with create, need to save then find
|
||||
return await UserModel.findOne({ _id: newUser._id })
|
||||
.select("-password")
|
||||
.select("-profileImage"); // .select() doesn't work with create, need to save then find
|
||||
} catch (error) {
|
||||
if (error.code === DUPLICATE_KEY_CODE) {
|
||||
throw new Error(errorMessages.DB_USER_EXISTS);
|
||||
@@ -66,7 +68,9 @@ const getUserByEmail = async (req, res) => {
|
||||
try {
|
||||
// Need the password to be able to compare, removed .select()
|
||||
// We can strip the hash before returing the user
|
||||
const user = await UserModel.findOne({ email: req.body.email });
|
||||
const user = await UserModel.findOne(
|
||||
{ email: req.body.email }.select("-profileImage")
|
||||
);
|
||||
if (user) {
|
||||
return user;
|
||||
} else {
|
||||
@@ -102,7 +106,9 @@ const updateUser = async (req, res) => {
|
||||
candidateUserId,
|
||||
candidateUser,
|
||||
{ new: true } // Returns updated user instead of pre-update user
|
||||
).select("-password");
|
||||
)
|
||||
.select("-password")
|
||||
.select("-profileImage");
|
||||
return updatedUser;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
@@ -190,7 +196,9 @@ const resetPassword = async (req, res) => {
|
||||
// Fetch the user again without the password
|
||||
const userWithoutPassword = await UserModel.findOne({
|
||||
email: recoveryToken.email,
|
||||
}).select("-password");
|
||||
})
|
||||
.select("-password")
|
||||
.select("-profileImage");
|
||||
return userWithoutPassword;
|
||||
} else {
|
||||
throw new Error(errorMessages.DB_USER_NOT_FOUND);
|
||||
|
||||
Reference in new issue
Block a user