|
@@ -1,6 +1,6 @@
|
|
import { useEffect, useMemo, useState } from "react";
|
|
import { useEffect, useMemo, useState } from "react";
|
|
import { useLockFn } from "ahooks";
|
|
import { useLockFn } from "ahooks";
|
|
-import { Box, Button, Paper, TextField } from "@mui/material";
|
|
|
|
|
|
+import { Box, Button, ButtonGroup, Paper, TextField } from "@mui/material";
|
|
import { Virtuoso } from "react-virtuoso";
|
|
import { Virtuoso } from "react-virtuoso";
|
|
import { useTranslation } from "react-i18next";
|
|
import { useTranslation } from "react-i18next";
|
|
import { closeAllConnections, getInformation } from "@/services/api";
|
|
import { closeAllConnections, getInformation } from "@/services/api";
|
|
@@ -10,6 +10,14 @@ import BaseEmpty from "@/components/base/base-empty";
|
|
|
|
|
|
const initConn = { uploadTotal: 0, downloadTotal: 0, connections: [] };
|
|
const initConn = { uploadTotal: 0, downloadTotal: 0, connections: [] };
|
|
|
|
|
|
|
|
+type IOderOpts = {
|
|
|
|
+ [key in string]: {
|
|
|
|
+ orderFunc(
|
|
|
|
+ connections: ApiType.ConnectionsItem[]
|
|
|
|
+ ): ApiType.ConnectionsItem[];
|
|
|
|
+ };
|
|
|
|
+};
|
|
|
|
+
|
|
const ConnectionsPage = () => {
|
|
const ConnectionsPage = () => {
|
|
const { t } = useTranslation();
|
|
const { t } = useTranslation();
|
|
|
|
|
|
@@ -22,6 +30,25 @@ const ConnectionsPage = () => {
|
|
);
|
|
);
|
|
}, [connData, filterText]);
|
|
}, [connData, filterText]);
|
|
|
|
|
|
|
|
+ const orderOpts: IOderOpts = {
|
|
|
|
+ Default: {
|
|
|
|
+ orderFunc: (list) => list,
|
|
|
|
+ },
|
|
|
|
+ // "Download Traffic": {
|
|
|
|
+ // orderFunc: (list) => list,
|
|
|
|
+ // },
|
|
|
|
+ // "Upload Traffic": {
|
|
|
|
+ // orderFunc: (list) => list,
|
|
|
|
+ // },
|
|
|
|
+ "Download Speed": {
|
|
|
|
+ orderFunc: (list) => list.sort((a, b) => b.curDownload! - a.curDownload!),
|
|
|
|
+ },
|
|
|
|
+ "Upload Speed": {
|
|
|
|
+ orderFunc: (list) => list.sort((a, b) => b.curUpload! - a.curUpload!),
|
|
|
|
+ },
|
|
|
|
+ };
|
|
|
|
+ const [curOrderOpt, setOrderOpt] = useState("Default");
|
|
|
|
+
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
let ws: WebSocket | null = null;
|
|
let ws: WebSocket | null = null;
|
|
|
|
|
|
@@ -61,13 +88,19 @@ const ConnectionsPage = () => {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- return { ...data, connections };
|
|
|
|
|
|
+ const orderedConnections =
|
|
|
|
+ orderOpts[curOrderOpt].orderFunc(connections);
|
|
|
|
+
|
|
|
|
+ return {
|
|
|
|
+ ...data,
|
|
|
|
+ connections: orderedConnections,
|
|
|
|
+ };
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
|
|
return () => ws?.close();
|
|
return () => ws?.close();
|
|
- }, []);
|
|
|
|
|
|
+ }, [curOrderOpt]);
|
|
|
|
|
|
const onCloseAll = useLockFn(closeAllConnections);
|
|
const onCloseAll = useLockFn(closeAllConnections);
|
|
|
|
|
|
@@ -122,7 +155,25 @@ const ConnectionsPage = () => {
|
|
/>
|
|
/>
|
|
</Box>
|
|
</Box>
|
|
|
|
|
|
- <Box height="calc(100% - 50px)">
|
|
|
|
|
|
+ <Box sx={{ mx: "12px", mb: 0.5 }}>
|
|
|
|
+ <ButtonGroup size="small" sx={{ width: "100%" }}>
|
|
|
|
+ {Object.keys(orderOpts).map((opt) => (
|
|
|
|
+ <Button
|
|
|
|
+ key={opt}
|
|
|
|
+ variant={opt === curOrderOpt ? "contained" : "outlined"}
|
|
|
|
+ onClick={() => setOrderOpt(opt)}
|
|
|
|
+ sx={{
|
|
|
|
+ fontSize: "0.5rem",
|
|
|
|
+ textTransform: "capitalize",
|
|
|
|
+ }}
|
|
|
|
+ >
|
|
|
|
+ {t(opt)}
|
|
|
|
+ </Button>
|
|
|
|
+ ))}
|
|
|
|
+ </ButtonGroup>
|
|
|
|
+ </Box>
|
|
|
|
+
|
|
|
|
+ <Box height="calc(100% - 50px - 30px)">
|
|
{filterConn.length > 0 ? (
|
|
{filterConn.length > 0 ? (
|
|
<Virtuoso
|
|
<Virtuoso
|
|
data={filterConn}
|
|
data={filterConn}
|