diff --git a/src/components/connection/connection-table.tsx b/src/components/connection/connection-table.tsx index 35dfdd6..7d6696f 100644 --- a/src/components/connection/connection-table.tsx +++ b/src/components/connection/connection-table.tsx @@ -1,6 +1,7 @@ import dayjs from "dayjs"; -import { useMemo } from "react"; +import { useMemo, useState } from "react"; import { DataGrid, GridColDef } from "@mui/x-data-grid"; +import { Snackbar } from "@mui/material"; import parseTraffic from "@/utils/parse-traffic"; interface Props { @@ -10,6 +11,10 @@ interface Props { const ConnectionTable = (props: Props) => { const { connections } = props; + const [openedDetail, setOpenedDetail] = useState( + null + ); + const columns: GridColDef[] = [ { field: "host", @@ -72,7 +77,7 @@ const ConnectionTable = (props: Props) => { { field: "process", headerName: "Process", - width: 120, + width: 480, disableColumnMenu: true, }, { @@ -121,24 +126,117 @@ const ConnectionTable = (props: Props) => { ulSpeed: each.curUpload, chains, rule, - process: metadata.process || metadata.processPath, + process: truncateStr( + metadata.process || metadata.processPath || "", + 16, + 56 + ), time: each.start, source: `${metadata.sourceIP}:${metadata.sourcePort}`, destinationIP: metadata.destinationIP, type: `${metadata.type}(${metadata.network})`, + + connectionData: each, }; }); }, [connections]); return ( - + <> + setOpenedDetail(e.row.connectionData)} + density="compact" + sx={{ border: "none", "div:focus": { outline: "none !important" } }} + hideFooter + /> + setOpenedDetail(null)} + message={ + openedDetail ? : null + } + /> + ); }; export default ConnectionTable; + +const truncateStr = (str: string, prefixLen: number, maxLen: number) => { + if (str.length <= maxLen) return str; + return ( + str.slice(0, prefixLen) + " ... " + str.slice(-(maxLen - prefixLen - 5)) + ); +}; + +const SingleConnectionDetail = ({ data }: { data: IConnectionsItem }) => { + const { metadata, rulePayload } = data; + const chains = [...data.chains].reverse().join(" / "); + const rule = rulePayload ? `${data.rule}(${rulePayload})` : data.rule; + const host = metadata.host + ? `${metadata.host}:${metadata.destinationPort}` + : `${metadata.destinationIP}:${metadata.destinationPort}`; + + return ( +
+
+ {" "} + Host: {host}{" "} +
+
+ {" "} + Download: {parseTraffic(data.download).join(" ")}{" "} +
+
+ {" "} + Upload: {parseTraffic(data.upload).join(" ")}{" "} +
+
+ {" "} + DL Speed:{" "} + {parseTraffic(data.curDownload ?? -1).join(" ") + "/s"}{" "} +
+
+ {" "} + UL Speed:{" "} + {parseTraffic(data.curUpload ?? -1).join(" ") + "/s"}{" "} +
+
+ {" "} + Chains: {chains}{" "} +
+
+ {" "} + Rule: {rule}{" "} +
+
+ {" "} + Process: {metadata.process}{" "} +
+
+ {" "} + ProcessPath: {metadata.processPath}{" "} +
+
+ {" "} + Time: {dayjs(data.start).fromNow()}{" "} +
+
+ {" "} + Source:{" "} + {`${metadata.sourceIP}:${metadata.sourcePort}`}{" "} +
+
+ {" "} + Destination IP: {metadata.destinationIP}{" "} +
+
+ {" "} + Type: {`${metadata.type}(${metadata.network})`}{" "} +
+
+ ); +};