Skip to content

Commit a0f0968

Browse files
committed
FEAT: server details
1 parent 57f5ab2 commit a0f0968

File tree

6 files changed

+134
-53
lines changed

6 files changed

+134
-53
lines changed

web/src/App.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const router = createBrowserRouter([
1212
element: <ServerList />,
1313
},
1414
{
15-
path: "/:id",
15+
path: "/:host",
1616
element: <ServerDetail />,
1717
},
1818
]);

web/src/AppHeader.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Toolbar from "@mui/material/Toolbar";
66
import Typography from "@mui/material/Typography";
77
import InputBase from "@mui/material/InputBase";
88
import SearchIcon from "@mui/icons-material/Search";
9+
import { Link } from "react-router-dom";
910

1011
const Search = styled("div")(({ theme }) => ({
1112
position: "relative",
@@ -62,6 +63,7 @@ export default function AppHeader() {
6263
>
6364
Saido
6465
</Typography>
66+
6567
<Search>
6668
<SearchIconWrapper>
6769
<SearchIcon />

web/src/common/ErrorContent.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from "react";
22
import { Typography } from "@mui/material";
33
import clsx from "clsx";
44
import SentimentVeryDissatisfiedIcon from "@mui/icons-material/SentimentVeryDissatisfied";
5+
import ThemeConfig from "../ThemeConfig";
56

67
interface ErrorContentType {
78
title: string;
@@ -20,6 +21,7 @@ function ErrorContent(props: ErrorContentType): JSX.Element {
2021

2122
return (
2223
<div
24+
style={{ color: ThemeConfig.palette.error.main }}
2325
className={clsx(
2426
"p-1 d-flex text-danger justify-content-center align-items-center flex-column w-100",
2527
className

web/src/server/ServerDetail.tsx

+53-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,56 @@
1-
import React from "react";
1+
import { Container } from "@mui/material";
2+
import React, { useState } from "react";
3+
import { useParams } from "react-router-dom";
4+
import useWebSocket, { ReadyState } from "react-use-websocket";
5+
import LoadingContent from "../common/LoadingContent";
6+
import {
7+
ServerGroupedByNameResponseType,
8+
ServerResponseType,
9+
} from "./ServerType";
210

11+
const wssMetricsBaseURL = `${process.env.REACT_APP_WS_BASE_URL}/metrics`;
312
export default function ServerDetail() {
4-
return <div>ServerDetail</div>;
13+
const { host } = useParams<{ host: string }>();
14+
15+
const [servers, setServers] = useState<ServerResponseType[]>([]);
16+
17+
const serversGroupedByName: ServerGroupedByNameResponseType[] =
18+
servers.reduce((group: any, server) => {
19+
const { Message } = server;
20+
const { Name } = Message;
21+
group[Name] = group[Name] ?? [];
22+
group[Name].push(server);
23+
return group;
24+
}, {});
25+
26+
console.log("serversGroupedByName", serversGroupedByName);
27+
28+
const { sendJsonMessage, readyState } = useWebSocket(wssMetricsBaseURL, {
29+
onOpen: () => console.log("WebSocket connection opened."),
30+
onClose: () => console.log("WebSocket connection closed."),
31+
shouldReconnect: (closeEvent) => true,
32+
onMessage: (event: WebSocketEventMap["message"]) => {
33+
const newMessage: ServerResponseType = JSON.parse(event.data);
34+
setServers((prev) => prev.concat(newMessage));
35+
},
36+
});
37+
38+
sendJsonMessage({ FilterBy: host });
39+
40+
const connectionStatus: string = {
41+
[ReadyState.CONNECTING]: "Connecting",
42+
[ReadyState.OPEN]: "Open",
43+
[ReadyState.CLOSING]: "Closing",
44+
[ReadyState.CLOSED]: "Closed",
45+
[ReadyState.UNINSTANTIATED]: "Uninstantiated",
46+
}[readyState];
47+
48+
return (
49+
<Container>
50+
<LoadingContent
51+
loading={connectionStatus === "Connecting"}
52+
error={connectionStatus === "Closed"}
53+
></LoadingContent>
54+
</Container>
55+
);
556
}

web/src/server/ServerList.tsx

+67-49
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,42 @@
11
import { Card, CardActionArea, Grid, Typography } from "@mui/material";
22
import { Box, Container } from "@mui/system";
33
import React, { useState } from "react";
4+
import { useNavigate } from "react-router-dom";
45
import useWebSocket, { ReadyState } from "react-use-websocket";
5-
import { ReactComponent as ServerIcon } from "../assets/svg/server.svg";
6-
import LoadingContent from "../common/LoadingContent";
7-
import ThemeConfig from "../ThemeConfig";
8-
import { ServerResponse } from "./ServerType";
6+
import { ReactComponent as ServerIcon } from "assets/svg/server.svg";
7+
import LoadingContent from "common/LoadingContent";
8+
import ThemeConfig from "ThemeConfig";
9+
import {
10+
ServerGroupedByHostResponseType,
11+
ServerResponseType,
12+
} from "./ServerType";
13+
14+
const wssMetricsBaseURL = `${process.env.REACT_APP_WS_BASE_URL}/metrics`;
915

1016
export default function ServerList() {
11-
const [servers, setServers] = useState<ServerResponse[]>([]);
12-
const { sendJsonMessage, getWebSocket, readyState } = useWebSocket(
13-
`ws://localhost:3000/metrics`,
14-
{
15-
onOpen: () => console.log("WebSocket connection opened."),
16-
onClose: () => console.log("WebSocket connection closed."),
17-
shouldReconnect: (closeEvent) => true,
18-
onMessage: (event: WebSocketEventMap["message"]) => {
19-
const newMessage: ServerResponse = JSON.parse(event.data);
20-
setServers((prev: ServerResponse[]) => {
21-
if (!newMessage.Error) {
22-
return prev.concat(newMessage);
23-
}
24-
});
25-
},
26-
}
17+
const navigate = useNavigate();
18+
19+
const [servers, setServers] = useState<ServerResponseType[]>([]);
20+
const serversGroupedByHost: ServerGroupedByHostResponseType = servers.reduce(
21+
(group: any, server) => {
22+
const { Message } = server;
23+
const { Host } = Message;
24+
group[Host] = group[Host] ?? [];
25+
group[Host].push(server);
26+
return group;
27+
},
28+
{}
2729
);
28-
getWebSocket();
30+
31+
const { readyState } = useWebSocket(wssMetricsBaseURL, {
32+
onOpen: () => console.log("WebSocket connection opened."),
33+
onClose: () => console.log("WebSocket connection closed."),
34+
shouldReconnect: (closeEvent) => true,
35+
onMessage: (event: WebSocketEventMap["message"]) => {
36+
const newMessage: ServerResponseType = JSON.parse(event.data);
37+
setServers((prev) => prev.concat(newMessage));
38+
},
39+
});
2940

3041
const connectionStatus: string = {
3142
[ReadyState.CONNECTING]: "Connecting",
@@ -35,42 +46,49 @@ export default function ServerList() {
3546
[ReadyState.UNINSTANTIATED]: "Uninstantiated",
3647
}[readyState];
3748

38-
console.log(servers);
39-
// console.log("getWebsocket", getWebSocket()?.OPEN);
4049
return (
4150
<Container>
4251
<LoadingContent
4352
loading={connectionStatus === "Connecting"}
4453
error={connectionStatus === "Closed"}
4554
>
4655
<Grid container spacing={2} my={10}>
47-
{servers.map((server: any, index: number) => (
48-
<Grid item xs={6} md={4}>
49-
<Card key={index}>
50-
<CardActionArea>
51-
<Box
52-
display={"flex"}
53-
justifyContent="center"
54-
alignItems="center"
55-
flexDirection="column"
56-
>
57-
<ServerIcon width={"100px"} />
58-
<Typography
59-
textTransform={"capitalize"}
60-
mb={2}
61-
noWrap
62-
fontWeight={600}
56+
{Object.keys(serversGroupedByHost)?.map(
57+
(serverHost: string, index: number) => (
58+
<Grid item xs={6} md={4}>
59+
<Card key={index}>
60+
<CardActionArea onClick={() => navigate(`/${serverHost}`)}>
61+
<Box
62+
display={"flex"}
63+
justifyContent="center"
64+
alignItems="center"
65+
flexDirection="column"
6366
>
64-
localhost -{" "}
65-
<span style={{ color: ThemeConfig.palette.success.dark }}>
66-
linux
67-
</span>
68-
</Typography>
69-
</Box>
70-
</CardActionArea>
71-
</Card>
72-
</Grid>
73-
))}
67+
<ServerIcon width={"100px"} />
68+
<Typography
69+
textTransform={"capitalize"}
70+
mb={2}
71+
noWrap
72+
fontWeight={600}
73+
>
74+
<>
75+
{serverHost} -{" "}
76+
<span
77+
style={{ color: ThemeConfig.palette.success.dark }}
78+
>
79+
{
80+
serversGroupedByHost[serverHost]?.[0]?.Message
81+
?.Platform
82+
}
83+
</span>
84+
</>
85+
</Typography>
86+
</Box>
87+
</CardActionArea>
88+
</Card>
89+
</Grid>
90+
)
91+
)}
7492
</Grid>
7593
</LoadingContent>
7694
</Container>

web/src/server/ServerType.tsx

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export interface ServerResponse {
1+
export interface ServerResponseType {
22
Error: boolean;
33
Message: {
44
Host: string;
@@ -14,3 +14,11 @@ export interface ServerResponse {
1414
Data: Object;
1515
};
1616
}
17+
18+
export interface ServerGroupedByHostResponseType {
19+
[Host: string]: ServerResponseType[];
20+
}
21+
22+
export interface ServerGroupedByNameResponseType {
23+
[Name: string]: ServerResponseType[];
24+
}

0 commit comments

Comments
 (0)