diff --git a/Client/src/Features/UI/uiSlice.js b/Client/src/Features/UI/uiSlice.js
index 2b6a08e8d..a70c31041 100644
--- a/Client/src/Features/UI/uiSlice.js
+++ b/Client/src/Features/UI/uiSlice.js
@@ -9,6 +9,9 @@ const initialState = {
team: {
rowsPerPage: 5,
},
+ maintenance: {
+ rowsPerPage: 5,
+ },
sidebar: {
collapsed: false,
},
diff --git a/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx b/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx
index 057df1c74..48b1cbc07 100644
--- a/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx
+++ b/Client/src/Pages/Maintenance/CreateMaintenance/index.jsx
@@ -190,6 +190,7 @@ const CreateMaintenance = () => {
repeat,
};
+ console.log(submit);
if (repeat === 0) {
submit.expiry = end;
}
diff --git a/Client/src/Pages/Maintenance/MaintenanceTable/ActionsMenu/index.jsx b/Client/src/Pages/Maintenance/MaintenanceTable/ActionsMenu/index.jsx
new file mode 100644
index 000000000..22f864c51
--- /dev/null
+++ b/Client/src/Pages/Maintenance/MaintenanceTable/ActionsMenu/index.jsx
@@ -0,0 +1,182 @@
+import { useState } from "react";
+import { useTheme } from "@emotion/react";
+import { useNavigate } from "react-router-dom";
+import {
+ Button,
+ IconButton,
+ Menu,
+ MenuItem,
+ Modal,
+ Stack,
+ Typography,
+} from "@mui/material";
+import Settings from "../../../../assets/icons/settings-bold.svg?react";
+import PropTypes from "prop-types";
+
+const ActionsMenu = ({ isAdmin, maintenanceWindow }) => {
+ const [anchorEl, setAnchorEl] = useState(null);
+ const [isOpen, setIsOpen] = useState(false);
+ const theme = useTheme();
+
+ const handleRemove = async (event) => {
+ event.preventDefault();
+ event.stopPropagation();
+ console.log("remove");
+ setIsOpen(false); // close modal
+ };
+
+ const openMenu = (event) => {
+ event.preventDefault();
+ event.stopPropagation();
+ setAnchorEl(event.currentTarget);
+ };
+
+ const openRemove = (e) => {
+ closeMenu(e);
+ setIsOpen(true);
+ };
+
+ const closeMenu = (e) => {
+ e.stopPropagation();
+ setAnchorEl(null);
+ };
+
+ const navigate = useNavigate();
+
+ return (
+ <>
+ {
+ event.stopPropagation();
+ openMenu(event);
+ }}
+ sx={{
+ "&:focus": {
+ outline: "none",
+ },
+ "& svg path": {
+ stroke: theme.palette.other.icon,
+ },
+ }}
+ >
+
+
+
+
+ {
+ e.stopPropagation();
+ setIsOpen(false);
+ }}
+ >
+
+
+ Do you really want to remove this maintenance window?
+
+
+
+
+
+
+
+ >
+ );
+};
+
+ActionsMenu.propTypes = {
+ maintenanceWindow: PropTypes.object,
+ isAdmin: PropTypes.bool,
+ updateCallback: PropTypes.func,
+};
+
+export default ActionsMenu;
diff --git a/Client/src/Pages/Maintenance/MaintenanceTable/index.jsx b/Client/src/Pages/Maintenance/MaintenanceTable/index.jsx
index 29c651add..6cccfa06a 100644
--- a/Client/src/Pages/Maintenance/MaintenanceTable/index.jsx
+++ b/Client/src/Pages/Maintenance/MaintenanceTable/index.jsx
@@ -15,16 +15,18 @@ import {
} from "@mui/material";
import ArrowDownwardRoundedIcon from "@mui/icons-material/ArrowDownwardRounded";
import ArrowUpwardRoundedIcon from "@mui/icons-material/ArrowUpwardRounded";
-
+import ActionsMenu from "./ActionsMenu";
import { useState, useEffect, memo, useCallback, useRef } from "react";
-import { useDispatch } from "react-redux";
+import { useDispatch, useSelector } from "react-redux";
import { useTheme } from "@emotion/react";
import LeftArrowDouble from "../../../assets/icons/left-arrow-double.svg?react";
import RightArrowDouble from "../../../assets/icons/right-arrow-double.svg?react";
import LeftArrow from "../../../assets/icons/left-arrow.svg?react";
import RightArrow from "../../../assets/icons/right-arrow.svg?react";
import SelectorVertical from "../../../assets/icons/selector-vertical.svg?react";
-// import ActionsMenu from "../actionsMenu";
+import { formatDurationRounded } from "../../../Utils/timeUtils";
+import { StatusLabel } from "../../../Components/Label";
+import { setRowsPerPage } from "../../../Features/UI/uiSlice";
/**
* Component for pagination actions (first, previous, next, last).
@@ -101,16 +103,15 @@ TablePaginationActions.propTypes = {
const MaintenanceTable = ({
page,
setPage,
- rowsPerPage,
- setRowsPerPage,
sort,
setSort,
maintenanceWindows,
maintenanceWindowCount,
}) => {
+ const { rowsPerPage } = useSelector((state) => state.ui.maintenance);
+
const theme = useTheme();
const dispatch = useDispatch();
-
const handleChangePage = (event, newPage) => {
setPage(newPage);
};
@@ -119,7 +120,7 @@ const MaintenanceTable = ({
dispatch(
setRowsPerPage({
value: parseInt(event.target.value, 10),
- table: "monitors",
+ table: "maintenance",
})
);
setPage(0);
@@ -159,7 +160,7 @@ const MaintenanceTable = ({
onClick={() => handleSort("name")}
>
- Host
+ Maintenance Window Name
{sort.order === "asc" ? (
@@ -195,12 +196,38 @@ const MaintenanceTable = ({
- Response Time
- Type
+ Next Window
+ Repeat
Actions
-
+
+ {maintenanceWindows.map((maintenanceWindow) => {
+ const text = maintenanceWindow.active ? "active" : "paused";
+ const status = maintenanceWindow.active ? "up" : "paused";
+ return (
+
+ {maintenanceWindow.name}
+
+
+
+ {maintenanceWindow.start}
+
+ {maintenanceWindow.repeat === 0
+ ? "N/A"
+ : formatDurationRounded(maintenanceWindow.repeat)}
+
+
+
+
+
+ );
+ })}
+
{
const theme = useTheme();
- const authState = useSelector((state) => state.auth);
+ const navigate = useNavigate();
+ const { authToken } = useSelector((state) => state.auth);
+ const { rowsPerPage } = useSelector((state) => state.ui.maintenance);
const [maintenanceWindows, setMaintenanceWindows] = useState([]);
const [maintenanceWindowCount, setMaintenanceWindowCount] = useState(0);
const [page, setPage] = useState(0);
- const [rowsPerPage, setRowsPerPage] = useState(5);
const [sort, setSort] = useState({});
- useEffect(() => {});
+ useEffect(() => {
+ const fetchMaintenanceWindows = async () => {
+ try {
+ const response = await networkService.getMaintenanceWindowsByTeamId({
+ authToken: authToken,
+ page: page,
+ rowsPerPage: rowsPerPage,
+ });
+ const { maintenanceWindows, maintenanceWindowCount } =
+ response.data.data;
+ setMaintenanceWindows(maintenanceWindows);
+ setMaintenanceWindowCount(maintenanceWindowCount);
+ } catch (error) {
+ console.log(error);
+ }
+ };
+ fetchMaintenanceWindows();
+ }, [authToken, page, rowsPerPage]);
return (
{
}}
>
{maintenanceWindows.length > 0 && (
-
+
+
+
+
+
+
+
)}
{isAdmin && maintenanceWindows.length === 0 && (
} The response from the axios POST request.
+ *
+ */
+
+ async getMaintenanceWindowsByTeamId(config) {
+ const { authToken, active, page, rowsPerPage, field, order } = config;
+
+ const params = new URLSearchParams();
+
+ if (active) params.append("status", active);
+ if (page) params.append("page", page);
+ if (rowsPerPage) params.append("rowsPerPage", rowsPerPage);
+ if (field) params.append("field", field);
+ if (order) params.append("order", order);
+
+ return this.axiosInstance.get(
+ `/maintenance-window/team?${params.toString()}`,
+ {
+ headers: {
+ Authorization: `Bearer ${authToken}`,
+ "Content-Type": "application/json",
+ },
+ }
+ );
+ }
}
export default NetworkService;
diff --git a/Server/controllers/maintenanceWindowController.js b/Server/controllers/maintenanceWindowController.js
index 09dd177a9..bd92b4dc1 100644
--- a/Server/controllers/maintenanceWindowController.js
+++ b/Server/controllers/maintenanceWindowController.js
@@ -28,6 +28,7 @@ const createMaintenanceWindows = async (req, res, next) => {
return req.db.createMaintenanceWindow({
teamId,
monitorId,
+ name: req.body.name,
active: req.body.active ? req.body.active : true,
repeat: req.body.repeat,
start: req.body.start,
diff --git a/Server/db/models/MaintenanceWindow.js b/Server/db/models/MaintenanceWindow.js
index 06141cc60..3727d3b40 100644
--- a/Server/db/models/MaintenanceWindow.js
+++ b/Server/db/models/MaintenanceWindow.js
@@ -43,6 +43,9 @@ const MaintenanceWindow = mongoose.Schema(
type: Boolean,
default: true,
},
+ name: {
+ type: String,
+ },
repeat: {
type: Number,
},
diff --git a/Server/db/mongo/modules/maintenanceWindowModule.js b/Server/db/mongo/modules/maintenanceWindowModule.js
index 57b1eb05f..7e328e27c 100644
--- a/Server/db/mongo/modules/maintenanceWindowModule.js
+++ b/Server/db/mongo/modules/maintenanceWindowModule.js
@@ -36,7 +36,7 @@ const createMaintenanceWindow = async (maintenanceWindowData) => {
if (maintenanceWindowData.oneTime) {
maintenanceWindow.expiry = maintenanceWindowData.end;
}
- const result = maintenanceWindow.save();
+ const result = await maintenanceWindow.save();
return result;
} catch (error) {
error.service = SERVICE_NAME;