Fix IP filter to check AP's own IP from DOM
Previous implementation fetched connected client IPs via API (which was returning empty data). The filter now checks the AP's own management IP directly from the data already in the table — no network request, instant. An AP is shown when its IP last octet is between 150 and 155 inclusive. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -221,9 +221,13 @@
|
||||
const visibleCount = document.getElementById('visible-count');
|
||||
const allRows = [...document.querySelectorAll('#ap-table-body tr')];
|
||||
|
||||
let ipMatchingMacs = null; // null = inactive; Set<string> = active
|
||||
let ipFilterActive = false;
|
||||
|
||||
function normMac(s) { return (s || '').toUpperCase().replace(/-/g, ':'); }
|
||||
function isTargetIp(ip) {
|
||||
if (!ip) return false;
|
||||
const last = parseInt((ip.split('.')[3] || ''), 10);
|
||||
return last >= 150 && last <= 155;
|
||||
}
|
||||
|
||||
function applyFilters() {
|
||||
const q = filterInput.value.toLowerCase().trim();
|
||||
@@ -234,9 +238,9 @@
|
||||
const nameMatch = !q || name.includes(q) || site.includes(q);
|
||||
|
||||
let ipMatch = true;
|
||||
if (ipMatchingMacs !== null) {
|
||||
if (ipFilterActive) {
|
||||
const cb = row.querySelector('.ap-checkbox');
|
||||
ipMatch = ipMatchingMacs.has(normMac(cb?.dataset.mac));
|
||||
ipMatch = isTargetIp(cb?.dataset.ip || '');
|
||||
}
|
||||
|
||||
const visible = nameMatch && ipMatch;
|
||||
@@ -252,18 +256,9 @@
|
||||
// ── IP range filter button ─────────────────────────────────────────────────
|
||||
const btnIpFilter = document.getElementById('btn-ip-filter');
|
||||
const ipFilterLabel = document.getElementById('ip-filter-label');
|
||||
const ipFilterIcon = document.getElementById('ip-filter-icon');
|
||||
let cachedApClients = null;
|
||||
|
||||
function isTargetIp(ip) {
|
||||
if (!ip) return false;
|
||||
const parts = ip.split('.');
|
||||
if (parts.length !== 4) return false;
|
||||
const last = parseInt(parts[3], 10);
|
||||
return last >= 150 && last <= 155;
|
||||
}
|
||||
|
||||
function setIpFilterActive(active) {
|
||||
ipFilterActive = active;
|
||||
if (active) {
|
||||
btnIpFilter.classList.replace('bg-white', 'bg-blue-50');
|
||||
btnIpFilter.classList.replace('hover:bg-gray-50', 'hover:bg-blue-100');
|
||||
@@ -279,40 +274,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
btnIpFilter?.addEventListener('click', async () => {
|
||||
if (ipMatchingMacs !== null) {
|
||||
// Clear filter
|
||||
ipMatchingMacs = null;
|
||||
setIpFilterActive(false);
|
||||
btnIpFilter?.addEventListener('click', () => {
|
||||
setIpFilterActive(!ipFilterActive);
|
||||
applyFilters();
|
||||
return;
|
||||
}
|
||||
|
||||
btnIpFilter.disabled = true;
|
||||
ipFilterLabel.textContent = 'Loading…';
|
||||
ipFilterIcon.classList.add('animate-spin');
|
||||
|
||||
try {
|
||||
if (!cachedApClients) {
|
||||
const res = await fetch('/api/all-clients');
|
||||
if (!res.ok) { const e = await res.json(); throw new Error(e.detail || 'Request failed'); }
|
||||
cachedApClients = (await res.json()).ap_clients || {};
|
||||
}
|
||||
|
||||
ipMatchingMacs = new Set();
|
||||
for (const [apMac, clients] of Object.entries(cachedApClients)) {
|
||||
if (clients.some(c => isTargetIp(c.ip))) ipMatchingMacs.add(apMac);
|
||||
}
|
||||
|
||||
setIpFilterActive(true);
|
||||
applyFilters();
|
||||
} catch (e) {
|
||||
showToast('Failed to load client data: ' + e.message, 'error');
|
||||
ipFilterLabel.textContent = 'Filter .150–.155';
|
||||
} finally {
|
||||
btnIpFilter.disabled = false;
|
||||
ipFilterIcon.classList.remove('animate-spin');
|
||||
}
|
||||
});
|
||||
|
||||
// ── Refresh ────────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user