Explore: refresh with its own filters; the Statistics refresh stays on its page
The Statistics page's once-a-minute refresh also ran on #/stats/explore and drew the Statistics page over it, losing the filters. It now runs on the Statistics page only, and the explore page refreshes itself every minute with the same filters (not while the filter bar is being edited). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e94d3634b6
commit
7d93c373d1
2 files changed
+26
-2
No files matched your search
@@ -49,7 +49,11 @@ function copy(f) { const g = {}; for (const k of kinds) g[k] = [...(f[k] || [])]
|
|||||||
const includes = (f, k) => (f[k] || []).filter((v) => !isNot(v));
|
const includes = (f, k) => (f[k] || []).filter((v) => !isNot(v));
|
||||||
const anyFilter = (f) => kinds.some((k) => (f[k] || []).length);
|
const anyFilter = (f) => kinds.some((k) => (f[k] || []).length);
|
||||||
|
|
||||||
|
let generation = 0;
|
||||||
|
|
||||||
export async function render(el, params, query) {
|
export async function render(el, params, query) {
|
||||||
|
const gen = ++generation;
|
||||||
|
const hash = location.hash;
|
||||||
const f = parse(query);
|
const f = parse(query);
|
||||||
const since = query.get("since") || "24h";
|
const since = query.get("since") || "24h";
|
||||||
const go = (g) => exploreHref(g, since);
|
const go = (g) => exploreHref(g, since);
|
||||||
@@ -105,7 +109,25 @@ export async function render(el, params, query) {
|
|||||||
if (lists.length) parts.push(h("div", { class: "chart-grid" }, lists));
|
if (lists.length) parts.push(h("div", { class: "chart-grid" }, lists));
|
||||||
|
|
||||||
parts.push(recentPanel(ex, (k, v) => go(addTo(f, k, v))));
|
parts.push(recentPanel(ex, (k, v) => go(addTo(f, k, v))));
|
||||||
|
if (gen !== generation) return; // the user moved on
|
||||||
|
el.classList.remove("refreshing");
|
||||||
mount(el, parts);
|
mount(el, parts);
|
||||||
|
scheduleRefresh(el, params, query, gen, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
// scheduleRefresh redraws the page a minute later with the same filters,
|
||||||
|
// so the graphs move along; not while a filter is being typed in.
|
||||||
|
function scheduleRefresh(el, params, query, gen, hash) {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (gen !== generation || location.hash !== hash || !el.isConnected) return;
|
||||||
|
const form = el.querySelector("form.explore-filters");
|
||||||
|
if (form && (form.contains(document.activeElement) || form.dataset.dirty)) {
|
||||||
|
scheduleRefresh(el, params, query, gen, hash); // try again later
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
el.classList.add("refreshing");
|
||||||
|
render(el, params, query).catch(() => el.classList.remove("refreshing"));
|
||||||
|
}, 60_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// filterBar types filters in. Each field takes several values, comma
|
// filterBar types filters in. Each field takes several values, comma
|
||||||
@@ -126,7 +148,7 @@ function filterBar(f, since, ex, views) {
|
|||||||
type: split(type.value).map((v) => v.toUpperCase()), rcode: split(rcode.value).map((v) => v.toUpperCase()), blocked: split(blocked.value) };
|
type: split(type.value).map((v) => v.toUpperCase()), rcode: split(rcode.value).map((v) => v.toUpperCase()), blocked: split(blocked.value) };
|
||||||
location.hash = exploreHref(g, since);
|
location.hash = exploreHref(g, since);
|
||||||
};
|
};
|
||||||
const form = h("form", { class: "explore-filters", onsubmit: (e) => { e.preventDefault(); apply(); } },
|
const form = h("form", { class: "explore-filters", onsubmit: (e) => { e.preventDefault(); apply(); }, oninput: () => { form.dataset.dirty = "1"; } },
|
||||||
h("label", null, "Client ", client), h("label", null, "Name ", name), h("label", null, "View ", view),
|
h("label", null, "Client ", client), h("label", null, "Name ", name), h("label", null, "View ", view),
|
||||||
h("label", null, "Type ", type), h("label", null, "Result ", rcode), h("label", null, "Blocked ", blocked),
|
h("label", null, "Type ", type), h("label", null, "Result ", rcode), h("label", null, "Blocked ", blocked),
|
||||||
h("button", { type: "submit", class: "primary small" }, "Show"),
|
h("button", { type: "submit", class: "primary small" }, "Show"),
|
||||||
|
|||||||
@@ -183,7 +183,9 @@ async function loadAll(since, heatSince, queryLog, vf, filtered) {
|
|||||||
// keeping the current render (dimmed) until the new one is ready.
|
// keeping the current render (dimmed) until the new one is ready.
|
||||||
function scheduleRefresh(el, params, query, gen) {
|
function scheduleRefresh(el, params, query, gen) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (gen !== generation || !location.hash.startsWith("#/stats") || !el.isConnected) return;
|
// Only on the Statistics page itself: not #/stats/explore.
|
||||||
|
const h = location.hash;
|
||||||
|
if (gen !== generation || !(h === "#/stats" || h.startsWith("#/stats?")) || !el.isConnected) return;
|
||||||
el.classList.add("refreshing");
|
el.classList.add("refreshing");
|
||||||
render(el, params, query).catch(() => el.classList.remove("refreshing"));
|
render(el, params, query).catch(() => el.classList.remove("refreshing"));
|
||||||
}, 60_000);
|
}, 60_000);
|
||||||
|
|||||||
Reference in new issue
Block a user