From c78824b0e9ff9d7b64cf33072626effe6b6696e8 Mon Sep 17 00:00:00 2001 From: Daniel Redetzke Date: Mon, 5 Oct 2026 14:18:18 +0300 Subject: [PATCH] Dashboard: a range switch redraws only the traffic chart The range buttons light up at once and fetch only the chart's stats, like on the peer page, instead of reloading the whole dashboard. --- app.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/app.js b/app.js index c8c0ac7..40eeb9d 100644 --- a/app.js +++ b/app.js @@ -1036,6 +1036,19 @@ const failing = st.checks.filter((c) => !c.ok); const ifCheck = st.checks.find((c) => c.name === 'WireGuard interface'); const top = [...peers].sort((a, b) => (b.stats.down24h + b.stats.up24h) - (a.stats.down24h + a.stats.up24h)).slice(0, 6); + // A range switch fetches and redraws only the chart. + const traffic = h('div', null, chart(stats.points, range, 'total', true)); + const pills = h('div', { class: 'pills', role: 'group', 'aria-label': 'Time range' }); + const drawPills = () => pills.replaceChildren(...RANGES.map(([k, t]) => + h('button', { type: 'button', class: range === k ? 'pill on' : 'pill', 'aria-pressed': String(range === k), onClick: async () => { + range = k; + drawPills(); + try { + const s = await api('GET', '/stats?range=' + k); + if (range === k) traffic.replaceChildren(chart(s.points, k, 'total', true)); + } catch (x) { toast(x.message, true); } + } }, t))); + drawPills(); fill(wrap, h('div', { class: 'head' }, @@ -1066,10 +1079,8 @@ h('div', { class: 's' }, 'Service up ' + ago(st.started).replace(' ago', '') + ' ยท ' + (st.healthy ? 'all checks pass' : failing.length + ' check(s) failing')))), h('section', { class: 'card', 'aria-labelledby': 'tput' }, - h('div', { class: 'cardhead' }, h('h2', { id: 'tput' }, 'Traffic, all peers'), - h('div', { class: 'pills', role: 'group', 'aria-label': 'Time range' }, RANGES.map(([k, t]) => - h('button', { type: 'button', class: range === k ? 'pill on' : 'pill', 'aria-pressed': String(range === k), onClick: () => { range = k; draw().catch(() => {}); } }, t)))), - chart(stats.points, range, 'total', true)), + h('div', { class: 'cardhead' }, h('h2', { id: 'tput' }, 'Traffic, all peers'), pills), + traffic), h('div', { class: 'cols' }, h('section', { class: 'card flush' },