Merge pull request #1018 from bluewave-labs/refactor/Dialog
Refactor/dialog
This commit is contained in:
9 files changed
+299
-497
No files matched your search
@@ -0,0 +1,67 @@
|
||||
import { useId } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { Modal, Stack, Typography } from "@mui/material";
|
||||
|
||||
const GenericDialog = ({ title, description, open, onClose, theme, children }) => {
|
||||
const titleId = useId();
|
||||
const descriptionId = useId();
|
||||
const ariaDescribedBy = description?.length > 0 ? descriptionId : "";
|
||||
return (
|
||||
<Modal
|
||||
aria-labelledby={titleId}
|
||||
aria-describedby={ariaDescribedBy}
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
>
|
||||
<Stack
|
||||
gap={theme.spacing(2)}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
width: 400,
|
||||
bgcolor: theme.palette.background.main,
|
||||
border: 1,
|
||||
borderColor: theme.palette.border.light,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
boxShadow: 24,
|
||||
p: theme.spacing(15),
|
||||
"&:focus": {
|
||||
outline: "none",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
id={titleId}
|
||||
component="h2"
|
||||
fontSize={16}
|
||||
color={theme.palette.text.primary}
|
||||
fontWeight={600}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
{description && (
|
||||
<Typography
|
||||
id={descriptionId}
|
||||
color={theme.palette.text.tertiary}
|
||||
>
|
||||
{description}
|
||||
</Typography>
|
||||
)}
|
||||
{children}
|
||||
</Stack>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
GenericDialog.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
description: PropTypes.string,
|
||||
open: PropTypes.bool.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
theme: PropTypes.object.isRequired,
|
||||
children: PropTypes.element.isRequired,
|
||||
};
|
||||
|
||||
export { GenericDialog };
|
||||
@@ -1,103 +1,62 @@
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
import { Button, Modal, Stack, Typography } from "@mui/material";
|
||||
import PropTypes from "prop-types";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
import { Button, Stack } from "@mui/material";
|
||||
import { GenericDialog } from "./genericDialog";
|
||||
|
||||
const Dialog = ({
|
||||
modelTitle,
|
||||
modelDescription,
|
||||
open,
|
||||
onClose,
|
||||
title,
|
||||
confirmationBtnLbl,
|
||||
confirmationBtnOnClick,
|
||||
cancelBtnLbl,
|
||||
cancelBtnOnClick,
|
||||
theme,
|
||||
isLoading,
|
||||
description,
|
||||
open,
|
||||
theme,
|
||||
onCancel,
|
||||
confirmationButtonLabel,
|
||||
onConfirm,
|
||||
isLoading,
|
||||
}) => {
|
||||
return (
|
||||
<Modal
|
||||
aria-labelledby={modelTitle}
|
||||
aria-describedby={modelDescription}
|
||||
<GenericDialog
|
||||
title={title}
|
||||
description={description}
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
onClose={onCancel}
|
||||
theme={theme}
|
||||
>
|
||||
<Stack
|
||||
gap={theme.spacing(2)}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
width: 400,
|
||||
bgcolor: theme.palette.background.main,
|
||||
border: 1,
|
||||
borderColor: theme.palette.border.light,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
boxShadow: 24,
|
||||
p: theme.spacing(15),
|
||||
"&:focus": {
|
||||
outline: "none",
|
||||
},
|
||||
}}
|
||||
direction="row"
|
||||
gap={theme.spacing(4)}
|
||||
mt={theme.spacing(12)}
|
||||
justifyContent="flex-end"
|
||||
>
|
||||
<Typography
|
||||
id={modelTitle}
|
||||
component="h2"
|
||||
fontSize={16}
|
||||
color={theme.palette.text.primary}
|
||||
fontWeight={600}
|
||||
<Button
|
||||
variant="text"
|
||||
color="info"
|
||||
onClick={onCancel}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
{description && (
|
||||
<Typography
|
||||
id={modelDescription}
|
||||
color={theme.palette.text.tertiary}
|
||||
>
|
||||
{description}
|
||||
</Typography>
|
||||
)}
|
||||
<Stack
|
||||
direction="row"
|
||||
gap={theme.spacing(4)}
|
||||
mt={theme.spacing(12)}
|
||||
justifyContent="flex-end"
|
||||
Cancel
|
||||
</Button>
|
||||
<LoadingButton
|
||||
variant="contained"
|
||||
color="error"
|
||||
loading={isLoading}
|
||||
onClick={onConfirm}
|
||||
>
|
||||
<Button
|
||||
variant="text"
|
||||
color="info"
|
||||
onClick={cancelBtnOnClick}
|
||||
>
|
||||
{cancelBtnLbl}
|
||||
</Button>
|
||||
<LoadingButton
|
||||
variant="contained"
|
||||
color="error"
|
||||
loading={isLoading}
|
||||
onClick={confirmationBtnOnClick}
|
||||
>
|
||||
{confirmationBtnLbl}
|
||||
</LoadingButton>
|
||||
</Stack>
|
||||
{confirmationButtonLabel}
|
||||
</LoadingButton>
|
||||
</Stack>
|
||||
</Modal>
|
||||
</GenericDialog>
|
||||
);
|
||||
};
|
||||
|
||||
Dialog.propTypes = {
|
||||
modelTitle: PropTypes.string.isRequired,
|
||||
modelDescription: PropTypes.string.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
description: PropTypes.string,
|
||||
open: PropTypes.bool.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
confirmationBtnLbl: PropTypes.string.isRequired,
|
||||
confirmationBtnOnClick: PropTypes.func.isRequired,
|
||||
cancelBtnLbl: PropTypes.string.isRequired,
|
||||
cancelBtnOnClick: PropTypes.func.isRequired,
|
||||
theme: PropTypes.object.isRequired,
|
||||
onCancel: PropTypes.func.isRequired,
|
||||
confirmationButtonLabel: PropTypes.string.isRequired,
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
isLoading: PropTypes.bool.isRequired,
|
||||
description: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Dialog;
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useRef, useState } from "react";
|
||||
import TabPanel from "@mui/lab/TabPanel";
|
||||
import { Box, Button, Divider, Modal, Stack, Typography } from "@mui/material";
|
||||
import { Box, Button, Divider, Stack, Typography } from "@mui/material";
|
||||
import Avatar from "../../Avatar";
|
||||
import Field from "../../Inputs/Field";
|
||||
import ImageField from "../../Inputs/Image";
|
||||
@@ -15,6 +15,8 @@ import { clearUptimeMonitorState } from "../../../Features/UptimeMonitors/uptime
|
||||
import { createToast } from "../../../Utils/toastUtils";
|
||||
import { logger } from "../../../Utils/Logger";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
import { GenericDialog } from "../../Dialog/genericDialog";
|
||||
import Dialog from "../../Dialog";
|
||||
|
||||
/**
|
||||
* ProfilePanel component displays a form for editing user profile information
|
||||
@@ -369,158 +371,82 @@ const ProfilePanel = () => {
|
||||
</Box>
|
||||
)}
|
||||
{/* TODO - Update ModalPopup Component with @mui for reusability */}
|
||||
<Modal
|
||||
aria-labelledby="modal-delete-account"
|
||||
aria-describedby="delete-account-confirmation"
|
||||
|
||||
<Dialog
|
||||
open={isModalOpen("delete")}
|
||||
onClose={() => setIsOpen("")}
|
||||
disablePortal
|
||||
>
|
||||
<Stack
|
||||
gap={theme.spacing(5)}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
width: 500,
|
||||
bgcolor: theme.palette.background.main,
|
||||
border: 1,
|
||||
borderColor: theme.palette.border.light,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
boxShadow: 24,
|
||||
p: theme.spacing(15),
|
||||
"&:focus": {
|
||||
outline: "none",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
id="modal-delete-account"
|
||||
component="h1"
|
||||
>
|
||||
Really delete this account?
|
||||
</Typography>
|
||||
<Typography
|
||||
id="delete-account-confirmation"
|
||||
component="p"
|
||||
>
|
||||
If you delete your account, you will no longer be able to sign in, and all of
|
||||
your data will be deleted. Deleting your account is permanent and
|
||||
non-recoverable action.
|
||||
</Typography>
|
||||
<Stack
|
||||
direction="row"
|
||||
gap={theme.spacing(5)}
|
||||
mt={theme.spacing(5)}
|
||||
justifyContent="flex-end"
|
||||
>
|
||||
<Button
|
||||
variant="text"
|
||||
color="info"
|
||||
onClick={() => setIsOpen("")}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<LoadingButton
|
||||
variant="contained"
|
||||
color="error"
|
||||
onClick={handleDeleteAccount}
|
||||
loading={isLoading}
|
||||
>
|
||||
Delete account
|
||||
</LoadingButton>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Modal>
|
||||
<Modal
|
||||
aria-labelledby="modal-update-picture"
|
||||
aria-describedby="update-profile-picture"
|
||||
theme={theme}
|
||||
title={"Really delete this account?"}
|
||||
description={
|
||||
"If you delete your account, you will no longer be able to sign in, and all of your data will be deleted. Deleting your account is permanent and non-recoverable action."
|
||||
}
|
||||
onCancel={() => setIsOpen("")}
|
||||
confirmationButtonLabel={"Delete account"}
|
||||
onConfirm={handleDeleteAccount}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
|
||||
<GenericDialog
|
||||
title={"Upload Image"}
|
||||
open={isModalOpen("picture")}
|
||||
onClose={closePictureModal}
|
||||
theme={theme}
|
||||
>
|
||||
<Stack
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
width: 475,
|
||||
bgcolor: theme.palette.background.main,
|
||||
border: 1,
|
||||
borderColor: theme.palette.border.light,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
boxShadow: theme.shape.boxShadow,
|
||||
p: theme.spacing(15),
|
||||
"&:focus": {
|
||||
outline: "none",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
id="modal-update-picture"
|
||||
component="h1"
|
||||
color={theme.palette.text.secondary}
|
||||
>
|
||||
Upload Image
|
||||
</Typography>
|
||||
<ImageField
|
||||
id="update-profile-picture"
|
||||
src={
|
||||
file?.delete
|
||||
? ""
|
||||
: file?.src
|
||||
? file.src
|
||||
: localData?.file
|
||||
? localData.file
|
||||
: user?.avatarImage
|
||||
? `data:image/png;base64,${user.avatarImage}`
|
||||
: ""
|
||||
}
|
||||
loading={progress.isLoading && progress.value !== 100}
|
||||
onChange={handlePicture}
|
||||
<ImageField
|
||||
id="update-profile-picture"
|
||||
src={
|
||||
file?.delete
|
||||
? ""
|
||||
: file?.src
|
||||
? file.src
|
||||
: localData?.file
|
||||
? localData.file
|
||||
: user?.avatarImage
|
||||
? `data:image/png;base64,${user.avatarImage}`
|
||||
: ""
|
||||
}
|
||||
loading={progress.isLoading && progress.value !== 100}
|
||||
onChange={handlePicture}
|
||||
/>
|
||||
{progress.isLoading || progress.value !== 0 || errors["picture"] ? (
|
||||
<ProgressUpload
|
||||
icon={<ImageIcon />}
|
||||
label={file?.name}
|
||||
size={file?.size}
|
||||
progress={progress.value}
|
||||
onClick={removePicture}
|
||||
error={errors["picture"]}
|
||||
/>
|
||||
{progress.isLoading || progress.value !== 0 || errors["picture"] ? (
|
||||
<ProgressUpload
|
||||
icon={<ImageIcon />}
|
||||
label={file?.name}
|
||||
size={file?.size}
|
||||
progress={progress.value}
|
||||
onClick={removePicture}
|
||||
error={errors["picture"]}
|
||||
/>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
<Stack
|
||||
direction="row"
|
||||
mt={theme.spacing(10)}
|
||||
gap={theme.spacing(5)}
|
||||
justifyContent="flex-end"
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
<Stack
|
||||
direction="row"
|
||||
mt={theme.spacing(10)}
|
||||
gap={theme.spacing(5)}
|
||||
justifyContent="flex-end"
|
||||
>
|
||||
<Button
|
||||
variant="text"
|
||||
color="info"
|
||||
onClick={removePicture}
|
||||
>
|
||||
<Button
|
||||
variant="text"
|
||||
color="info"
|
||||
onClick={removePicture}
|
||||
>
|
||||
Remove
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={handleUpdatePicture}
|
||||
disabled={
|
||||
(Object.keys(errors).length !== 0 && errors?.picture) ||
|
||||
progress.value !== 100
|
||||
? true
|
||||
: false
|
||||
}
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
</Stack>
|
||||
Remove
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={handleUpdatePicture}
|
||||
disabled={
|
||||
(Object.keys(errors).length !== 0 && errors?.picture) ||
|
||||
progress.value !== 100
|
||||
? true
|
||||
: false
|
||||
}
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
</Stack>
|
||||
</Modal>
|
||||
</GenericDialog>
|
||||
</TabPanel>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useTheme } from "@emotion/react";
|
||||
import TabPanel from "@mui/lab/TabPanel";
|
||||
import { Box, Button, ButtonGroup, Modal, Stack, Typography } from "@mui/material";
|
||||
import { Button, ButtonGroup, Stack, Typography } from "@mui/material";
|
||||
import { useEffect, useState } from "react";
|
||||
import Field from "../../Inputs/Field";
|
||||
import { credentials } from "../../../Validation/validation";
|
||||
@@ -10,6 +10,7 @@ import { useSelector } from "react-redux";
|
||||
import BasicTable from "../../BasicTable";
|
||||
import Select from "../../Inputs/Select";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
import { GenericDialog } from "../../Dialog/genericDialog";
|
||||
|
||||
/**
|
||||
* TeamPanel component manages the organization and team members,
|
||||
@@ -31,10 +32,10 @@ const TeamPanel = () => {
|
||||
|
||||
const { authToken, user } = useSelector((state) => state.auth);
|
||||
//TODO
|
||||
const [orgStates, setOrgStates] = useState({
|
||||
name: "Bluewave Labs",
|
||||
isEdit: false,
|
||||
});
|
||||
// const [orgStates, setOrgStates] = useState({
|
||||
// name: "Bluewave Labs",
|
||||
// isEdit: false,
|
||||
// });
|
||||
const [toInvite, setToInvite] = useState({
|
||||
email: "",
|
||||
role: ["0"],
|
||||
@@ -134,10 +135,10 @@ const TeamPanel = () => {
|
||||
}, [errors, toInvite.email]);
|
||||
|
||||
// RENAME ORGANIZATION
|
||||
const toggleEdit = () => {
|
||||
setOrgStates((prev) => ({ ...prev, isEdit: !prev.isEdit }));
|
||||
};
|
||||
const handleRename = () => {};
|
||||
// const toggleEdit = () => {
|
||||
// setOrgStates((prev) => ({ ...prev, isEdit: !prev.isEdit }));
|
||||
// };
|
||||
// const handleRename = () => {};
|
||||
|
||||
// INVITE MEMBER
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
@@ -327,100 +328,65 @@ const TeamPanel = () => {
|
||||
table={"team"}
|
||||
/>
|
||||
</Stack>
|
||||
<Modal
|
||||
aria-labelledby="modal-invite-member"
|
||||
aria-describedby="invite-member-to-team"
|
||||
|
||||
<GenericDialog
|
||||
title={"Invite new team member"}
|
||||
description={
|
||||
"When you add a new team member, they will get access to all monitors."
|
||||
}
|
||||
open={isOpen}
|
||||
onClose={closeInviteModal}
|
||||
theme={theme}
|
||||
>
|
||||
<Field
|
||||
type="email"
|
||||
id="input-team-member"
|
||||
placeholder="Email"
|
||||
value={toInvite.email}
|
||||
onChange={handleChange}
|
||||
error={errors.email}
|
||||
/>
|
||||
<Select
|
||||
id="team-member-role"
|
||||
placeholder="Select role"
|
||||
isHidden={true}
|
||||
value={toInvite.role[0]}
|
||||
onChange={(event) =>
|
||||
setToInvite((prev) => ({
|
||||
...prev,
|
||||
role: [event.target.value],
|
||||
}))
|
||||
}
|
||||
items={[
|
||||
{ _id: "admin", name: "Admin" },
|
||||
{ _id: "user", name: "User" },
|
||||
]}
|
||||
/>
|
||||
<Stack
|
||||
gap={theme.spacing(5)}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
width: 450,
|
||||
bgcolor: theme.palette.background.main,
|
||||
border: 1,
|
||||
borderColor: theme.palette.border.light,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
boxShadow: theme.shape.boxShadow,
|
||||
p: theme.spacing(15),
|
||||
"&:focus": {
|
||||
outline: "none",
|
||||
},
|
||||
}}
|
||||
direction="row"
|
||||
gap={theme.spacing(4)}
|
||||
mt={theme.spacing(8)}
|
||||
justifyContent="flex-end"
|
||||
>
|
||||
<Box>
|
||||
<Typography
|
||||
id="modal-invite-member"
|
||||
component="h1"
|
||||
fontWeight={600}
|
||||
fontColor={theme.palette.text.secondary}
|
||||
>
|
||||
Invite new team member
|
||||
</Typography>
|
||||
<Typography
|
||||
id="invite-member-to-team"
|
||||
component="p"
|
||||
fontSize={13}
|
||||
color={theme.palette.text.accent}
|
||||
sx={{ mt: theme.spacing(1), mb: theme.spacing(4) }}
|
||||
>
|
||||
When you add a new team member, they will get access to all monitors.
|
||||
</Typography>
|
||||
</Box>
|
||||
<Field
|
||||
type="email"
|
||||
id="input-team-member"
|
||||
placeholder="Email"
|
||||
value={toInvite.email}
|
||||
onChange={handleChange}
|
||||
error={errors.email}
|
||||
/>
|
||||
<Select
|
||||
id="team-member-role"
|
||||
placeholder="Select role"
|
||||
isHidden={true}
|
||||
value={toInvite.role[0]}
|
||||
onChange={(event) =>
|
||||
setToInvite((prev) => ({
|
||||
...prev,
|
||||
role: [event.target.value],
|
||||
}))
|
||||
}
|
||||
items={[
|
||||
{ _id: "admin", name: "Admin" },
|
||||
{ _id: "user", name: "User" },
|
||||
]}
|
||||
/>
|
||||
<Stack
|
||||
direction="row"
|
||||
gap={theme.spacing(4)}
|
||||
mt={theme.spacing(8)}
|
||||
justifyContent="flex-end"
|
||||
<LoadingButton
|
||||
loading={isSendingInvite}
|
||||
variant="text"
|
||||
color="info"
|
||||
onClick={closeInviteModal}
|
||||
>
|
||||
<LoadingButton
|
||||
loading={isSendingInvite}
|
||||
variant="text"
|
||||
color="info"
|
||||
onClick={closeInviteModal}
|
||||
>
|
||||
Cancel
|
||||
</LoadingButton>
|
||||
<LoadingButton
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={handleInviteMember}
|
||||
loading={isSendingInvite}
|
||||
disabled={isDisabled}
|
||||
>
|
||||
Send invite
|
||||
</LoadingButton>
|
||||
</Stack>
|
||||
Cancel
|
||||
</LoadingButton>
|
||||
<LoadingButton
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={handleInviteMember}
|
||||
loading={isSendingInvite}
|
||||
disabled={isDisabled}
|
||||
>
|
||||
Send invite
|
||||
</LoadingButton>
|
||||
</Stack>
|
||||
</Modal>
|
||||
</GenericDialog>
|
||||
</TabPanel>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,23 +2,16 @@ import { useState } from "react";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useSelector } from "react-redux";
|
||||
import {
|
||||
Button,
|
||||
IconButton,
|
||||
Menu,
|
||||
MenuItem,
|
||||
Modal,
|
||||
Stack,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
import { IconButton, Menu, MenuItem } from "@mui/material";
|
||||
import { logger } from "../../../../Utils/Logger";
|
||||
import Settings from "../../../../assets/icons/settings-bold.svg?react";
|
||||
import PropTypes from "prop-types";
|
||||
import { networkService } from "../../../../main";
|
||||
import { createToast } from "../../../../Utils/toastUtils";
|
||||
|
||||
const ActionsMenu = ({ isAdmin, maintenanceWindow, updateCallback }) => {
|
||||
import Dialog from "../../../../Components/Dialog";
|
||||
|
||||
const ActionsMenu = ({ /* isAdmin, */ maintenanceWindow, updateCallback }) => {
|
||||
maintenanceWindow;
|
||||
const { authToken } = useSelector((state) => state.auth);
|
||||
const [anchorEl, setAnchorEl] = useState(null);
|
||||
@@ -155,71 +148,21 @@ const ActionsMenu = ({ isAdmin, maintenanceWindow, updateCallback }) => {
|
||||
Remove
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
<Modal
|
||||
aria-labelledby="modal-delete-monitor"
|
||||
aria-describedby="delete-monitor-confirmation"
|
||||
<Dialog
|
||||
open={isOpen}
|
||||
onClose={(e) => {
|
||||
theme={theme}
|
||||
title={"Do you really want to remove this maintenance window?"}
|
||||
onCancel={(e) => {
|
||||
e.stopPropagation();
|
||||
setIsOpen(false);
|
||||
}}
|
||||
>
|
||||
<Stack
|
||||
gap={theme.spacing(2)}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
width: 400,
|
||||
bgcolor: theme.palette.background.main,
|
||||
border: 1,
|
||||
borderColor: theme.palette.border.light,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
boxShadow: 24,
|
||||
p: theme.spacing(15),
|
||||
"&:focus": {
|
||||
outline: "none",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
id="modal-delete-maintenance"
|
||||
component="h2"
|
||||
variant="h2"
|
||||
>
|
||||
Do you really want to remove this maintenance window?
|
||||
</Typography>
|
||||
<Stack
|
||||
direction="row"
|
||||
gap={theme.spacing(4)}
|
||||
mt={theme.spacing(12)}
|
||||
justifyContent="flex-end"
|
||||
>
|
||||
<Button
|
||||
variant="text"
|
||||
color="info"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setIsOpen(false);
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<LoadingButton
|
||||
loading={isLoading}
|
||||
variant="contained"
|
||||
color="error"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation(e);
|
||||
handleRemove(e);
|
||||
}}
|
||||
>
|
||||
Delete
|
||||
</LoadingButton>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Modal>
|
||||
confirmationButtonLabel={"Delete"}
|
||||
onConfirm={(e) => {
|
||||
e.stopPropagation(e);
|
||||
handleRemove(e);
|
||||
}}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -453,20 +453,17 @@ const Configure = () => {
|
||||
</Stack>
|
||||
</>
|
||||
)}
|
||||
|
||||
<Dialog
|
||||
modelTitle="modal-delete-monitor"
|
||||
modelDescription="delete-monitor-confirmation"
|
||||
open={isOpen}
|
||||
onClose={() => setIsOpen(false)}
|
||||
title="Do you really want to delete this monitor?"
|
||||
confirmationBtnLbl="Delete"
|
||||
confirmationBtnOnClick={handleRemove}
|
||||
cancelBtnLbl="Cancel"
|
||||
cancelBtnOnClick={() => setIsOpen(false)}
|
||||
theme={theme}
|
||||
isLoading={isLoading}
|
||||
title="Do you really want to delete this monitor?"
|
||||
description="Once deleted, this monitor cannot be retrieved."
|
||||
></Dialog>
|
||||
onCancel={() => setIsOpen(false)}
|
||||
confirmationButtonLabel="Delete"
|
||||
onConfirm={handleRemove}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -188,25 +188,25 @@ const ActionsMenu = ({ monitor, isAdmin, updateCallback }) => {
|
||||
)}
|
||||
</Menu>
|
||||
<Dialog
|
||||
modelTitle="modal-delete-monitor"
|
||||
modelDescription="delete-monitor-confirmation"
|
||||
open={isOpen}
|
||||
onClose={() => setIsOpen(false)}
|
||||
theme={theme}
|
||||
title="Do you really want to delete this monitor?"
|
||||
confirmationBtnLbl="Delete"
|
||||
confirmationBtnOnClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleRemove(e);
|
||||
}}
|
||||
cancelBtnLbl="Cancel"
|
||||
cancelBtnOnClick={(e) => {
|
||||
description="Once deleted, this monitor cannot be retrieved."
|
||||
/* Do we need stop propagation? */
|
||||
onCancel={(e) => {
|
||||
e.stopPropagation();
|
||||
setIsOpen(false);
|
||||
}}
|
||||
theme={theme}
|
||||
confirmationButtonLabel="Delete"
|
||||
/* Do we need stop propagation? */
|
||||
onConfirm={(e) => {
|
||||
e.stopPropagation();
|
||||
handleRemove(e);
|
||||
}}
|
||||
isLoading={isLoading}
|
||||
description="Once deleted, this monitor cannot be retrieved."
|
||||
></Dialog>
|
||||
modelTitle="modal-delete-monitor"
|
||||
modelDescription="delete-monitor-confirmation"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { Box, Button, Modal, Stack, Tooltip, Typography } from "@mui/material";
|
||||
import { Box, Stack, Tooltip, Typography } from "@mui/material";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useNavigate, useParams } from "react-router";
|
||||
import {
|
||||
@@ -25,6 +25,7 @@ import PlayCircleOutlineRoundedIcon from "@mui/icons-material/PlayCircleOutlineR
|
||||
import SkeletonLayout from "./skeleton";
|
||||
import useUtils from "../../Monitors/utils";
|
||||
import "./index.css";
|
||||
import Dialog from "../../../Components/Dialog";
|
||||
|
||||
const PageSpeedConfigure = () => {
|
||||
const theme = useTheme();
|
||||
@@ -37,6 +38,7 @@ const PageSpeedConfigure = () => {
|
||||
const [monitor, setMonitor] = useState({});
|
||||
const [errors, setErrors] = useState({});
|
||||
const { statusColor, pagespeedStatusMsg, determineState } = useUtils();
|
||||
const [buttonLoading, setButtonLoading] = useState(false);
|
||||
const idMap = {
|
||||
"monitor-url": "url",
|
||||
"monitor-name": "name",
|
||||
@@ -156,12 +158,14 @@ const PageSpeedConfigure = () => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const handleRemove = async (event) => {
|
||||
event.preventDefault();
|
||||
setButtonLoading(true);
|
||||
const action = await dispatch(deletePageSpeed({ authToken, monitor }));
|
||||
if (action.meta.requestStatus === "fulfilled") {
|
||||
navigate("/pagespeed");
|
||||
} else {
|
||||
createToast({ body: "Failed to delete monitor." });
|
||||
}
|
||||
setButtonLoading(false);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -428,69 +432,16 @@ const PageSpeedConfigure = () => {
|
||||
</Stack>
|
||||
</>
|
||||
)}
|
||||
<Modal
|
||||
aria-labelledby="modal-delete-pagespeed-monitor"
|
||||
aria-describedby="delete-pagespeed-monitor-confirmation"
|
||||
<Dialog
|
||||
open={isOpen}
|
||||
onClose={() => setIsOpen(false)}
|
||||
disablePortal
|
||||
>
|
||||
<Stack
|
||||
gap={theme.spacing(2)}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
width: 400,
|
||||
bgcolor: theme.palette.background.main,
|
||||
border: 1,
|
||||
borderColor: theme.palette.border.light,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
boxShadow: 24,
|
||||
p: theme.spacing(15),
|
||||
"&:focus": {
|
||||
outline: "none",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
id="modal-delete-pagespeed-monitor"
|
||||
component="h2"
|
||||
variant="h2"
|
||||
fontWeight={500}
|
||||
>
|
||||
Do you really want to delete this monitor?
|
||||
</Typography>
|
||||
<Typography
|
||||
id="delete-pagespeed-monitor-confirmation"
|
||||
variant="body1"
|
||||
>
|
||||
Once deleted, this monitor cannot be retrieved.
|
||||
</Typography>
|
||||
<Stack
|
||||
direction="row"
|
||||
gap={theme.spacing(4)}
|
||||
mt={theme.spacing(12)}
|
||||
justifyContent="flex-end"
|
||||
>
|
||||
<Button
|
||||
variant="text"
|
||||
color="info"
|
||||
onClick={() => setIsOpen(false)}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="error"
|
||||
onClick={handleRemove}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Modal>
|
||||
theme={theme}
|
||||
title={"Do you really want to delete this monitor?"}
|
||||
description={"Once deleted, this monitor cannot be retrieved."}
|
||||
onCancel={() => setIsOpen(false)}
|
||||
confirmationButtonLabel={"Delete"}
|
||||
onConfirm={handleRemove}
|
||||
isLoading={buttonLoading}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -263,18 +263,15 @@ const Settings = ({ isAdmin }) => {
|
||||
</Box>
|
||||
</Stack>
|
||||
<Dialog
|
||||
modelTitle="model-clear-stats"
|
||||
modelDescription="clear-stats-confirmation"
|
||||
open={isOpen.deleteStats}
|
||||
onClose={() => setIsOpen(deleteStatsMonitorsInitState)}
|
||||
title="Do you want to clear all stats?"
|
||||
confirmationBtnLbl="Yes, clear all stats"
|
||||
confirmationBtnOnClick={handleClearStats}
|
||||
cancelBtnLbl="Cancel"
|
||||
cancelBtnOnClick={() => setIsOpen(deleteStatsMonitorsInitState)}
|
||||
theme={theme}
|
||||
title="Do you want to clear all stats?"
|
||||
description="Once deleted, this monitor cannot be retrieved."
|
||||
onCancel={() => setIsOpen(deleteStatsMonitorsInitState)}
|
||||
confirmationButtonLabel="Yes, clear all stats"
|
||||
onConfirm={handleClearStats}
|
||||
isLoading={isLoading || authIsLoading || checksIsLoading}
|
||||
></Dialog>
|
||||
/>
|
||||
</ConfigBox>
|
||||
)}
|
||||
{isAdmin && (
|
||||
@@ -314,18 +311,14 @@ const Settings = ({ isAdmin }) => {
|
||||
</Box>
|
||||
</Stack>
|
||||
<Dialog
|
||||
modelTitle="model-delete-all-monitors"
|
||||
modelDescription="delete-all-monitors-confirmation"
|
||||
open={isOpen.deleteMonitors}
|
||||
onClose={() => setIsOpen(deleteStatsMonitorsInitState)}
|
||||
title="Do you want to remove all monitors?"
|
||||
confirmationBtnLbl="Yes, clear all monitors"
|
||||
confirmationBtnOnClick={handleDeleteAllMonitors}
|
||||
cancelBtnLbl="Cancel"
|
||||
cancelBtnOnClick={() => setIsOpen(deleteStatsMonitorsInitState)}
|
||||
theme={theme}
|
||||
title="Do you want to remove all monitors?"
|
||||
onCancel={() => setIsOpen(deleteStatsMonitorsInitState)}
|
||||
confirmationButtonLabel="Yes, clear all monitors"
|
||||
onConfirm={handleDeleteAllMonitors}
|
||||
isLoading={isLoading || authIsLoading || checksIsLoading}
|
||||
></Dialog>
|
||||
/>
|
||||
</ConfigBox>
|
||||
)}
|
||||
{isAdmin && (
|
||||
|
||||
Reference in new issue
Block a user