summaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/Connections.css4
-rw-r--r--src/components/Connections.tsx85
2 files changed, 70 insertions, 19 deletions
diff --git a/src/components/Connections.css b/src/components/Connections.css
index bc69a62..55dd869 100644
--- a/src/components/Connections.css
+++ b/src/components/Connections.css
@@ -47,3 +47,7 @@
.react-tabs__tab-panel--selected {
display: block;
}
+
+._btn_lzu00_1 {
+ margin-right: 10px;
+}
diff --git a/src/components/Connections.tsx b/src/components/Connections.tsx
index fd29390..1e9602f 100644
--- a/src/components/Connections.tsx
+++ b/src/components/Connections.tsx
@@ -11,6 +11,7 @@ import { State } from '~/store/types';
import * as connAPI from '../api/connections';
import useRemainingViewPortHeight from '../hooks/useRemainingViewPortHeight';
import { getClashAPIConfig } from '../store/app';
+import Button from './Button';
import s from './Connections.module.scss';
import ConnectionTable from './ConnectionTable';
import ContentHeader from './ContentHeader';
@@ -58,22 +59,38 @@ function hasSubstring(s: string, pat: string) {
return s.toLowerCase().includes(pat.toLowerCase());
}
-function filterConns(conns: FormattedConn[], keyword: string) {
- return !keyword
- ? conns
- : conns.filter((conn) =>
- [
- conn.host,
- conn.sourceIP,
- conn.sourcePort,
- conn.destinationIP,
- conn.chains,
- conn.rule,
- conn.type,
- conn.network,
- conn.process,
- ].some((field) => hasSubstring(field, keyword))
+function filterConnIps(conns: FormattedConn[], ipStr: string) {
+ return conns.filter((each) => each.sourceIP === ipStr);
+}
+
+function filterConns(conns: FormattedConn[], keyword: string, sourceIp: string) {
+ let result = conns;
+ if (keyword !== '') {
+ result = conns.filter((conn) =>
+ [
+ conn.host,
+ conn.sourceIP,
+ conn.sourcePort,
+ conn.destinationIP,
+ conn.chains,
+ conn.rule,
+ conn.type,
+ conn.network,
+ conn.process,
+ ].some((field) => {
+ return hasSubstring(field, keyword);
+ })
);
+ }
+ if (sourceIp !== '') {
+ result = filterConnIps(result, sourceIp);
+ }
+
+ return result;
+}
+
+function getConnIpList(conns: FormattedConn[]) {
+ return Array.from(new Set(conns.map((x) => x.sourceIP))).sort();
}
function formatConnectionDataItem(
@@ -134,11 +151,19 @@ function ConnQty({ qty }) {
function Conn({ apiConfig }) {
const [refContainer, containerHeight] = useRemainingViewPortHeight();
+
const [conns, setConns] = useState([]);
const [closedConns, setClosedConns] = useState([]);
+
const [filterKeyword, setFilterKeyword] = useState('');
- const filteredConns = filterConns(conns, filterKeyword);
- const filteredClosedConns = filterConns(closedConns, filterKeyword);
+ const [filterSourceIpStr, setFilterSourceIpStr] = useState('');
+
+ const filteredConns = filterConns(conns, filterKeyword, filterSourceIpStr);
+ const filteredClosedConns = filterConns(closedConns, filterKeyword, filterSourceIpStr);
+
+ const connIpSet = getConnIpList(conns);
+ const ClosedConnIpSet = getConnIpList(closedConns);
+
const [isCloseAllModalOpen, setIsCloseAllModalOpen] = useState(false);
const openCloseAllModal = useCallback(() => setIsCloseAllModalOpen(true), []);
const closeCloseAllModal = useCallback(() => setIsCloseAllModalOpen(false), []);
@@ -230,7 +255,17 @@ function Conn({ apiConfig }) {
}}
>
<TabPanel>
- <>{renderTableOrPlaceholder(filteredConns)}</>
+ <Button onClick={() => setFilterSourceIpStr('')} kind="minimal">
+ {t('All')}
+ </Button>
+ {connIpSet.map((value, k) => {
+ return (
+ <Button key={k} onClick={() => setFilterSourceIpStr(value)} kind="minimal">
+ {value}
+ </Button>
+ );
+ })}
+ {renderTableOrPlaceholder(filteredConns)}
<Fab
icon={isRefreshPaused ? <Play size={16} /> : <Pause size={16} />}
mainButtonStyles={isRefreshPaused ? { background: '#e74c3c' } : {}}
@@ -243,7 +278,19 @@ function Conn({ apiConfig }) {
</Action>
</Fab>
</TabPanel>
- <TabPanel>{renderTableOrPlaceholder(filteredClosedConns)}</TabPanel>
+ <TabPanel>
+ <Button onClick={() => setFilterSourceIpStr('')} kind="minimal">
+ {t('All')}
+ </Button>
+ {ClosedConnIpSet.map((value, k) => {
+ return (
+ <Button key={k} onClick={() => setFilterSourceIpStr(value)} kind="minimal">
+ {value}
+ </Button>
+ );
+ })}
+ {renderTableOrPlaceholder(filteredClosedConns)}
+ </TabPanel>
</div>
</div>
<ModalCloseAllConnections