Merge pull request #806 from bluewave-labs/feat/refactor-monitor-redux

Feat/refactor monitor redux
This commit is contained in:
Alexander Holliday authored and GitHub committed 2024-09-05 14:38:22 -07:00
commit 3dbbd93f01
11 files changed
+169 -53

No files matched your search

@@ -3,7 +3,7 @@ import { jwtDecode } from "jwt-decode";
import { networkService } from "../../main";
const initialState = {
isLoading: false,
monitors: [],
monitorsSummary: [],
success: null,
msg: null,
};
@@ -53,14 +53,10 @@ export const getPageSpeedByTeamId = createAsyncThunk(
async (token, thunkApi) => {
const user = jwtDecode(token);
try {
const res = await networkService.getMonitorsByTeamId(
const res = await networkService.getMonitorsAndSummaryByTeamId(
token,
user.teamId,
25,
["pagespeed"],
null,
"desc",
false
["pagespeed"]
);
return res.data;
@@ -155,7 +151,7 @@ const pageSpeedMonitorSlice = createSlice({
reducers: {
clearMonitorState: (state) => {
state.isLoading = false;
state.monitors = [];
state.monitorsSummary = [];
state.success = null;
state.msg = null;
},
@@ -172,7 +168,7 @@ const pageSpeedMonitorSlice = createSlice({
.addCase(getPageSpeedByTeamId.fulfilled, (state, action) => {
state.isLoading = false;
state.success = action.payload.msg;
state.monitors = action.payload.data;
state.monitorsSummary = action.payload.data;
})
.addCase(getPageSpeedByTeamId.rejected, (state, action) => {
state.isLoading = false;
@@ -3,7 +3,7 @@ import { jwtDecode } from "jwt-decode";
import { networkService } from "../../main";
const initialState = {
isLoading: false,
monitors: [],
monitorsSummary: [],
success: null,
msg: null,
};
@@ -53,14 +53,10 @@ export const getUptimeMonitorsByTeamId = createAsyncThunk(
async (token, thunkApi) => {
const user = jwtDecode(token);
try {
const res = await networkService.getMonitorsByTeamId(
const res = await networkService.getMonitorsAndSummaryByTeamId(
token,
user.teamId,
25,
["http", "ping"],
null,
"desc",
true
["http", "ping"]
);
return res.data;
} catch (error) {
@@ -175,7 +171,7 @@ const uptimeMonitorsSlice = createSlice({
reducers: {
clearUptimeMonitorState: (state) => {
state.isLoading = false;
state.monitors = [];
state.monitorsSummary = [];
state.success = null;
state.msg = null;
},
@@ -192,7 +188,7 @@ const uptimeMonitorsSlice = createSlice({
.addCase(getUptimeMonitorsByTeamId.fulfilled, (state, action) => {
state.isLoading = false;
state.success = action.payload.msg;
state.monitors = action.payload.data;
state.monitorsSummary = action.payload.data;
})
.addCase(getUptimeMonitorsByTeamId.rejected, (state, action) => {
state.isLoading = false;
+24 -24
View File
@@ -23,23 +23,9 @@ const Monitors = ({ isAdmin }) => {
useEffect(() => {
dispatch(getUptimeMonitorsByTeamId(authState.authToken));
}, [authState.authToken, dispatch]);
const monitorStats = monitorState?.monitors?.monitors?.reduce(
(acc, monitor) => {
if (monitor.isActive === false) {
acc["paused"] += 1;
} else if (monitor.status === true) {
acc["up"] += 1;
} else {
acc["down"] += 1;
}
return acc;
},
{ paused: 0, up: 0, down: 0 }
);
let loading = monitorState.isLoading && monitorState.monitors.length === 0;
let loading =
monitorState?.isLoading &&
monitorState?.monitorsSummary?.monitors?.length === 0;
return (
<Stack className="monitors" gap={theme.spacing(8)}>
{loading ? (
@@ -55,7 +41,7 @@ const Monitors = ({ isAdmin }) => {
mt={theme.spacing(5)}
>
<Greeting type="uptime" />
{monitorState.monitors?.length !== 0 && (
{monitorState?.monitorsSummary?.monitors?.length !== 0 && (
<Button
variant="contained"
color="primary"
@@ -69,20 +55,33 @@ const Monitors = ({ isAdmin }) => {
)}
</Stack>
</Box>
{isAdmin && monitorState.monitors?.length === 0 && (
{isAdmin && monitorState?.monitorsSummary?.monitors?.length === 0 && (
<Fallback isAdmin={isAdmin} />
)}
{monitorState.monitors?.length !== 0 && (
{monitorState?.monitorsSummary?.monitors?.length !== 0 && (
<>
<Stack
gap={theme.spacing(8)}
direction="row"
justifyContent="space-between"
>
<StatusBox title="up" value={monitorStats.up} />
<StatusBox title="down" value={monitorStats.down} />
<StatusBox title="paused" value={monitorStats.paused} />
<StatusBox
title="up"
value={monitorState?.monitorsSummary?.monitorCounts?.up ?? 0}
/>
<StatusBox
title="down"
value={
monitorState?.monitorsSummary?.monitorCounts?.down ?? 0
}
/>
<StatusBox
title="paused"
value={
monitorState?.monitorsSummary?.monitorCounts?.paused ?? 0
}
/>
</Stack>
<Box
flex={1}
@@ -111,7 +110,8 @@ const Monitors = ({ isAdmin }) => {
borderColor={theme.palette.border.light}
backgroundColor={theme.palette.background.accent}
>
{monitorState.monitors.monitors.length}
{monitorState?.monitorsSummary.monitors?.monitors?.length ||
0}
</Box>
{/* TODO - add search bar */}
</Stack>
@@ -217,7 +217,6 @@ const PageSpeedDetails = () => {
null,
null
);
console.log(res.data.data);
setMonitor(res?.data?.data ?? {});
setAudits(res?.data?.data?.checks?.[0]?.audits ?? []);
} catch (error) {
+5 -5
View File
@@ -18,7 +18,7 @@ const PageSpeed = ({ isAdmin }) => {
const navigate = useNavigate();
const { authToken } = useSelector((state) => state.auth);
const { monitors, isLoading } = useSelector(
const { monitorsSummary, isLoading } = useSelector(
(state) => state.pageSpeedMonitors
);
useEffect(() => {
@@ -27,7 +27,7 @@ const PageSpeed = ({ isAdmin }) => {
// will show skeletons only on initial load
// since monitor state is being added to redux persist, there's no reason to display skeletons on every render
let isActuallyLoading = isLoading && monitors?.monitors.length === 0;
let isActuallyLoading = isLoading && monitorsSummary?.monitors?.length === 0;
return (
<Box
@@ -46,7 +46,7 @@ const PageSpeed = ({ isAdmin }) => {
>
{isActuallyLoading ? (
<SkeletonLayout />
) : monitors?.monitors?.length !== 0 ? (
) : monitorsSummary?.monitors?.length !== 0 ? (
<Box
sx={{
"& p": {
@@ -73,8 +73,8 @@ const PageSpeed = ({ isAdmin }) => {
</Stack>
</Box>
<Grid container spacing={theme.spacing(12)}>
{monitors?.monitors?.map((monitor) => (
<Card data={monitor} key={`monitor-${monitor._id}`} />
{monitorsSummary?.monitors?.map((monitor) => (
<Card data={monitor} key={monitor._id} />
))}
</Grid>
</Box>
+20 -1
View File
@@ -58,9 +58,28 @@ class NetworkService {
});
}
async getMonitorsAndSummaryByTeamId(authToken, teamId, types) {
const params = new URLSearchParams();
if (types) {
types.forEach((type) => {
params.append("type", type);
});
}
return this.axiosInstance.get(
`/monitors/team/summary/${teamId}?${params.toString()}`,
{
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
},
}
);
}
/**
* ************************************
* Get all uptime monitors for a user
* Get all uptime monitors for a Team
* ************************************
*
* @async
+51 -2
View File
@@ -4,6 +4,8 @@ const {
getMonitorsByTeamIdValidation,
createMonitorBodyValidation,
editMonitorBodyValidation,
getMonitorsAndSummaryByTeamIdParamValidation,
getMonitorsAndSummaryByTeamIdQueryValidation,
getMonitorsByTeamIdQueryValidation,
pauseMonitorParamValidation,
getMonitorStatsByIdParamValidation,
@@ -16,7 +18,6 @@ const {
const sslChecker = require("ssl-checker");
const SERVICE_NAME = "monitorController";
const { errorMessages, successMessages } = require("../utils/messages");
/**
* Returns all monitors
* @async
@@ -186,7 +187,54 @@ const getMonitorById = async (req, res, next) => {
};
/**
* Returns all monitors belong to User with UserID
* Returns all monitors and a sumamry for a team with TeamID
* @async
* @param {Express.Request} req
* @param {Express.Response} res
* @returns {Promise<Express.Response>}
* @throws {Error}
*/
const getMonitorsAndSummaryByTeamId = async (req, res, next) => {
try {
await getMonitorsAndSummaryByTeamIdParamValidation.validateAsync(
req.params
);
await getMonitorsAndSummaryByTeamIdQueryValidation.validateAsync(req.query);
//validation
} catch (error) {
error.status = 422;
error.service = SERVICE_NAME;
error.method === undefined &&
error.method === "getMonitorsAndSummaryByTeamId";
error.message =
error.details?.[0]?.message || error.message || "Validation Error";
next(error);
return;
}
try {
const { teamId } = req.params;
const { type } = req.query;
const monitorsSummary = await req.db.getMonitorsAndSummaryByTeamId(
teamId,
type
);
return res.status(200).json({
success: true,
msg: successMessages.MONITOR_GET_BY_USER_ID(teamId),
data: monitorsSummary,
});
} catch (error) {
error.service = SERVICE_NAME;
error.method === undefined &&
error.method === "getMonitorsAndSummaryByTeamId";
next(error);
}
};
/**
* Returns all monitors belong to team with TeamID
* @async
* @param {Express.Request} req
* @param {Express.Response} res
@@ -424,6 +472,7 @@ module.exports = {
getMonitorStatsById,
getMonitorCertificate,
getMonitorById,
getMonitorsAndSummaryByTeamId,
getMonitorsByTeamId,
createMonitor,
deleteMonitor,
+2 -2
View File
@@ -64,10 +64,9 @@ const {
const {
getAllMonitors,
getMonitorAggregateStats,
testMethod,
getMonitorStatsById,
getMonitorById,
getMonitorsAndSummaryByTeamId,
getMonitorsByTeamId,
createMonitor,
deleteMonitor,
@@ -148,6 +147,7 @@ module.exports = {
getAllMonitors,
getMonitorStatsById,
getMonitorById,
getMonitorsAndSummaryByTeamId,
getMonitorsByTeamId,
createMonitor,
deleteMonitor,
+38
View File
@@ -292,6 +292,43 @@ const getMonitorById = async (monitorId) => {
}
};
/**
* Get monitors and Summary by TeamID
* @async
* @param {Express.Request} req
* @param {Express.Response} res
* @returns {Promise<Array<Monitor>>}
* @throws {Error}
*/
const getMonitorsAndSummaryByTeamId = async (teamId, type) => {
try {
const monitors = await Monitor.find({ teamId, type });
const monitorCounts = monitors.reduce(
(acc, monitor) => {
if (monitor.status === true) {
acc.up += 1;
}
if (monitor.status === false) {
acc.down += 1;
}
if (monitor.isActive === false) {
acc.paused += 1;
}
return acc;
},
{ up: 0, down: 0, paused: 0 }
);
monitorCounts.total = monitors.length;
return { monitors, monitorCounts };
} catch (error) {
error.method = "getMonitorsAndSummaryByTeamId";
throw error;
}
};
/**
* Get monitors by TeamID
* @async
@@ -464,6 +501,7 @@ module.exports = {
getAllMonitors,
getMonitorStatsById,
getMonitorById,
getMonitorsAndSummaryByTeamId,
getMonitorsByTeamId,
createMonitor,
deleteMonitor,
+4
View File
@@ -7,6 +7,10 @@ router.get("/aggregate/:monitorId", monitorController.getMonitorAggregateStats);
router.get("/stats/:monitorId", monitorController.getMonitorStatsById);
router.get("/certificate/:monitorId", monitorController.getMonitorCertificate);
router.get("/:monitorId", monitorController.getMonitorById);
router.get(
"/team/summary/:teamId",
monitorController.getMonitorsAndSummaryByTeamId
);
router.get("/team/:teamId", monitorController.getMonitorsByTeamId);
router.post(
+15
View File
@@ -161,6 +161,19 @@ const getMonitorByIdQueryValidation = joi.object({
normalize: joi.boolean(),
});
const getMonitorsAndSummaryByTeamIdParamValidation = joi.object({
teamId: joi.string().required(),
});
const getMonitorsAndSummaryByTeamIdQueryValidation = joi.object({
type: joi
.alternatives()
.try(
joi.string().valid("http", "ping", "pagespeed"),
joi.array().items(joi.string().valid("http", "ping", "pagespeed"))
),
});
const getMonitorsByTeamIdValidation = joi.object({
teamId: joi.string().required(),
});
@@ -381,6 +394,8 @@ module.exports = {
createMonitorBodyValidation,
getMonitorByIdParamValidation,
getMonitorByIdQueryValidation,
getMonitorsAndSummaryByTeamIdParamValidation,
getMonitorsAndSummaryByTeamIdQueryValidation,
getMonitorsByTeamIdValidation,
getMonitorsByTeamIdQueryValidation,
getMonitorStatsByIdParamValidation,