From 78c95a508dc60e6d4739815eb248a1b4eed0680d Mon Sep 17 00:00:00 2001 From: Myron Blair Date: Mon, 1 Jun 2026 14:22:36 +0000 Subject: [PATCH] Add total count badges beside page titles in admin - KB Facts: shows total fact count (sum across all categories) - Network Devices: shows online/total count in title - Home Assistant Entities: shows entity count in title - Proxmox VMs: shows running/total VM count in title - KB Intents already had this; no change needed --- public_html/admin/index.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/public_html/admin/index.php b/public_html/admin/index.php index bd538d3..29f3f2d 100644 --- a/public_html/admin/index.php +++ b/public_html/admin/index.php @@ -718,7 +718,7 @@ select.filter-sel:focus{border-color:var(--cyan)}
-
NETWORK DEVICES +
NETWORK DEVICES
@@ -757,7 +757,7 @@ select.filter-sel:focus{border-color:var(--cyan)}
-
KB FACTS +
KB FACTS
@@ -774,7 +774,7 @@ select.filter-sel:focus{border-color:var(--cyan)}
-
KB INTENTS +
KB INTENTS
@@ -785,7 +785,7 @@ select.filter-sel:focus{border-color:var(--cyan)}
-
HOME ASSISTANT ENTITIES +
HOME ASSISTANT ENTITIES
@@ -821,7 +821,7 @@ select.filter-sel:focus{border-color:var(--cyan)}
-
PROXMOX VMs +
PROXMOX VMs
SCANNING...
@@ -1230,6 +1230,7 @@ function renderNetwork() { if (_netFilter === 'named') devs = devs.filter(d => d.alias); const onlineCount = _allDevices.filter(d=>d.status==='online').length; document.getElementById('net-count').textContent = `${onlineCount}/${_allDevices.length} ONLINE`; + const _ntEl=document.getElementById('net-title-count'); if(_ntEl) _ntEl.textContent=`${onlineCount}/${_allDevices.length} ONLINE`; if (!devs.length) { document.getElementById('network-tbl').innerHTML='
NO DEVICES MATCH FILTER
'; return; } // Re-build shell (filter changed) document.getElementById('network-tbl').innerHTML = ` @@ -1354,6 +1355,8 @@ async function loadFactCategories() { const sel = document.getElementById('factCat'); sel.innerHTML = '' + cats.map(c=>``).join(''); + const _factTotal = cats.reduce((s,c)=>s+parseInt(c.cnt||0),0); + const _factCntEl = document.getElementById('facts-count'); if(_factCntEl) _factCntEl.textContent=_factTotal.toLocaleString()+' FACTS'; } async function loadFacts() { @@ -1391,6 +1394,7 @@ function factModal(id=0, category='', key='', value='') { async function loadIntents() { scanShell('intents-tbl', ['NAME','PATTERN','RESPONSE','TYPE','PRI','STATUS','ACTIONS'], null, null); const intents = await api('intents_list'); + const cntEl=document.getElementById('intents-count'); if(cntEl) cntEl.textContent=intents.length.toLocaleString()+' INTENTS'; if (!intents.length) { document.getElementById('intents-tbl').innerHTML='
NO INTENTS
'; return; } document.getElementById('intents-tbl').innerHTML = `
@@ -1509,6 +1513,7 @@ async function loadHA() { if (cur) sel.value = cur; const age = data.ts ? Math.floor((Date.now()/1000)-data.ts) : null; document.getElementById('ha-count').textContent = `${_haEntities.length} ENTITIES${age!=null?' · CACHE '+age+'s AGO':''}`; + const _haTitleEl=document.getElementById('ha-title-count'); if(_haTitleEl) _haTitleEl.textContent=_haEntities.length.toLocaleString()+' ENTITIES'; renderHATable(_haEntities); } @@ -1635,6 +1640,7 @@ async function loadVMs() { document.getElementById('vms-tbl').innerHTML='
SCANNING...
'; const data = await api('vms_list'); const vms = [...(data.vms||[]), ...(data.containers||[])]; + const _vmsCntEl=document.getElementById('vms-count'); if(_vmsCntEl){const _vmRun=vms.filter(v=>v.status==='running').length;_vmsCntEl.textContent=`${_vmRun}/${vms.length} RUNNING`;} if (!vms.length) { document.getElementById('vms-tbl').innerHTML='
NO VM DATA — Proxmox cache empty, refreshes every 5 min
'; return; } const ni = data.node_info||{};
NAMEPATTERNRESPONSETYPEPRISTATUSACTIONS