mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-08-28 12:44:12 +00:00
Fix multi-select filters (AND→OR) and add localStorage persistence
- Server: support comma-separated type filter values (OR logic) - Server: add observer_id filtering to /api/packets endpoint - Client: fix type and observer filters to use OR logic for multi-select - Client: persist observer and type filter selections to localStorage - Keys: meshcore-observer-filter, meshcore-type-filter
This commit is contained in:
+1
-1
@@ -84,7 +84,7 @@
|
||||
<script src="hop-resolver.js?v=1774126708"></script>
|
||||
<script src="app.js?v=1774126708"></script>
|
||||
<script src="home.js?v=1774042199"></script>
|
||||
<script src="packets.js?v=1774138896"></script>
|
||||
<script src="packets.js?v=1774139673"></script>
|
||||
<script src="map.js?v=1774126708" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="channels.js?v=1774331200" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
<script src="nodes.js?v=1774126708" onerror="console.error('Failed to load:', this.src)"></script>
|
||||
|
||||
+11
-2
@@ -13,6 +13,8 @@
|
||||
let selectedId = null;
|
||||
let groupByHash = true;
|
||||
let filters = {};
|
||||
{ const o = localStorage.getItem('meshcore-observer-filter'); if (o) filters.observer = o;
|
||||
const t = localStorage.getItem('meshcore-type-filter'); if (t) filters.type = t; }
|
||||
let wsHandler = null;
|
||||
let observers = [];
|
||||
let regionMap = {};
|
||||
@@ -21,6 +23,7 @@
|
||||
let totalCount = 0;
|
||||
let expandedHashes = new Set();
|
||||
let hopNameCache = {};
|
||||
let showHexHashes = localStorage.getItem('meshcore-hex-hashes') === 'true';
|
||||
let filtersBuilt = false;
|
||||
const PANEL_WIDTH_KEY = 'meshcore-panel-width';
|
||||
|
||||
@@ -116,6 +119,9 @@
|
||||
}
|
||||
|
||||
function renderHop(h) {
|
||||
if (showHexHashes) {
|
||||
return `<span class="hop">${escapeHtml(h)}</span>`;
|
||||
}
|
||||
const entry = hopNameCache[h];
|
||||
const name = entry ? (typeof entry === 'string' ? entry : entry.name) : null;
|
||||
const pubkey = entry?.pubkey || h;
|
||||
@@ -242,8 +248,8 @@
|
||||
|
||||
// Check if new packets pass current filters
|
||||
const filtered = newPkts.filter(p => {
|
||||
if (filters.type !== undefined && filters.type !== '' && p.payload_type !== Number(filters.type)) return false;
|
||||
if (filters.observer && p.observer_id !== filters.observer) return false;
|
||||
if (filters.type) { const types = filters.type.split(',').map(Number); if (!types.includes(p.payload_type)) return false; }
|
||||
if (filters.observer) { const obsSet = new Set(filters.observer.split(',')); if (!obsSet.has(p.observer_id)) return false; }
|
||||
if (filters.hash && p.hash !== filters.hash) return false;
|
||||
if (RegionFilter.getRegionParam()) {
|
||||
const selectedRegions = RegionFilter.getRegionParam().split(',');
|
||||
@@ -462,6 +468,7 @@
|
||||
<button class="col-toggle-btn" id="colToggleBtn" title="Show/hide table columns">Columns ▾</button>
|
||||
<div class="col-toggle-menu" id="colToggleMenu"></div>
|
||||
</div>
|
||||
<button class="btn btn-icon${showHexHashes ? ' active' : ''}" id="hexHashToggle" title="Show hex hashes in path column">Hex</button>
|
||||
</div>
|
||||
</div>
|
||||
<table class="data-table" id="pktTable">
|
||||
@@ -512,6 +519,7 @@
|
||||
if (e.target.checked) selectedObservers.add(id); else selectedObservers.delete(id);
|
||||
}
|
||||
filters.observer = selectedObservers.size > 0 ? [...selectedObservers].join(',') : undefined;
|
||||
if (filters.observer) localStorage.setItem('meshcore-observer-filter', filters.observer); else localStorage.removeItem('meshcore-observer-filter');
|
||||
buildObserverMenu();
|
||||
updateObsTrigger();
|
||||
loadPackets();
|
||||
@@ -553,6 +561,7 @@
|
||||
if (e.target.checked) selectedTypes.add(id); else selectedTypes.delete(id);
|
||||
}
|
||||
filters.type = selectedTypes.size > 0 ? [...selectedTypes].join(',') : undefined;
|
||||
if (filters.type) localStorage.setItem('meshcore-type-filter', filters.type); else localStorage.removeItem('meshcore-type-filter');
|
||||
buildTypeMenu();
|
||||
updateTypeTrigger();
|
||||
loadPackets();
|
||||
|
||||
@@ -921,7 +921,8 @@ app.get('/api/packets', (req, res) => {
|
||||
}
|
||||
let results = [...allPackets.values()].sort((a, b) => order === 'DESC' ? b.timestamp.localeCompare(a.timestamp) : a.timestamp.localeCompare(b.timestamp));
|
||||
// Apply additional filters
|
||||
if (type !== undefined) results = results.filter(p => String(p.payload_type) === String(type));
|
||||
if (type !== undefined) { const types = String(type).split(','); results = results.filter(p => types.includes(String(p.payload_type))); }
|
||||
if (observer) { const obsIds = observer.split(','); results = results.filter(p => obsIds.includes(p.observer_id)); }
|
||||
if (region) results = results.filter(p => (p.observer_id || '').includes(region) || (p.decoded_json || '').includes(region));
|
||||
if (since) results = results.filter(p => p.timestamp >= since);
|
||||
if (until) results = results.filter(p => p.timestamp <= until);
|
||||
|
||||
Reference in New Issue
Block a user