diff --git a/src/web/components/LogsPage.jsx b/src/web/components/LogsPage.jsx
index ec321c8..9f3ed8a 100644
--- a/src/web/components/LogsPage.jsx
+++ b/src/web/components/LogsPage.jsx
@@ -33,7 +33,7 @@ const CATEGORY_BADGE = {
other: { cls: '', label: 'other' },
};
-function groupTraffic(list) {
+function groupTraffic(list, sortBy = 'time') {
const map = new Map();
for (const e of list) {
const key = `${e.category}|${e.host}|${e.port}|${e.matchedRule || ''}`;
@@ -47,7 +47,9 @@ function groupTraffic(list) {
map.set(key, { ...e, _key: key, _lastTs: ts, count: 1, lastTs: e.ts });
}
}
- return Array.from(map.values()).sort((a, b) => b._lastTs - a._lastTs);
+ const arr = Array.from(map.values());
+ if (sortBy === 'count') return arr.sort((a, b) => b.count - a.count || b._lastTs - a._lastTs);
+ return arr.sort((a, b) => b._lastTs - a._lastTs);
}
function TrafficTab() {
@@ -56,6 +58,7 @@ function TrafficTab() {
const [filter, setFilter] = useState('all'); // all | direct | vpn | block
const [search, setSearch] = useState('');
const [grouped, setGrouped] = useState(true);
+ const [sortBy, setSortBy] = useState('count'); // time | count
const [autoscroll, setAutoscroll] = useState(true);
const containerRef = useRef(null);
const pausedRef = useRef(false);
@@ -90,8 +93,8 @@ function TrafficTab() {
e.matchedRule?.toLowerCase().includes(s),
);
}
- return grouped ? groupTraffic(list) : list;
- }, [traffic, filter, search, grouped]);
+ return grouped ? groupTraffic(list, sortBy) : list;
+ }, [traffic, filter, search, grouped, sortBy]);
useEffect(() => {
if (!autoscroll || !containerRef.current) return;
@@ -124,6 +127,12 @@ function TrafficTab() {
setGrouped(e.target.checked)} />
Группировать
+ {grouped && (
+
+ )}