Refactored skeletons
This commit is contained in:
1 parent
70f88058a0
commit
2485198b6a
6 files changed
+471
-448
No files matched your search
@@ -12,6 +12,32 @@ import Select from "../../Components/Inputs/Select";
|
||||
|
||||
import "./index.css";
|
||||
|
||||
/**
|
||||
* Renders a skeleton layout.
|
||||
*
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
const SkeletonLayout = () => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack direction="row" alignItems="center" gap={theme.gap.medium}>
|
||||
<Skeleton variant="rounded" width={150} height={34} />
|
||||
<Skeleton variant="rounded" width="15%" height={34} />
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="20%"
|
||||
height={34}
|
||||
sx={{ ml: "auto" }}
|
||||
/>
|
||||
</Stack>
|
||||
<Skeleton variant="rounded" width="100%" height={300} />
|
||||
<Skeleton variant="rounded" width="100%" height={100} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const Incidents = () => {
|
||||
const theme = useTheme();
|
||||
const navigate = useNavigate();
|
||||
@@ -106,20 +132,7 @@ const Incidents = () => {
|
||||
<>
|
||||
<Stack className="incidents" gap={theme.gap.large}>
|
||||
{loading ? (
|
||||
<>
|
||||
<Stack direction="row" alignItems="center" gap={theme.gap.medium}>
|
||||
<Skeleton variant="rounded" width={150} height={34} />
|
||||
<Skeleton variant="rounded" width="15%" height={34} />
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="20%"
|
||||
height={34}
|
||||
sx={{ ml: "auto" }}
|
||||
/>
|
||||
</Stack>
|
||||
<Skeleton variant="rounded" width="100%" height={300} />
|
||||
<Skeleton variant="rounded" width="100%" height={100} />
|
||||
</>
|
||||
<SkeletonLayout />
|
||||
) : hasAnyIncidents ? (
|
||||
<>
|
||||
<Stack direction="row" alignItems="center" gap={theme.gap.medium}>
|
||||
|
||||
@@ -36,6 +36,54 @@ const parseUrl = (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a skeleton layout.
|
||||
*
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
const SkeletonLayout = () => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Skeleton variant="rounded" width="15%" height={34} />
|
||||
<Stack gap={theme.gap.xl} mt={theme.gap.medium}>
|
||||
<Stack direction="row" gap={theme.gap.small} mt={theme.gap.small}>
|
||||
<Skeleton
|
||||
variant="circular"
|
||||
style={{ minWidth: 24, minHeight: 24 }}
|
||||
/>
|
||||
<Box width="80%">
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="50%"
|
||||
height={24}
|
||||
sx={{ mb: theme.gap.small }}
|
||||
/>
|
||||
<Skeleton variant="rounded" width="50%" height={18} />
|
||||
</Box>
|
||||
<Stack
|
||||
direction="row"
|
||||
gap={theme.gap.medium}
|
||||
sx={{
|
||||
ml: "auto",
|
||||
alignSelf: "flex-end",
|
||||
}}
|
||||
>
|
||||
<Skeleton variant="rounded" width={150} height={34} />
|
||||
</Stack>
|
||||
</Stack>
|
||||
<Skeleton variant="rounded" width="100%" height={200} />
|
||||
<Skeleton variant="rounded" width="100%" height={200} />
|
||||
<Skeleton variant="rounded" width="100%" height={200} />
|
||||
<Stack direction="row" justifyContent="flex-end">
|
||||
<Skeleton variant="rounded" width="15%" height={34} />
|
||||
</Stack>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Configure page displays monitor configurations and allows for editing actions.
|
||||
* @component
|
||||
@@ -169,56 +217,35 @@ const Configure = () => {
|
||||
return (
|
||||
<Box className="configure-monitor">
|
||||
{loading ? (
|
||||
<Skeleton variant="rounded" width="15%" height={34} />
|
||||
<SkeletonLayout />
|
||||
) : (
|
||||
<Button
|
||||
level="tertiary"
|
||||
label="Back"
|
||||
animate="slideLeft"
|
||||
img={<WestRoundedIcon />}
|
||||
onClick={() => navigate(-1)}
|
||||
sx={{
|
||||
backgroundColor: "#f4f4f4",
|
||||
px: theme.gap.ml,
|
||||
"& svg.MuiSvgIcon-root": {
|
||||
mr: theme.gap.small,
|
||||
fill: theme.palette.otherColors.slateGray,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<form
|
||||
className="configure-monitor-form"
|
||||
noValidate
|
||||
spellCheck="false"
|
||||
style={{
|
||||
marginTop: theme.gap.medium,
|
||||
}}
|
||||
>
|
||||
<Stack direction="row" gap={theme.gap.small} mt={theme.gap.small}>
|
||||
{loading ? (
|
||||
<Skeleton
|
||||
variant="circular"
|
||||
style={{ minWidth: 24, minHeight: 24 }}
|
||||
/>
|
||||
) : monitor?.status ? (
|
||||
<GreenCheck />
|
||||
) : (
|
||||
<RedCheck />
|
||||
)}
|
||||
<Box width="80%">
|
||||
{loading ? (
|
||||
<>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="50%"
|
||||
height={24}
|
||||
sx={{ mb: theme.gap.small }}
|
||||
/>
|
||||
<Skeleton variant="rounded" width="50%" height={18} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<>
|
||||
<Button
|
||||
level="tertiary"
|
||||
label="Back"
|
||||
animate="slideLeft"
|
||||
img={<WestRoundedIcon />}
|
||||
onClick={() => navigate(-1)}
|
||||
sx={{
|
||||
backgroundColor: "#f4f4f4",
|
||||
px: theme.gap.ml,
|
||||
"& svg.MuiSvgIcon-root": {
|
||||
mr: theme.gap.small,
|
||||
fill: theme.palette.otherColors.slateGray,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<form
|
||||
className="configure-monitor-form"
|
||||
noValidate
|
||||
spellCheck="false"
|
||||
style={{
|
||||
marginTop: theme.gap.medium,
|
||||
}}
|
||||
>
|
||||
<Stack direction="row" gap={theme.gap.small} mt={theme.gap.small}>
|
||||
{monitor?.status ? <GreenCheck /> : <RedCheck />}
|
||||
<Box>
|
||||
{parsedUrl?.host ? (
|
||||
<Typography
|
||||
component="h1"
|
||||
@@ -244,23 +271,15 @@ const Configure = () => {
|
||||
Checking every {duration}.{" "}
|
||||
{lastChecked ? `Last time checked ${lastChecked} ago.` : ""}
|
||||
</Typography>
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
<Stack
|
||||
direction="row"
|
||||
gap={theme.gap.medium}
|
||||
sx={{
|
||||
ml: "auto",
|
||||
alignSelf: "flex-end",
|
||||
}}
|
||||
>
|
||||
{loading ? (
|
||||
<>
|
||||
<Skeleton variant="rounded" width={150} height={34} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
</Box>
|
||||
<Stack
|
||||
direction="row"
|
||||
gap={theme.gap.medium}
|
||||
sx={{
|
||||
ml: "auto",
|
||||
alignSelf: "flex-end",
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
level="tertiary"
|
||||
label="Pause"
|
||||
@@ -284,18 +303,8 @@ const Configure = () => {
|
||||
}}
|
||||
onClick={() => setIsOpen(true)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
</Stack>
|
||||
{loading ? (
|
||||
<>
|
||||
<Skeleton variant="rounded" width="100%" height={200} />
|
||||
<Skeleton variant="rounded" width="100%" height={200} />
|
||||
<Skeleton variant="rounded" width="100%" height={200} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
</Stack>
|
||||
</Stack>
|
||||
<Stack
|
||||
className="config-box"
|
||||
direction="row"
|
||||
@@ -414,21 +423,17 @@ const Configure = () => {
|
||||
/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</>
|
||||
)}
|
||||
<Stack direction="row" justifyContent="flex-end">
|
||||
{loading ? (
|
||||
<Skeleton variant="rounded" width="15%" height={34} />
|
||||
) : (
|
||||
<Button
|
||||
level="primary"
|
||||
label="Save"
|
||||
sx={{ px: theme.gap.large }}
|
||||
onClick={handleSubmit}
|
||||
/>
|
||||
)}
|
||||
</Stack>
|
||||
</form>
|
||||
<Stack direction="row" justifyContent="flex-end">
|
||||
<Button
|
||||
level="primary"
|
||||
label="Save"
|
||||
sx={{ px: theme.gap.large }}
|
||||
onClick={handleSubmit}
|
||||
/>
|
||||
</Stack>
|
||||
</form>
|
||||
</>
|
||||
)}
|
||||
<Modal
|
||||
aria-labelledby="modal-delete-monitor"
|
||||
aria-describedby="delete-monitor-confirmation"
|
||||
|
||||
@@ -35,6 +35,76 @@ StatBox.propTypes = {
|
||||
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a skeleton layout.
|
||||
*
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
const SkeletonLayout = () => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Skeleton variant="rounded" width="20%" height={34} />
|
||||
<Stack gap={theme.gap.xl} mt={theme.gap.medium}>
|
||||
<Stack direction="row" gap={theme.gap.small} mt={theme.gap.small}>
|
||||
<Skeleton
|
||||
variant="circular"
|
||||
style={{ minWidth: 24, minHeight: 24 }}
|
||||
/>
|
||||
<Box width="80%">
|
||||
<Skeleton variant="rounded" width="50%" height={24} />
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="50%"
|
||||
height={18}
|
||||
sx={{ mt: theme.gap.small }}
|
||||
/>
|
||||
</Box>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="20%"
|
||||
height={34}
|
||||
sx={{ alignSelf: "flex-end" }}
|
||||
/>
|
||||
</Stack>
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
gap={theme.gap.large}
|
||||
>
|
||||
<Skeleton variant="rounded" width="100%" height={80} />
|
||||
<Skeleton variant="rounded" width="100%" height={80} />
|
||||
<Skeleton variant="rounded" width="100%" height={80} />
|
||||
</Stack>
|
||||
<Box>
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
mb={theme.gap.ml}
|
||||
>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="20%"
|
||||
height={24}
|
||||
sx={{ alignSelf: "flex-end" }}
|
||||
/>
|
||||
<Skeleton variant="rounded" width="20%" height={34} />
|
||||
</Stack>
|
||||
<Box sx={{ height: "200px" }}>
|
||||
<Skeleton variant="rounded" width="100%" height="100%" />
|
||||
</Box>
|
||||
</Box>
|
||||
<Stack gap={theme.gap.ml}>
|
||||
<Skeleton variant="rounded" width="20%" height={24} />
|
||||
<Skeleton variant="rounded" width="100%" height={200} />
|
||||
<Skeleton variant="rounded" width="100%" height={50} />
|
||||
</Stack>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Details page component displaying monitor details and related information.
|
||||
* @component
|
||||
@@ -168,49 +238,28 @@ const DetailsPage = () => {
|
||||
return (
|
||||
<Box className="monitor-details">
|
||||
{loading ? (
|
||||
<Skeleton variant="rounded" width="20%" height={34} />
|
||||
<SkeletonLayout />
|
||||
) : (
|
||||
<Button
|
||||
level="tertiary"
|
||||
label="Back to Monitors"
|
||||
animate="slideLeft"
|
||||
img={<WestRoundedIcon />}
|
||||
onClick={() => navigate("/monitors")}
|
||||
sx={{
|
||||
backgroundColor: "#f4f4f4",
|
||||
px: theme.gap.ml,
|
||||
"& svg.MuiSvgIcon-root": {
|
||||
mr: theme.gap.small,
|
||||
fill: theme.palette.otherColors.slateGray,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Stack gap={theme.gap.xl} mt={theme.gap.medium}>
|
||||
<Stack direction="row" gap={theme.gap.small} mt={theme.gap.small}>
|
||||
{loading ? (
|
||||
<Skeleton
|
||||
variant="circular"
|
||||
style={{ minWidth: 24, minHeight: 24 }}
|
||||
/>
|
||||
) : monitor?.status ? (
|
||||
<GreenCheck />
|
||||
) : (
|
||||
<RedCheck />
|
||||
)}
|
||||
<Box width="80%">
|
||||
{loading ? (
|
||||
<>
|
||||
<Skeleton variant="rounded" width="50%" height={24} />
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="50%"
|
||||
height={18}
|
||||
sx={{ mt: theme.gap.small }}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<>
|
||||
<Button
|
||||
level="tertiary"
|
||||
label="Back to Monitors"
|
||||
animate="slideLeft"
|
||||
img={<WestRoundedIcon />}
|
||||
onClick={() => navigate("/monitors")}
|
||||
sx={{
|
||||
backgroundColor: "#f4f4f4",
|
||||
px: theme.gap.ml,
|
||||
"& svg.MuiSvgIcon-root": {
|
||||
mr: theme.gap.small,
|
||||
fill: theme.palette.otherColors.slateGray,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<Stack gap={theme.gap.xl} mt={theme.gap.medium}>
|
||||
<Stack direction="row" gap={theme.gap.small} mt={theme.gap.small}>
|
||||
{monitor?.status ? <GreenCheck /> : <RedCheck />}
|
||||
<Box>
|
||||
<Typography component="h1" sx={{ lineHeight: 1 }}>
|
||||
{monitor.url?.replace(/^https?:\/\//, "") || "..."}
|
||||
</Typography>
|
||||
@@ -229,55 +278,36 @@ const DetailsPage = () => {
|
||||
Last time checked{" "}
|
||||
{formatDurationRounded(getLastChecked(monitor?.checks))} ago.
|
||||
</Typography>
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
{loading ? (
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="20%"
|
||||
height={34}
|
||||
sx={{ alignSelf: "flex-end" }}
|
||||
/>
|
||||
) : (
|
||||
<Button
|
||||
level="tertiary"
|
||||
label="Configure"
|
||||
animate="rotate90"
|
||||
img={
|
||||
<SettingsIcon
|
||||
style={{
|
||||
minWidth: theme.gap.mlplus,
|
||||
minHeight: theme.gap.mlplus,
|
||||
}}
|
||||
/>
|
||||
}
|
||||
onClick={() => navigate(`/monitors/configure/${monitorId}`)}
|
||||
sx={{
|
||||
ml: "auto",
|
||||
alignSelf: "flex-end",
|
||||
backgroundColor: "#f4f4f4",
|
||||
px: theme.gap.medium,
|
||||
"& svg": {
|
||||
mr: "6px",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Stack>
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
gap={theme.gap.large}
|
||||
>
|
||||
{loading ? (
|
||||
<>
|
||||
<Skeleton variant="rounded" width="100%" height={80} />
|
||||
<Skeleton variant="rounded" width="100%" height={80} />
|
||||
<Skeleton variant="rounded" width="100%" height={80} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
</Box>
|
||||
<Button
|
||||
level="tertiary"
|
||||
label="Configure"
|
||||
animate="rotate90"
|
||||
img={
|
||||
<SettingsIcon
|
||||
style={{
|
||||
minWidth: theme.gap.mlplus,
|
||||
minHeight: theme.gap.mlplus,
|
||||
}}
|
||||
/>
|
||||
}
|
||||
onClick={() => navigate(`/monitors/configure/${monitorId}`)}
|
||||
sx={{
|
||||
ml: "auto",
|
||||
alignSelf: "flex-end",
|
||||
backgroundColor: "#f4f4f4",
|
||||
px: theme.gap.medium,
|
||||
"& svg": {
|
||||
mr: "6px",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
gap={theme.gap.large}
|
||||
>
|
||||
<StatBox
|
||||
title="Currently up for"
|
||||
value={formatDuration(calculateUptimeDuration(monitor.checks))}
|
||||
@@ -290,27 +320,13 @@ const DetailsPage = () => {
|
||||
title="Incidents"
|
||||
value={countIncidents(monitor.checks)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
<Box>
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
mb={theme.gap.ml}
|
||||
>
|
||||
{loading ? (
|
||||
<>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="20%"
|
||||
height={24}
|
||||
sx={{ alignSelf: "flex-end" }}
|
||||
/>
|
||||
<Skeleton variant="rounded" width="20%" height={34} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
</Stack>
|
||||
<Box>
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
mb={theme.gap.ml}
|
||||
>
|
||||
<Typography component="h2" mb={theme.gap.small}>
|
||||
Response Times
|
||||
</Typography>
|
||||
@@ -344,35 +360,21 @@ const DetailsPage = () => {
|
||||
}}
|
||||
/>
|
||||
</ButtonGroup>
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
<Box sx={{ height: "200px" }}>
|
||||
{loading ? (
|
||||
<Skeleton variant="rounded" width="100%" height="100%" />
|
||||
) : (
|
||||
<MonitorDetailsAreaChart
|
||||
checks={monitor.checks}
|
||||
filter={filter}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
<Stack gap={theme.gap.ml}>
|
||||
{loading ? (
|
||||
<>
|
||||
<Skeleton variant="rounded" width="20%" height={24} />
|
||||
<Skeleton variant="rounded" width="100%" height={200} />
|
||||
<Skeleton variant="rounded" width="100%" height={50} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
</Stack>
|
||||
<Box sx={{ height: "200px" }}>
|
||||
<MonitorDetailsAreaChart
|
||||
checks={monitor.checks}
|
||||
filter={filter}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
<Stack gap={theme.gap.ml}>
|
||||
<Typography component="h2">History</Typography>
|
||||
<BasicTable data={data} paginated={true} reversed={true} />
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -72,6 +72,38 @@ const Host = ({ params }) => {
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a skeleton layout.
|
||||
*
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
const SkeletonLayout = () => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack direction="row" justifyContent="space-between" alignItems="center">
|
||||
<Skeleton variant="rounded" width="50%" height={36} />
|
||||
<Skeleton variant="rounded" width="15%" height={36} />
|
||||
</Stack>
|
||||
<Stack
|
||||
gap={theme.gap.large}
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<Skeleton variant="rounded" width="100%" height={100} />
|
||||
<Skeleton variant="rounded" width="100%" height={100} />
|
||||
<Skeleton variant="rounded" width="100%" height={100} />
|
||||
</Stack>
|
||||
<Stack gap={theme.gap.large} p={theme.gap.xl} backgroundColor="#f9fafb">
|
||||
<Skeleton variant="rounded" width="50%" height={25} />
|
||||
<Skeleton variant="rounded" width="100%" height={300} />
|
||||
<Skeleton variant="rounded" width="100%" height={100} />
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const Monitors = () => {
|
||||
const theme = useTheme();
|
||||
const navigate = useNavigate();
|
||||
@@ -205,18 +237,19 @@ const Monitors = () => {
|
||||
};
|
||||
});
|
||||
|
||||
let loading = monitorState.isLoading && monitorState.monitors.length === 0;
|
||||
let loading = monitorState.isLoading && monitorState.monitors.length === 0;
|
||||
|
||||
return (
|
||||
<Stack className="monitors" gap={theme.gap.large}>
|
||||
<Stack direction="row" justifyContent="space-between" alignItems="center">
|
||||
{loading ? (
|
||||
<>
|
||||
<Skeleton variant="rounded" width="50%" height={36} />
|
||||
<Skeleton variant="rounded" width="15%" height={36} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{loading ? (
|
||||
<SkeletonLayout />
|
||||
) : (
|
||||
<>
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
>
|
||||
<Typography component="h1">
|
||||
Hello, {authState.user.firstName}
|
||||
</Typography>
|
||||
@@ -227,60 +260,37 @@ const Monitors = () => {
|
||||
navigate("/monitors/create");
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
<Stack
|
||||
gap={theme.gap.large}
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
>
|
||||
{loading ? (
|
||||
<>
|
||||
<Skeleton variant="rounded" width="100%" height={100} />
|
||||
<Skeleton variant="rounded" width="100%" height={100} />
|
||||
<Skeleton variant="rounded" width="100%" height={100} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
</Stack>
|
||||
<Stack
|
||||
gap={theme.gap.large}
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<ServerStatus title="Up" value={up} state="up" />
|
||||
<ServerStatus title="Down" value={down} state="down" />
|
||||
<ServerStatus title="Paused" value={0} state="pause" />
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
<Stack
|
||||
gap={theme.gap.large}
|
||||
p={theme.gap.xl}
|
||||
border={1}
|
||||
borderColor={
|
||||
loading ? "#f9fafb" : theme.palette.otherColors.graishWhite
|
||||
}
|
||||
backgroundColor={loading ? "#f9fafb" : "white"}
|
||||
sx={{
|
||||
borderRadius: `${theme.shape.borderRadius}px`,
|
||||
}}
|
||||
>
|
||||
{loading ? (
|
||||
<Skeleton variant="rounded" width="50%" height={25} />
|
||||
) : (
|
||||
<Stack direction="row" alignItems="center">
|
||||
<Typography component="h2">Current monitors</Typography>
|
||||
<Box className="current-monitors-counter">
|
||||
{monitorState.monitors.length}
|
||||
</Box>
|
||||
{/* TODO - add search bar */}
|
||||
</Stack>
|
||||
)}
|
||||
{loading ? (
|
||||
<>
|
||||
<Skeleton variant="rounded" width="100%" height={400} />
|
||||
<Skeleton variant="rounded" width="100%" height={100} />
|
||||
</>
|
||||
) : (
|
||||
<BasicTable data={data} paginated={true} />
|
||||
)}
|
||||
</Stack>
|
||||
<Stack
|
||||
gap={theme.gap.large}
|
||||
p={theme.gap.xl}
|
||||
border={1}
|
||||
borderColor={theme.palette.otherColors.graishWhite}
|
||||
backgroundColor={theme.palette.otherColors.white}
|
||||
sx={{
|
||||
borderRadius: `${theme.shape.borderRadius}px`,
|
||||
}}
|
||||
>
|
||||
<Stack direction="row" alignItems="center">
|
||||
<Typography component="h2">Current monitors</Typography>
|
||||
<Box className="current-monitors-counter">
|
||||
{monitorState.monitors.length}
|
||||
</Box>
|
||||
{/* TODO - add search bar */}
|
||||
</Stack>
|
||||
<BasicTable data={data} paginated={true} />
|
||||
</Stack>
|
||||
</>
|
||||
)}
|
||||
<Menu
|
||||
className="actions-menu"
|
||||
anchorEl={anchorEl}
|
||||
|
||||
@@ -126,6 +126,53 @@ const PieValueLabel = ({ value, startAngle, endAngle, color, highlighted }) => {
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a skeleton layout.
|
||||
*
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
const SkeletonLayout = () => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Skeleton variant="rounded" width="15%" height={34} />
|
||||
<Stack direction="row" gap={theme.gap.small}>
|
||||
<Skeleton variant="circular" style={{ minWidth: 24, minHeight: 24 }} />
|
||||
<Box width="80%">
|
||||
<Skeleton variant="rounded" width="50%" height={24} />
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="50%"
|
||||
height={18}
|
||||
sx={{ mt: theme.gap.small }}
|
||||
/>
|
||||
</Box>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="15%"
|
||||
height={34}
|
||||
sx={{ alignSelf: "flex-end" }}
|
||||
/>
|
||||
</Stack>
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
gap={theme.gap.xl}
|
||||
flexWrap="wrap"
|
||||
>
|
||||
<Skeleton variant="rounded" width="30%" height={90} sx={{ flex: 1 }} />
|
||||
<Skeleton variant="rounded" width="30%" height={90} sx={{ flex: 1 }} />
|
||||
<Skeleton variant="rounded" width="30%" height={90} sx={{ flex: 1 }} />
|
||||
</Stack>
|
||||
<Skeleton variant="rounded" width="25%" height={24} />
|
||||
<Skeleton variant="rounded" width="100%" height={300} />
|
||||
<Skeleton variant="rounded" width="25%" height={24} />
|
||||
<Skeleton variant="rounded" width="100%" height={300} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const PageSpeedDetails = () => {
|
||||
const theme = useTheme();
|
||||
const navigate = useNavigate();
|
||||
@@ -254,50 +301,26 @@ const PageSpeedDetails = () => {
|
||||
return (
|
||||
<Stack className="page-speed-details" gap={theme.gap.large}>
|
||||
{loading ? (
|
||||
<Skeleton variant="rounded" width="15%" height={34} />
|
||||
<SkeletonLayout />
|
||||
) : (
|
||||
<Button
|
||||
level="tertiary"
|
||||
label="Back"
|
||||
animate="slideLeft"
|
||||
img={<WestRoundedIcon />}
|
||||
onClick={() => navigate("/pagespeed")}
|
||||
sx={{
|
||||
width: "fit-content",
|
||||
backgroundColor: theme.palette.otherColors.fillGray,
|
||||
px: theme.gap.ml,
|
||||
"& svg.MuiSvgIcon-root": {
|
||||
mr: theme.gap.small,
|
||||
fill: theme.palette.otherColors.slateGray,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Stack direction="row" gap={theme.gap.small}>
|
||||
{loading ? (
|
||||
<>
|
||||
<Skeleton
|
||||
variant="circular"
|
||||
style={{ minWidth: 24, minHeight: 24 }}
|
||||
/>
|
||||
<Box width="80%">
|
||||
<Skeleton variant="rounded" width="50%" height={24} />
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="50%"
|
||||
height={18}
|
||||
sx={{ mt: theme.gap.small }}
|
||||
/>
|
||||
</Box>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="15%"
|
||||
height={34}
|
||||
sx={{ alignSelf: "flex-end" }}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<>
|
||||
<Button
|
||||
level="tertiary"
|
||||
label="Back"
|
||||
animate="slideLeft"
|
||||
img={<WestRoundedIcon />}
|
||||
onClick={() => navigate("/pagespeed")}
|
||||
sx={{
|
||||
width: "fit-content",
|
||||
backgroundColor: theme.palette.otherColors.fillGray,
|
||||
px: theme.gap.ml,
|
||||
"& svg.MuiSvgIcon-root": {
|
||||
mr: theme.gap.small,
|
||||
fill: theme.palette.otherColors.slateGray,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<Stack direction="row" gap={theme.gap.small}>
|
||||
<GreenCheck />
|
||||
<Box>
|
||||
<Typography
|
||||
@@ -334,38 +357,13 @@ const PageSpeedDetails = () => {
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
gap={theme.gap.xl}
|
||||
flexWrap="wrap"
|
||||
>
|
||||
{loading ? (
|
||||
<>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="30%"
|
||||
height={90}
|
||||
sx={{ flex: 1 }}
|
||||
/>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="30%"
|
||||
height={90}
|
||||
sx={{ flex: 1 }}
|
||||
/>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="30%"
|
||||
height={90}
|
||||
sx={{ flex: 1 }}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
</Stack>
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
gap={theme.gap.xl}
|
||||
flexWrap="wrap"
|
||||
>
|
||||
<StatBox
|
||||
icon={<LastCheckedIcon />}
|
||||
title="Last checked"
|
||||
@@ -408,31 +406,13 @@ const PageSpeedDetails = () => {
|
||||
title="Checks every"
|
||||
value={formatDurationRounded(monitor?.interval)}
|
||||
></StatBox>
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
{loading ? (
|
||||
<>
|
||||
<Skeleton variant="rounded" width="25%" height={24} />
|
||||
<Skeleton variant="rounded" width="100%" height={300} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
</Stack>
|
||||
<Typography component="h2">Score history</Typography>
|
||||
<Box height="300px">
|
||||
<PageSpeedLineChart
|
||||
pageSpeedChecks={monitor?.checks?.slice(0, 25)}
|
||||
/>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
{loading ? (
|
||||
<>
|
||||
<Skeleton variant="rounded" width="25%" height={24} />
|
||||
<Skeleton variant="rounded" width="100%" height={300} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Typography component="h2">Performance report</Typography>
|
||||
<Stack direction="row" alignItems="center" overflow="hidden">
|
||||
<Stack
|
||||
|
||||
@@ -57,6 +57,67 @@ const Card = ({ data }) => {
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a skeleton layout.
|
||||
*
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
const SkeletonLayout = () => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<Stack gap={theme.gap.xs}>
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
mb={theme.gap.large}
|
||||
>
|
||||
<Box width="80%">
|
||||
<Skeleton variant="rounded" width="25%" height={24} />
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="50%"
|
||||
height={19.5}
|
||||
sx={{ mt: theme.gap.xs }}
|
||||
/>
|
||||
</Box>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="20%"
|
||||
height={34}
|
||||
sx={{ alignSelf: "flex-end" }}
|
||||
/>
|
||||
</Stack>
|
||||
<Stack direction="row" flexWrap="wrap" gap={theme.gap.large}>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="100%"
|
||||
height={120}
|
||||
sx={{ flex: "35%" }}
|
||||
/>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="100%"
|
||||
height={120}
|
||||
sx={{ flex: "35%" }}
|
||||
/>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="100%"
|
||||
height={120}
|
||||
sx={{ flex: "35%" }}
|
||||
/>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="100%"
|
||||
height={120}
|
||||
sx={{ flex: "35%" }}
|
||||
/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
const PageSpeed = () => {
|
||||
const theme = useTheme();
|
||||
const dispatch = useDispatch();
|
||||
@@ -77,55 +138,7 @@ const PageSpeed = () => {
|
||||
return (
|
||||
<Box className="page-speed">
|
||||
{isActuallyLoading ? (
|
||||
<Stack gap={theme.gap.xs}>
|
||||
<Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
mb={theme.gap.large}
|
||||
>
|
||||
<Box width="80%">
|
||||
<Skeleton variant="rounded" width="25%" height={24} />
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="50%"
|
||||
height={19.5}
|
||||
sx={{ mt: theme.gap.xs }}
|
||||
/>
|
||||
</Box>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="20%"
|
||||
height={34}
|
||||
sx={{ alignSelf: "flex-end" }}
|
||||
/>
|
||||
</Stack>
|
||||
<Stack direction="row" flexWrap="wrap" gap={theme.gap.large}>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="100%"
|
||||
height={120}
|
||||
sx={{ flex: "35%" }}
|
||||
/>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="100%"
|
||||
height={120}
|
||||
sx={{ flex: "35%" }}
|
||||
/>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="100%"
|
||||
height={120}
|
||||
sx={{ flex: "35%" }}
|
||||
/>
|
||||
<Skeleton
|
||||
variant="rounded"
|
||||
width="100%"
|
||||
height={120}
|
||||
sx={{ flex: "35%" }}
|
||||
/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
<SkeletonLayout />
|
||||
) : monitors?.length !== 0 ? (
|
||||
<Stack gap={theme.gap.xs}>
|
||||
<Stack
|
||||
|
||||
Reference in new issue
Block a user