From 0b1c65c015ec84734149009bf6476443bcce7bd9 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Fri, 17 Jul 2026 18:39:03 -0500 Subject: refactor(gallery): extract the shared tally-row markup The validation and policy tallies were built from the same dot/label/count row template, written out per bucket in both. That template is now tallyRow() and tallyTotal(), so the markup has one source and the next index tally reuses it. The differing count and jump logic stays in each function, since those genuinely diverge: the validation tally drives the floating audit stepper, the policy tally a plain hash cycle. Also hoisted GW.POLICIES[kind] to a local in card(), where it was read three times. Behaviour-preserving: the output HTML is byte-identical. --- docs/prototypes/panel-widget-gallery.html | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'docs/prototypes') diff --git a/docs/prototypes/panel-widget-gallery.html b/docs/prototypes/panel-widget-gallery.html index 95b3719..a31f578 100644 --- a/docs/prototypes/panel-widget-gallery.html +++ b/docs/prototypes/panel-widget-gallery.html @@ -1154,16 +1154,23 @@ function gvCopy(btn){ Clicking a row jumps to the next card in that state (cycles), so a count that disagrees with a visual scan can be audited card by card. */ const VJUMP={green:0,amber:0,off:0}; +/* shared tally-row markup for the index panels (validation + policy): the same + dot/label/count row was written out per bucket in both tallies. attr names the + grouping attribute (data-v or data-g); dot is the .vdot state or '' for none. */ +function tallyRow(attr,key,dot,label,n){ + return `
${label}${n}
`; +} +function tallyTotal(n){return `
total${n}
`;} function updateVTally(){ const el=$('vtally'); if(!el)return; const lamps=[...document.querySelectorAll('.vlamp')]; const n={off:0,amber:0,green:0}; lamps.forEach(l=>{n[l.dataset.v]=(n[l.dataset.v]||0)+1;}); el.innerHTML= - `
done${n.green}
`+ - `
in progress${n.amber}
`+ - `
not done${n.off}
`+ - `
total${lamps.length}
`+ + tallyRow('data-v','green','green','done',n.green)+ + tallyRow('data-v','amber','amber','in progress',n.amber)+ + tallyRow('data-v','off','','not done',n.off)+ + tallyTotal(lamps.length)+ ``; el.querySelectorAll('.vrow[data-v]').forEach(row=>row.addEventListener('click',()=>{ VJUMP[row.dataset.v]=0; auditNext(row.dataset.v); @@ -1213,8 +1220,9 @@ function cardPolicy(html){ function card(host, no, name, html, note){ const isBuild=typeof html==='function'; const P=cardPolicy(html), kind=P&&P.kind; - const free=kind&&GW.POLICIES[kind]&&GW.POLICIES[kind].free; - const polTip=kind?(GW.POLICIES[kind].gist||''):'policy not yet classified'; + const meta=kind&&GW.POLICIES[kind]; + const free=meta&&meta.free; + const polTip=meta?(meta.gist||''):'policy not yet classified'; const c=document.createElement('div'); c.className='card'; c.id='card-'+no; c.dataset.cpol=kind||'none'; c.innerHTML=`
${no}${name}`+ @@ -1232,7 +1240,7 @@ function card(host, no, name, html, note){ if(inf){const d=document.createElement('details'); d.className='winfo'; let rows=''; if(P){ - rows+=`
policy
${kind} — ${GW.POLICIES[kind].gist}
`; + rows+=`
policy
${kind} — ${meta.gist}
`; rows+=`
why
${P.why}
`; rows+=`
authentic
${P.authentic}
`; } else { @@ -1260,10 +1268,10 @@ function updatePolTally(){ const n={free:0,locked:0,none:0}; cards.forEach(c=>{n[grp(c.dataset.cpol)]++;}); el.innerHTML= - `
free${n.free}
`+ - `
locked${n.locked}
`+ - `
unclassified${n.none}
`+ - `
total${cards.length}
`; + tallyRow('data-g','free','green','free',n.free)+ + tallyRow('data-g','locked','amber','locked',n.locked)+ + tallyRow('data-g','none','','unclassified',n.none)+ + tallyTotal(cards.length); el.querySelectorAll('.vrow[data-g]').forEach(row=>row.addEventListener('click',()=>{ const g=row.dataset.g, hits=cards.filter(c=>grp(c.dataset.cpol)===g); if(!hits.length)return; const i=PJUMP[g]++%hits.length; -- cgit v1.2.3