Skip to content

Commit 66c4061

Browse files
committed
check details base
1 parent d139e0b commit 66c4061

File tree

9 files changed

+112
-47
lines changed

9 files changed

+112
-47
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
AGENTS.md
55
*.sh
66
notes
7-
docker-compose.yml
7+
docker-compose.yml
8+
mongo

client/src/components/design-elements/BasePage.tsx

Lines changed: 36 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,42 @@ import type { StackProps } from "@mui/material/Stack";
77
import { useTheme } from "@mui/material/styles";
88
import { useTranslation } from "react-i18next";
99
interface BasePageProps extends StackProps {
10+
loading?: boolean;
11+
error?: boolean;
1012
children: React.ReactNode;
1113
breadcrumbOverride?: string[];
1214
}
1315

1416
export const BasePage = ({
17+
loading,
18+
error,
1519
children,
1620
breadcrumbOverride,
1721
...props
1822
}: BasePageProps) => {
1923
const theme = useTheme();
24+
25+
if (loading) {
26+
return (
27+
<Stack
28+
alignItems="center"
29+
justifyContent="center"
30+
sx={{ height: "100%" }}
31+
>
32+
<CircularProgress color="primary" size={28} />
33+
</Stack>
34+
);
35+
}
36+
37+
if (error) {
38+
return (
39+
<ErrorFallback
40+
title="Something went wrong..."
41+
subtitle="Please try again later"
42+
/>
43+
);
44+
}
45+
2046
return (
2147
<Stack spacing={theme.spacing(10)} {...props}>
2248
<Breadcrumb breadcrumbOverride={breadcrumbOverride} />
@@ -49,27 +75,6 @@ export const BasePageWithStates = ({
4975
}: BasePageWithStatesProps) => {
5076
const showLoading = loading && (!items || items.length === 0);
5177

52-
if (showLoading) {
53-
return (
54-
<Stack
55-
alignItems="center"
56-
justifyContent="center"
57-
sx={{ height: "100%" }}
58-
>
59-
<CircularProgress color="primary" size={28} />
60-
</Stack>
61-
);
62-
}
63-
64-
if (error) {
65-
return (
66-
<ErrorFallback
67-
title="Something went wrong..."
68-
subtitle="Please try again later"
69-
/>
70-
);
71-
}
72-
7378
if (isEmpty(items)) {
7479
return (
7580
<EmptyFallback
@@ -81,7 +86,11 @@ export const BasePageWithStates = ({
8186
);
8287
}
8388

84-
return <BasePage {...props}>{children}</BasePage>;
89+
return (
90+
<BasePage loading={showLoading} error={error} {...props}>
91+
{children}
92+
</BasePage>
93+
);
8594
};
8695

8796
interface MonitorBasePageWithStatesProps extends StackProps {
@@ -114,27 +123,6 @@ export const MonitorBasePageWithStates = ({
114123

115124
const showLoading = loading && (!items || items.length === 0);
116125

117-
if (showLoading) {
118-
return (
119-
<Stack
120-
alignItems="center"
121-
justifyContent="center"
122-
sx={{ height: "100%" }}
123-
>
124-
<CircularProgress color="primary" size={28} />
125-
</Stack>
126-
);
127-
}
128-
129-
if (error) {
130-
return (
131-
<ErrorFallback
132-
title="Something went wrong..."
133-
subtitle="Please try again later"
134-
/>
135-
);
136-
}
137-
138126
if (isEmpty(items)) {
139127
return (
140128
<EmptyMonitorFallback
@@ -148,5 +136,9 @@ export const MonitorBasePageWithStates = ({
148136
);
149137
}
150138

151-
return <BasePage {...props}>{children}</BasePage>;
139+
return (
140+
<BasePage loading={showLoading} error={error} {...props}>
141+
{children}
142+
</BasePage>
143+
);
152144
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { BasePage } from "@/components/design-elements";
2+
3+
import { useParams } from "react-router";
4+
import { useGet } from "@/hooks/UseApi";
5+
import type { ICheck } from "@/types/check";
6+
import type { ApiResponse } from "@/types/api";
7+
const CheckDetails = () => {
8+
const { id } = useParams();
9+
const { response, loading, error } = useGet<ApiResponse<ICheck>>(
10+
`/checks/${id}`
11+
);
12+
13+
const check = response?.data;
14+
return (
15+
<BasePage loading={loading} error={error}>
16+
{JSON.stringify(check)}
17+
</BasePage>
18+
);
19+
};
20+
21+
export default CheckDetails;

client/src/pages/uptime/CheckTable.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { ICheck, IChecksWithCount } from "@/types/check";
66
import type { ApiResponse } from "@/types/api";
77
import type { MonitorStatus } from "@/types/monitor";
88

9+
import { useNavigate } from "react-router";
910
import { useState } from "react";
1011
import { useTranslation } from "react-i18next";
1112
import { useGet } from "@/hooks/UseApi";
@@ -51,6 +52,7 @@ const getHeaders = (t: Function, uiTimezone: string) => {
5152
};
5253

5354
export const CheckTable = ({ monitorId }: { monitorId: string }) => {
55+
const navigate = useNavigate();
5456
const [page, setPage] = useState(0);
5557
const [rowsPerPage, setRowsPerPage] = useState(5);
5658
const { t } = useTranslation();
@@ -87,7 +89,13 @@ export const CheckTable = ({ monitorId }: { monitorId: string }) => {
8789

8890
return (
8991
<Box>
90-
<Table headers={headers} data={checks} />
92+
<Table
93+
headers={headers}
94+
data={checks}
95+
onRowClick={(row) => {
96+
navigate(`/checks/${row._id}`);
97+
}}
98+
/>
9199
<Pagination
92100
component="div"
93101
count={count}

client/src/pages/uptime/UptimeMonitors.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ const UptimeMonitors = () => {
119119

120120
return (
121121
<MonitorBasePageWithStates
122-
loading={loading}
122+
loading={true}
123123
error={error}
124124
items={monitorItems}
125125
page="uptime"

client/src/routes/Router.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import NotificationChannelsConfigPage from "@/pages/notification-channels/Notifi
2121
import IncidentsPage from "@/pages/incidents/IncidentsPage";
2222
import IncidentDetailsPage from "@/pages/incidents/IncidentDetails";
2323
import ChecksPage from "@/pages/checks/ChecksPage";
24+
import CheckDetails from "@/pages/checks/CheckDetails";
2425
import PageSpeedMonitorsPage from "@/pages/pagespeed/PageSpeedMonitors";
2526
import PageSpeedDetailsPage from "@/pages/pagespeed/PageSpeedDetails";
2627
import PageSpeedConfigurePage from "@/pages/pagespeed/PageSpeedConfig";
@@ -121,6 +122,7 @@ const Router = () => {
121122
<Route path="incidents" element={<IncidentsPage />} />
122123
<Route path="incidents/:id" element={<IncidentDetailsPage />} />
123124
<Route path="checks" element={<ChecksPage />} />
125+
<Route path="checks/:id" element={<CheckDetails />} />
124126
<Route path="pagespeed/create" element={<PageSpeedCreatePage />} />
125127
<Route
126128
path="pagespeed/:id/configure"

server/src/controllers/ChecksController.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { CheckService } from "@/services/index.js";
44

55
export interface IChecksController {
66
getChecksByStatus: (req: Request, res: Response, next: NextFunction) => void;
7+
getCheckById: (req: Request, res: Response, next: NextFunction) => void;
78
}
89

910
class ChecksController implements IChecksController {
@@ -53,6 +54,30 @@ class ChecksController implements IChecksController {
5354
next(error);
5455
}
5556
};
57+
58+
getCheckById = async (req: Request, res: Response, next: NextFunction) => {
59+
try {
60+
const userContext = req.user;
61+
if (!userContext) {
62+
return res.status(401).json({ message: "Unauthorized" });
63+
}
64+
65+
const teamId = userContext.currentTeamId;
66+
if (!teamId) {
67+
throw new ApiError("No team ID", 400);
68+
}
69+
70+
const checkId = req.params.id;
71+
const check = await this.checkService.getCheckById(checkId, teamId);
72+
73+
return res.status(200).json({
74+
message: "Check retrieved successfully",
75+
data: check,
76+
});
77+
} catch (error) {
78+
next(error);
79+
}
80+
};
5681
}
5782

5883
export default ChecksController;

server/src/routes/checks.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ class CheckRoutes {
2626
validateQuery(checksStatusIdQuerySchema),
2727
this.controller.getChecksByStatus
2828
);
29+
this.router.get(
30+
"/:id",
31+
verifyToken,
32+
addUserContext,
33+
verifyOrgPermission([PERMISSIONS.checks.read]),
34+
this.controller.getCheckById
35+
);
2936
};
3037

3138
getRouter() {

server/src/services/business/CheckService.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ export interface ICheckService {
3333
range: string
3434
) => Promise<{ checks: ICheck[]; count: number }>;
3535

36+
getCheckById: (checkId: string, teamId: string) => Promise<ICheck | null>;
37+
3638
cleanupOrphanedChecks: () => Promise<boolean>;
3739
}
3840

@@ -259,6 +261,13 @@ class CheckService implements ICheckService {
259261
]);
260262
return { checks, count };
261263
};
264+
265+
getCheckById = async (checkId: string, teamId: string) => {
266+
return await Check.findOne({
267+
_id: new mongoose.Types.ObjectId(checkId),
268+
"metadata.teamId": new mongoose.Types.ObjectId(teamId),
269+
});
270+
};
262271
}
263272

264273
export default CheckService;

0 commit comments

Comments
 (0)