@@ -179,10 +179,34 @@ const STYLE = `
179179/* ── Section headers ─────────────────────────────────────────────────── */
180180.section-hdr{
181181 display:flex;
182- align-items:baseline ;
182+ align-items:center ;
183183 gap:12px;
184184 margin-bottom:14px;
185185}
186+
187+ /* ── Form filter buttons ─────────────────────────────────────────────── */
188+ .form-filter-btns{
189+ margin-left:auto;
190+ display:flex;
191+ gap:6px;
192+ align-items:center;
193+ }
194+ .form-filter-btn{
195+ padding:4px 12px;
196+ border-radius:6px;
197+ border:1px solid var(--border);
198+ background:white;
199+ font-size:11px;
200+ font-weight:600;
201+ color:var(--muted);
202+ cursor:pointer;
203+ transition:background .15s,color .15s,border-color .15s;
204+ font-family:'IBM Plex Sans',system-ui,sans-serif;
205+ }
206+ .form-filter-btn:hover{background:#f8fafc}
207+ .form-filter-btn.active[data-filter="both"]{background:var(--navy);color:white;border-color:var(--navy)}
208+ .form-filter-btn.active[data-filter="v1"]{background:var(--blue-lt);color:var(--blue);border-color:var(--blue-mid)}
209+ .form-filter-btn.active[data-filter="eds"]{background:var(--purple-lt);color:var(--purple);border-color:var(--purple-mid)}
186210.section-hdr h2{
187211 font-family:'Playfair Display',Georgia,serif;
188212 font-size:20px;
@@ -816,8 +840,11 @@ function renderCallouts(callouts) {
816840 </div>` ;
817841}
818842
819- function renderTrendsTable ( weeks ) {
820- const latest = weeks [ weeks . length - 1 ] ;
843+ function renderTrendsTable ( weeks , formFilter = 'both' ) {
844+ if ( ! weeks . length ) {
845+ return '<p class="empty" style="padding:16px;color:var(--muted)">No weekly data available.</p>' ;
846+ }
847+ const last = weeks [ weeks . length - 1 ] ;
821848
822849 const thead = `
823850 <thead>
@@ -833,11 +860,44 @@ function renderTrendsTable(weeks) {
833860 </thead>` ;
834861
835862 const rows = weeks . slice ( ) . reverse ( ) . map ( ( w , i ) => {
836- const isLatest = w . week === latest . week ;
863+ const isLatest = w . week === last . week ;
837864 const isAlt = ! isLatest && i % 2 === 1 ;
838865 const rowClass = isLatest ? 'row-latest' : isAlt ? 'row-group-alt' : '' ;
839866 const contClass = isLatest ? 'row-latest-cont' : isAlt ? 'row-group-alt-cont' : '' ;
840867
868+ const weekCell = `
869+ <td class="week-cell">
870+ <div class="week-num">${ w . week || w . label } </div>
871+ <div class="week-dates">${ w . dateRange || '' } </div>
872+ ${ w . reportUrl ? `<a class="report-link" href="${ w . reportUrl } " target="_blank">Report ↗</a>` : '' }
873+ </td>` ;
874+
875+ if ( formFilter === 'v1' ) {
876+ return `
877+ <tr class="${ rowClass } ">
878+ ${ weekCell }
879+ <td><span class="form-badge form-v1">V1</span></td>
880+ <td class="num num-v1">${ fmt ( w . v1 ?. pageViews ) } </td>
881+ <td class="num num-err">${ fmt ( w . v1 ?. jsErrors ) } </td>
882+ <td class="num num-muted">${ fmt ( w . v1 ?. missingResources ) } </td>
883+ <td class="num num-v1">${ w . v1 ?. visibilityP50 || '—' } </td>
884+ <td class="num num-muted">${ w . v1 ?. visibilityP75 || '—' } </td>
885+ </tr>` ;
886+ }
887+
888+ if ( formFilter === 'eds' ) {
889+ return `
890+ <tr class="${ rowClass } ">
891+ ${ weekCell }
892+ <td><span class="form-badge form-eds">EDS</span></td>
893+ <td class="num num-eds">${ fmt ( w . eds ?. pageViews ) } </td>
894+ <td class="num num-eds">${ fmt ( w . eds ?. jsErrors ) } </td>
895+ <td class="num num-muted">${ fmt ( w . eds ?. missingResources ) } </td>
896+ <td class="num num-eds">${ w . eds ?. visibilityP50 || '—' } </td>
897+ <td class="num num-muted">${ w . eds ?. visibilityP75 || '—' } </td>
898+ </tr>` ;
899+ }
900+
841901 return `
842902 <tr class="${ rowClass } ">
843903 <td class="week-cell" rowspan="2">
@@ -974,6 +1034,19 @@ class ExecutiveDashboard extends HTMLElement {
9741034 ? latestMonth . label . split ( ' ' ) [ 0 ] . slice ( 0 , 3 ) . toUpperCase ( )
9751035 : ( latest . week || latest . label ) ;
9761036
1037+ const aprilWeeks = latestMonth
1038+ ? weekly . filter ( w => {
1039+ const wStart = new Date ( w . startDate ) ;
1040+ const wEnd = new Date ( w . endDate ) ;
1041+ const mStart = new Date ( latestMonth . startDate ) ;
1042+ const mEnd = new Date ( latestMonth . endDate ) ;
1043+ return wStart <= mEnd && wEnd >= mStart ;
1044+ } )
1045+ : weekly ;
1046+ const trendsFirst = aprilWeeks [ 0 ] ?. week || '' ;
1047+ const trendsLast = aprilWeeks [ aprilWeeks . length - 1 ] ?. week || '' ;
1048+ const trendsSubText = `${ trendsFirst } – ${ trendsLast } · one row per form type` ;
1049+
9771050 wrapper . innerHTML = `
9781051 <div class="hero">
9791052 <div class="hero-left">
@@ -999,9 +1072,14 @@ class ExecutiveDashboard extends HTMLElement {
9991072 <div>
10001073 <div class="section-hdr">
10011074 <h2>Weekly Trends</h2>
1002- <span class="section-sub">${ weekly [ 0 ] ?. week || '' } – ${ latest . week || latest . label } · one row per form type</span>
1075+ <span class="section-sub">${ trendsSubText } </span>
1076+ <div class="form-filter-btns" id="trends-filter-btns">
1077+ <button class="form-filter-btn active" data-filter="both">Both</button>
1078+ <button class="form-filter-btn" data-filter="v1">V1</button>
1079+ <button class="form-filter-btn" data-filter="eds">EDS</button>
1080+ </div>
10031081 </div>
1004- ${ renderTrendsTable ( weekly ) }
1082+ <div id="trends-table-wrap"> ${ renderTrendsTable ( aprilWeeks ) } </div>
10051083 </div>
10061084
10071085 <div class="monthly-section">
@@ -1017,6 +1095,21 @@ class ExecutiveDashboard extends HTMLElement {
10171095 </div>
10181096
10191097 </div>` ;
1098+
1099+ // Wire up trends form filter
1100+ const filterBtns = shadow . getElementById ( 'trends-filter-btns' ) ;
1101+ const trendsWrap = shadow . getElementById ( 'trends-table-wrap' ) ;
1102+ if ( filterBtns && trendsWrap ) {
1103+ filterBtns . addEventListener ( 'click' , ( e ) => {
1104+ const btn = e . target . closest ( '[data-filter]' ) ;
1105+ if ( ! btn ) {
1106+ return ;
1107+ }
1108+ filterBtns . querySelectorAll ( '.form-filter-btn' ) . forEach ( b => b . classList . remove ( 'active' ) ) ;
1109+ btn . classList . add ( 'active' ) ;
1110+ trendsWrap . innerHTML = renderTrendsTable ( aprilWeeks , btn . dataset . filter ) ;
1111+ } ) ;
1112+ }
10201113 }
10211114}
10221115
0 commit comments