Merge pull request #3968 from bluewave-labs/feat/dashboard-add-redux-state

feat: remove mock data and add redux state to dashboard page
This commit is contained in:
Alexander Holliday authored and GitHub committed 2026-09-17 12:08:30 -07:00
commit 87eab6f996
6 files changed
+53 -31

No files matched your search

@@ -9,19 +9,27 @@ import { useTranslation } from "react-i18next";
import type { MonitorsSummary } from "@/Types/Monitor";
interface MonitorStatusCardProps {
summary: MonitorsSummary;
summary: MonitorsSummary | null;
}
export const MonitorStatusCard = ({ summary }: MonitorStatusCardProps) => {
const theme = useTheme();
const { t } = useTranslation();
const up = summary.upMonitors;
const total = summary.totalMonitors;
const up = summary?.upMonitors ?? 0;
const total = summary?.totalMonitors ?? 0;
const ratio = total > 0 ? up / total : 0;
return (
<DashboardCard title={t("pages.dashboard.cards.monitorStatus")}>
{total === 0 ? (
<Typography
fontSize={typographyLevels.m}
color={theme.palette.text.disabled}
>
{t("pages.dashboard.noData")}
</Typography>
) : (
<Stack gap={theme.spacing(SPACING.SM)}>
<Stack
direction="row"
@@ -44,6 +52,7 @@ export const MonitorStatusCard = ({ summary }: MonitorStatusCardProps) => {
</Stack>
<ProgressBar fillRatio={ratio} />
</Stack>
)}
</DashboardCard>
);
};
@@ -1,14 +1,16 @@
import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
import { DashboardCard } from "@/Pages/Dashboard/components/DashboardCard";
import { BarRow } from "@/Pages/Dashboard/components/cards/BarRow";
import { useTranslation } from "react-i18next";
import { useTheme } from "@mui/material/styles";
import type { DashboardTypeCount } from "@/Pages/Dashboard/types";
import type { MonitorTypeCount } from "@/Types/Monitor";
import { getMonitorTypeLabel } from "@/Types/Monitor";
import { LAYOUT } from "@/Utils/Theme/constants";
import { typographyLevels } from "@/Utils/Theme/Palette";
interface MonitorsByTypeCardProps {
monitorsByType: DashboardTypeCount[];
monitorsByType: MonitorTypeCount[];
}
export const MonitorsByTypeCard = ({ monitorsByType }: MonitorsByTypeCardProps) => {
@@ -19,6 +21,14 @@ export const MonitorsByTypeCard = ({ monitorsByType }: MonitorsByTypeCardProps)
return (
<DashboardCard title={t("pages.dashboard.cards.monitorsByType")}>
{monitorsByType.length === 0 ? (
<Typography
fontSize={typographyLevels.m}
color={theme.palette.text.disabled}
>
{t("pages.dashboard.noData")}
</Typography>
) : (
<Stack gap={theme.spacing(LAYOUT.SM)}>
{monitorsByType.map(({ type, count }) => (
<BarRow
@@ -30,6 +40,7 @@ export const MonitorsByTypeCard = ({ monitorsByType }: MonitorsByTypeCardProps)
/>
))}
</Stack>
)}
</DashboardCard>
);
};
+22 -20
View File
@@ -1,32 +1,34 @@
import { useMemo } from "react";
import Box from "@mui/material/Box";
import { useTheme } from "@mui/material/styles";
import { BasePage } from "@/Components/design-elements/BasePage";
import { LAYOUT } from "@/Utils/Theme/constants";
import { useMonitorListController } from "@/Hooks/useMonitorListController";
import { MonitorTypes, type MonitorTypeCount } from "@/Types/Monitor";
import { MonitorStatusCard } from "@/Pages/Dashboard/components/cards/MonitorStatusCard";
import { MonitorsByTypeCard } from "@/Pages/Dashboard/components/cards/MonitorsByTypeCard";
import type { MonitorsSummary } from "@/Types/Monitor";
import type { DashboardTypeCount } from "@/Pages/Dashboard/types";
const MOCK_SUMMARY: MonitorsSummary = {
totalMonitors: 12,
upMonitors: 10,
downMonitors: 1,
pausedMonitors: 1,
initializingMonitors: 0,
maintenanceMonitors: 0,
breachedMonitors: 0,
};
const MOCK_MONITORS_BY_TYPE: DashboardTypeCount[] = [
{ type: "http", count: 7 },
{ type: "ping", count: 3 },
{ type: "port", count: 2 },
];
const Dashboard = () => {
const theme = useTheme();
const { monitors, summary } = useMonitorListController({
types: [...MonitorTypes],
checksLimit: 1,
refreshInterval: 30000,
rowsPerPageTable: "monitors",
rowsPerPageDefault: 100,
});
const monitorsByType = useMemo<MonitorTypeCount[]>(() => {
const countMap = new Map<MonitorTypeCount["type"], number>();
(monitors ?? []).forEach((m) =>
countMap.set(m.type, (countMap.get(m.type) ?? 0) + 1)
);
return [...countMap.entries()]
.map(([type, count]) => ({ type, count }))
.sort((a, b) => b.count - a.count);
}, [monitors]);
return (
<BasePage headerKey="dashboard">
@@ -35,8 +37,8 @@ const Dashboard = () => {
gridTemplateColumns={{ xs: "1fr", md: "1fr 1fr" }}
gap={theme.spacing(LAYOUT.MD)}
>
<MonitorStatusCard summary={MOCK_SUMMARY} />
<MonitorsByTypeCard monitorsByType={MOCK_MONITORS_BY_TYPE} />
<MonitorStatusCard summary={summary} />
<MonitorsByTypeCard monitorsByType={monitorsByType} />
</Box>
</BasePage>
);
-6
View File
@@ -1,6 +0,0 @@
import type { MonitorType } from "@/Types/Monitor";
export interface DashboardTypeCount {
type: MonitorType;
count: number;
}
+5
View File
@@ -192,6 +192,11 @@ export interface MonitorsSummary {
breachedMonitors: number;
}
export interface MonitorTypeCount {
type: MonitorType;
count: number;
}
export interface MonitorsWithChecksResponse {
count: number;
monitors: MonitorWithChecks[];
+1
View File
@@ -1911,6 +1911,7 @@
}
},
"dashboard": {
"noData": "No data available at this moment.",
"monitorStatus": {
"ofUp": "of {{total}} up"
},