feat(dashboard): version in header, restructure footer #109
@@ -561,6 +561,7 @@ body {
|
|||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="header-left">
|
<div class="header-left">
|
||||||
<div class="logo">Numa</div>
|
<div class="logo">Numa</div>
|
||||||
|
<span id="headerVersion" style="font-family:var(--font-mono);font-size:0.68rem;color:var(--text-dim);"></span>
|
||||||
<div class="tagline">DNS that governs itself</div>
|
<div class="tagline">DNS that governs itself</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;align-items:center;gap:1.2rem;">
|
<div style="display:flex;align-items:center;gap:1.2rem;">
|
||||||
@@ -1136,16 +1137,20 @@ async function refresh() {
|
|||||||
document.getElementById('totalQueries').textContent = formatNumber(q.total);
|
document.getElementById('totalQueries').textContent = formatNumber(q.total);
|
||||||
document.getElementById('uptime').textContent = formatUptime(stats.uptime_secs);
|
document.getElementById('uptime').textContent = formatUptime(stats.uptime_secs);
|
||||||
document.getElementById('uptimeSub').textContent = formatUptimeSub(stats.uptime_secs);
|
document.getElementById('uptimeSub').textContent = formatUptimeSub(stats.uptime_secs);
|
||||||
|
document.getElementById('headerVersion').textContent = stats.version ? 'v' + stats.version : '';
|
||||||
document.getElementById('footerUpstream').textContent = stats.upstream || '';
|
document.getElementById('footerUpstream').textContent = stats.upstream || '';
|
||||||
document.getElementById('footerConfig').textContent = stats.config_path || '';
|
document.getElementById('footerConfig').textContent = stats.config_path || '';
|
||||||
document.getElementById('footerData').textContent = stats.data_dir || '';
|
document.getElementById('footerData').textContent = stats.data_dir || '';
|
||||||
const modeEl = document.getElementById('footerMode');
|
|
||||||
modeEl.textContent = stats.mode || '—';
|
|
||||||
modeEl.style.color = stats.mode === 'recursive' ? 'var(--emerald)' : 'var(--amber)';
|
|
||||||
document.getElementById('footerDnssec').textContent = stats.dnssec ? 'on' : 'off';
|
document.getElementById('footerDnssec').textContent = stats.dnssec ? 'on' : 'off';
|
||||||
document.getElementById('footerDnssec').style.color = stats.dnssec ? 'var(--emerald)' : 'var(--text-dim)';
|
document.getElementById('footerDnssec').style.color = stats.dnssec ? 'var(--emerald)' : 'var(--text-dim)';
|
||||||
document.getElementById('footerSrtt').textContent = stats.srtt ? 'on' : 'off';
|
document.getElementById('footerSrtt').textContent = stats.srtt ? 'on' : 'off';
|
||||||
document.getElementById('footerSrtt').style.color = stats.srtt ? 'var(--emerald)' : 'var(--text-dim)';
|
document.getElementById('footerSrtt').style.color = stats.srtt ? 'var(--emerald)' : 'var(--text-dim)';
|
||||||
|
if (!document.getElementById('footerLogs').textContent) {
|
||||||
|
const isMac = stats.data_dir && stats.data_dir.includes('/usr/local/');
|
||||||
|
document.getElementById('footerLogs').textContent = isMac
|
||||||
|
? '/usr/local/var/log/numa.log'
|
||||||
|
: 'journalctl -u numa -f';
|
||||||
|
}
|
||||||
|
|
||||||
// LAN status indicator
|
// LAN status indicator
|
||||||
const lanEl = document.getElementById('lanToggle');
|
const lanEl = document.getElementById('lanToggle');
|
||||||
@@ -1504,14 +1509,14 @@ refresh();
|
|||||||
setInterval(refresh, 2000);
|
setInterval(refresh, 2000);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div style="text-align:center;padding:0.8rem;font-family:var(--font-mono);font-size:0.68rem;color:var(--text-dim);">
|
<div style="text-align:center;padding:0.8rem 0.8rem 0.4rem;font-family:var(--font-mono);font-size:0.68rem;color:var(--text-dim);line-height:1.8;">
|
||||||
Config: <span id="footerConfig" style="user-select:all;color:var(--emerald);"></span>
|
Config: <span id="footerConfig" style="user-select:all;color:var(--emerald);"></span>
|
||||||
· Data: <span id="footerData" style="user-select:all;color:var(--emerald);"></span>
|
· Data: <span id="footerData" style="user-select:all;color:var(--emerald);"></span>
|
||||||
· Upstream: <span id="footerUpstream" style="user-select:all;color:var(--emerald);"></span>
|
· Logs: <span id="footerLogs" style="user-select:all;color:var(--emerald);"></span>
|
||||||
· Mode: <span id="footerMode" style="color:var(--text-dim);">—</span>
|
<br>
|
||||||
|
Upstream: <span id="footerUpstream" style="user-select:all;color:var(--emerald);"></span>
|
||||||
· DNSSEC: <span id="footerDnssec" style="color:var(--text-dim);">—</span>
|
· DNSSEC: <span id="footerDnssec" style="color:var(--text-dim);">—</span>
|
||||||
· SRTT: <span id="footerSrtt" style="color:var(--text-dim);">—</span>
|
· SRTT: <span id="footerSrtt" style="color:var(--text-dim);">—</span>
|
||||||
· Logs: <span style="user-select:all;color:var(--emerald);">macOS: /usr/local/var/log/numa.log · Linux: journalctl -u numa -f</span>
|
|
||||||
· <a href="https://github.com/razvandimescu/numa" target="_blank" rel="noopener" style="color:var(--amber);text-decoration:none;">GitHub</a>
|
· <a href="https://github.com/razvandimescu/numa" target="_blank" rel="noopener" style="color:var(--amber);text-decoration:none;">GitHub</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -160,6 +160,7 @@ struct QueryLogResponse {
|
|||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct StatsResponse {
|
struct StatsResponse {
|
||||||
|
version: &'static str,
|
||||||
uptime_secs: u64,
|
uptime_secs: u64,
|
||||||
upstream: String,
|
upstream: String,
|
||||||
mode: &'static str, // "recursive" or "forward" — never "auto" at runtime
|
mode: &'static str, // "recursive" or "forward" — never "auto" at runtime
|
||||||
@@ -539,6 +540,7 @@ async fn stats(State(ctx): State<Arc<ServerCtx>>) -> Json<StatsResponse> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Json(StatsResponse {
|
Json(StatsResponse {
|
||||||
|
version: env!("CARGO_PKG_VERSION"),
|
||||||
uptime_secs: snap.uptime_secs,
|
uptime_secs: snap.uptime_secs,
|
||||||
upstream,
|
upstream,
|
||||||
mode: ctx.upstream_mode.as_str(),
|
mode: ctx.upstream_mode.as_str(),
|
||||||
|
|||||||
Reference in New Issue
Block a user