Improve Latest Incidents panel layout

- Simplify incident rows to single line with grid layout
- Remove redundant "Monitor:" and "Status:" labels
- Align columns vertically (monitor name, status badge, duration)
- Center-align status badge column
- Match icon styling with General Statistics (18px, strokeWidth 1.5)
- Remove pointer cursor (click not implemented)
- Add dividers and minHeight to Statistics panel for alignment
This commit is contained in:
gorkem-bwl
2026-01-15 21:19:34 -05:00
parent 54ecf02d9a
commit c60d07c3a0
2 changed files with 83 additions and 124 deletions
@@ -4,7 +4,6 @@ import { useTheme } from "@emotion/react";
import { StatusLabel } from "@/Components/v1/Label/index.jsx";
import { getHumanReadableDuration } from "@/Utils/timeUtils.js";
import Monitors from "@/assets/icons/monitors.svg?react";
import AverageResponseIcon from "@/assets/icons/status-pages.svg?react";
import { useTranslation } from "react-i18next";
const IncidentItem = ({ incident }) => {
@@ -37,101 +36,65 @@ const IncidentItem = ({ incident }) => {
const duration = calculateDuration();
const iconWrapperStyle = {
px: theme.spacing(2),
display: "flex",
justifyContent: "center",
mx: theme.spacing(2),
color: theme.palette.primary.contrastTextTertiary,
"& svg": {
width: 18,
height: 18,
},
"& svg path": {
stroke: "currentColor",
strokeWidth: 1.5,
},
};
return (
<Box
sx={{
cursor: "pointer",
display: "grid",
gridTemplateColumns: "1fr 100px 80px",
alignItems: "center",
gap: theme.spacing(2),
width: "100%",
py: theme.spacing(0.5),
"&:hover": { opacity: 0.8 },
}}
>
<Stack
direction="column"
gap={theme.spacing(1.5)}
direction="row"
alignItems="center"
gap={theme.spacing(2)}
>
<Stack
direction="row"
alignItems="center"
gap={theme.spacing(1)}
<Box sx={iconWrapperStyle}>
<Monitors />
</Box>
<Typography
variant="body1"
fontWeight={500}
noWrap
>
<Box
sx={{
...iconWrapperStyle,
}}
>
<Monitors />
</Box>
<Stack
direction="row"
gap={theme.spacing(4)}
alignItems="baseline"
>
<Typography variant="body1">
{t("incidentsPage.incidentItemMonitor")}:
</Typography>
<Typography
variant="body1"
fontWeight={600}
>
{incident.monitorName || t("incidentsPage.unknownMonitor")}
</Typography>
</Stack>
</Stack>
<Stack
direction="row"
alignItems="center"
width="100%"
marginTop={theme.spacing(1)}
>
<Stack
direction="row"
alignItems="center"
gap={theme.spacing(3)}
>
<Box sx={{ ...iconWrapperStyle }}>
<AverageResponseIcon />
</Box>
<Stack
direction="row"
alignItems="center"
spacing={2}
>
<Typography variant="body1">
{t("incidentsPage.incidentItemStatus")}:
</Typography>
</Stack>
<StatusLabel
status={isActive ? "down" : "up"}
text={isActive ? t("incidentsPage.active") : t("incidentsPage.resolved")}
customStyles={{
textTransform: "capitalize",
}}
/>
</Stack>
<Box sx={{ flexGrow: 1 }} />
<Typography
variant="body1"
fontWeight={500}
>
{duration}
</Typography>
</Stack>
{incident.monitorName || t("incidentsPage.unknownMonitor")}
</Typography>
</Stack>
<Box sx={{ display: "flex", justifyContent: "center" }}>
<StatusLabel
status={isActive ? "down" : "up"}
text={isActive ? t("incidentsPage.active") : t("incidentsPage.resolved")}
customStyles={{
textTransform: "capitalize",
}}
/>
</Box>
<Typography
variant="body1"
fontWeight={500}
textAlign="right"
>
{duration}
</Typography>
</Box>
);
};
@@ -1,5 +1,5 @@
import PropTypes from "prop-types";
import { Box, Stack, Typography } from "@mui/material";
import { Box, Stack, Typography, Divider } from "@mui/material";
import { useTheme } from "@emotion/react";
import PanelSkeleton from "../IncidentsSummaryPanel/skeleton.jsx";
import { useTranslation } from "react-i18next";
@@ -86,74 +86,70 @@ const StatisticsPanel = ({ isLoading = false, error = null, summary = {} }) => {
return summary.topMonitor?.monitorName || t("incidentsPage.none");
};
const rowStyle = {
py: theme.spacing(0.5),
minHeight: 32,
};
return (
<SummaryCard title={t("incidentsPage.incidentsStatisticsPanelTitle")}>
<Stack gap={theme.spacing(4)}>
<Stack
direction="row"
alignItems="center"
gap={theme.spacing(3)}
>
<Box
sx={{
...iconWrapperStyle,
}}
<Box>
<Stack
direction="row"
alignItems="center"
gap={theme.spacing(2)}
sx={rowStyle}
>
<NotificationIcon />
</Box>
<Box>
<Box sx={iconWrapperStyle}>
<NotificationIcon />
</Box>
<Typography
variant="body1"
sx={{
fontWeight: 500,
lineHeight: 1.2,
}}
fontWeight={500}
>
{t("incidentsPage.totalIncidents")}: {summary.total || 0}
</Typography>
</Box>
</Stack>
<Stack
direction="row"
alignItems="center"
gap={theme.spacing(2)}
>
<Box sx={iconWrapperStyle}>
<Incidents />
</Box>
<Box>
</Stack>
<Divider sx={{ mt: theme.spacing(2) }} />
</Box>
<Box>
<Stack
direction="row"
alignItems="center"
gap={theme.spacing(2)}
sx={rowStyle}
>
<Box sx={iconWrapperStyle}>
<Incidents />
</Box>
<Typography
variant="body1"
sx={{
fontWeight: 500,
lineHeight: 1.2,
}}
fontWeight={500}
>
{t("incidentsPage.mostAffectedMonitor")}: {getMostAffectedMonitor()}
</Typography>
</Box>
</Stack>
</Stack>
<Divider sx={{ mt: theme.spacing(2) }} />
</Box>
<Stack
direction="row"
alignItems="center"
gap={theme.spacing(2)}
sx={rowStyle}
>
<Box sx={iconWrapperStyle}>
<Clock />
</Box>
<Box>
<Typography
variant="body1"
sx={{
fontWeight: 500,
}}
>
{t("incidentsPage.avgResolutionTime")}:{" "}
{summary.total > 0
? `${summary.avgResolutionTimeHours || 0} ${t("incidentsPage.hours")}`
: "N/A"}
</Typography>
</Box>
<Typography
variant="body1"
fontWeight={500}
>
{t("incidentsPage.avgResolutionTime")}:{" "}
{summary.total > 0
? `${summary.avgResolutionTimeHours || 0} ${t("incidentsPage.hours")}`
: "N/A"}
</Typography>
</Stack>
</Stack>
</SummaryCard>