fix flash

and some map ahh shi that is SO not needed
+ fmt
This commit is contained in:
lda
2025-08-29 10:07:09 +07:00 Unverified
parent e26d893e5f
commit 89a914d666
5 changed files with 49 additions and 41 deletions
+10 -4
View File
@@ -19,7 +19,7 @@ export function renderLeases(leases) {
let dotClass = "dot ok"; let dotClass = "dot ok";
if (expired) { if (expired) {
dotClass = "dot bad"; dotClass = "dot bad";
} else if (typeof l?.rank === "number") { } /* rank from NUDState */ else if (typeof l?.rank === "number") {
if (l.rank >= 5) dotClass = "dot ok"; if (l.rank >= 5) dotClass = "dot ok";
else if (l.rank >= 2) dotClass = "dot warn"; else if (l.rank >= 2) dotClass = "dot warn";
else dotClass = "dot bad"; else dotClass = "dot bad";
@@ -34,9 +34,15 @@ export function renderLeases(leases) {
const name = l.name || ""; const name = l.name || "";
tr.innerHTML = ` tr.innerHTML = `
<td><span class="${dotClass}" title="${title}"></span></td> <td><span class="${dotClass}" title="${title}"></span></td>
<td>${ip ? `<a href="#" class="pick" data-value="${ip}" title="filter by ip">${ip}</a>` : ""}</td> ${[ip, mac, name]
<td>${mac ? `<a href="#" class="pick" data-value="${mac}" title="filter by mac">${mac}</a>` : ""}</td> .map(
<td>${name ? `<a href="#" class="pick" data-value="${name}" title="filter by name">${name}</a>` : ""}</td> (f) =>
`<td>${
f &&
`<a href="#" class="pick" data-value="${f}" title="filter by ip">${f}</a>`
}</td>`
)
.join("\n")}
<td><span class="tiny">${whenText}</span></td>`; <td><span class="tiny">${whenText}</span></td>`;
tbl.appendChild(tr); tbl.appendChild(tr);
} }
+9 -1
View File
@@ -9,7 +9,12 @@ import {
setPill, setPill,
qs, qs,
} from "./dom.js"; } from "./dom.js";
import { getName, saveName, loadName, extractHostLikeBackend } from "./utils.js"; import {
getName,
saveName,
loadName,
extractHostLikeBackend,
} from "./utils.js";
import { fetchStatus } from "./status.js"; import { fetchStatus } from "./status.js";
import { fetchLeases } from "./leases.js"; import { fetchLeases } from "./leases.js";
import { sendWake } from "./wake.js"; import { sendWake } from "./wake.js";
@@ -39,6 +44,7 @@ function pickTarget(value) {
saveName(v); saveName(v);
setLink(v); setLink(v);
fetchStatus(v); fetchStatus(v);
fetchLeases();
} }
// events // events
@@ -48,6 +54,7 @@ elCheck.addEventListener("click", () => {
saveName(name); saveName(name);
setLink(name); setLink(name);
fetchStatus(name); fetchStatus(name);
fetchLeases();
}); });
elWake.addEventListener("click", () => { elWake.addEventListener("click", () => {
const name = getName(elName); const name = getName(elName);
@@ -55,6 +62,7 @@ elWake.addEventListener("click", () => {
saveName(name); saveName(name);
setLink(name); setLink(name);
sendWake(name); sendWake(name);
fetchLeases();
}); });
elName.addEventListener("keydown", (e) => { elName.addEventListener("keydown", (e) => {
if (e.key === "Enter") elCheck.click(); if (e.key === "Enter") elCheck.click();
+25 -33
View File
@@ -1,16 +1,23 @@
import { elHtml, elLog, setPill, qs } from "./dom.js"; import { elHtml, elLog, setPill, qs } from "./dom.js";
import { rankState } from "./utils.js"; import { rankState } from "./utils.js";
const status_map = {
ip: "ip",
mac: "mac",
state: "state",
dev: "interface",
};
const filter_array = ["ip", "dev", "nud", "mac"];
function buildStatusUrl(name) { function buildStatusUrl(name) {
const hasExtraFilters = ["ip", "dev", "nud", "mac"].some( const hasExtraFilters = f_array.some((k) => qs.getAll(k).length);
(k) => qs.getAll(k).length
);
if (name && !hasExtraFilters) { if (name && !hasExtraFilters) {
return new URL(`/api/smart/${encodeURIComponent(name)}`, location.origin); return new URL(`/api/smart/${encodeURIComponent(name)}`, location.origin);
} }
const u = new URL("/api/status", location.origin); const u = new URL("/api/status", location.origin);
if (name) u.searchParams.set("name", name); if (name) u.searchParams.set("name", name);
for (const k of ["ip", "dev", "nud", "mac"]) { for (const k of Object.keys(status_map)) {
const vals = qs.getAll(k); const vals = qs.getAll(k);
for (const v of vals) u.searchParams.append(k, v); for (const v of vals) u.searchParams.append(k, v);
} }
@@ -24,41 +31,27 @@ export function renderStatus(data) {
for (const row of data.table || []) { for (const row of data.table || []) {
const tr = document.createElement("tr"); const tr = document.createElement("tr");
tr.innerHTML = ` tr.innerHTML = Object.entries(status_map)
<td>${ .map(
row.ip (field, description) =>
? `<a href="#" class="pick" data-value="${row.ip}" title="filter by ip">${row.ip}</a>` `<td>${
row[field]
? `<a href="#" class="pick" data-value="${row[field]}" title="filter by ${description}">${row[field]}</a>`
: "" : ""
}</td> }</td>`
<td>${ )
row.mac .join();
? `<a href="#" class="pick" data-value="${row.mac}" title="filter by mac">${row.mac}</a>`
: ""
}</td>
<td>${
row.state
? `<a href="#" class="pick" data-value="${row.state}" title="filter by state">${row.state}</a>`
: ""
}</td>
<td>${
row.dev
? `<a href="#" class="pick" data-value="${row.dev}" title="filter by interface">${row.dev}</a>`
: ""
}</td>`;
tbl.appendChild(tr); tbl.appendChild(tr);
} }
elHtml.innerHTML = ""; elHtml.innerHTML = "";
if (data.filters) { if (data.filters) {
const parts = []; const parts = [];
if (Array.isArray(data.filters.ip) && data.filters.ip.length) filter_array.forEach((field) => {
parts.push(`ip=[${data.filters.ip.join(", ")}]`); if (Array.isArray(data.filters[field]) && data.filters[field].length)
if (Array.isArray(data.filters.dev) && data.filters.dev.length) parts.push(`${field}=[${data.filters[field].join(", ")}]`);
parts.push(`dev=[${data.filters.dev.join(", ")}]`); });
if (Array.isArray(data.filters.nud) && data.filters.nud.length)
parts.push(`nud=[${data.filters.nud.join(", ")}]`);
if (Array.isArray(data.filters.mac) && data.filters.mac.length)
parts.push(`mac=[${data.filters.mac.join(", ")}]`);
if (parts.length) { if (parts.length) {
const info = document.createElement("div"); const info = document.createElement("div");
info.className = "filters"; info.className = "filters";
@@ -85,7 +78,6 @@ export async function fetchStatus(name) {
setPill("warn", "checking…"); setPill("warn", "checking…");
const u = buildStatusUrl(name); const u = buildStatusUrl(name);
elLog.textContent = "GET " + u.pathname + u.search; elLog.textContent = "GET " + u.pathname + u.search;
elHtml.innerHTML = "";
try { try {
const r = await fetch(u); const r = await fetch(u);
if (!r.ok) { if (!r.ok) {
+3 -1
View File
@@ -36,7 +36,9 @@ export function extractHostLikeBackend(input) {
} }
export function rankState(s) { export function rankState(s) {
const key = String(s || "").trim().toUpperCase(); const key = String(s || "")
.trim()
.toUpperCase();
return ( return (
{ {
PERMANENT: 5, PERMANENT: 5,
+1 -1
View File
@@ -10,7 +10,7 @@ export async function sendWake(name) {
}); });
const t = await r.text(); const t = await r.text();
elLog.textContent = t || "ok"; elLog.textContent = t || "ok";
setTimeout(() => fetchStatus(name), 1500); setTimeout(() => fetchStatus(name), 800);
} catch (e) { } catch (e) {
elLog.textContent = "wake error: " + e; elLog.textContent = "wake error: " + e;
setPill("bad", "error"); setPill("bad", "error");