feat: добавлена возможность сортировки трафика по частоте и времени
Some checks failed
Build and Deploy Gateway / build-and-deploy (push) Failing after 0s

Refs: None
This commit is contained in:
2026-05-09 08:38:37 +03:00
parent 5c9a291920
commit b3fad00f80

View File

@@ -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() {
<input type="checkbox" checked={grouped} onChange={(e) => setGrouped(e.target.checked)} />
Группировать
</label>
{grouped && (
<select className="select" value={sortBy} onChange={(e) => setSortBy(e.target.value)} style={{ width: 'auto' }}>
<option value="count">По частоте</option>
<option value="time">По времени</option>
</select>
)}
<label className="checkbox">
<input type="checkbox" checked={autoscroll} onChange={(e) => setAutoscroll(e.target.checked)} />
Автоскролл