Skip to content

Commit e8c5dcc

Browse files
MDA2AVclaude
andcommitted
Add category filter (Compliance / Smuggling) on Probe Results page
Composes with the existing language filter — both narrow the summary chart independently. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1d93821 commit e8c5dcc

2 files changed

Lines changed: 96 additions & 1 deletion

File tree

docs/content/probe-results/_index.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ HTTP/1.1 compliance comparison across frameworks. Each test sends a specific mal
99
## Summary
1010

1111
<div id="lang-filter"></div>
12+
<div id="cat-filter"></div>
1213
<div id="probe-summary"><p><em>Loading probe data...</em></p></div>
1314

1415
{{< callout type="info" >}}
@@ -23,9 +24,25 @@ These results are from CI runs (`ubuntu-latest`). Click on the **Compliance**, *
2324
document.getElementById('probe-summary').innerHTML = '<p><em>No probe data available yet. Run the Probe workflow manually on <code>main</code> to generate results.</em></p>';
2425
return;
2526
}
27+
var langFiltered = window.PROBE_DATA;
28+
var catFilter = null;
29+
30+
function rerender() {
31+
var data = langFiltered;
32+
if (catFilter) {
33+
data = ProbeRender.filterByCategory(data, catFilter);
34+
}
35+
ProbeRender.renderSummary('probe-summary', data);
36+
}
37+
2638
ProbeRender.renderSummary('probe-summary', window.PROBE_DATA);
2739
ProbeRender.renderLanguageFilter('lang-filter', window.PROBE_DATA, function (filtered) {
28-
ProbeRender.renderSummary('probe-summary', filtered);
40+
langFiltered = filtered;
41+
rerender();
42+
});
43+
ProbeRender.renderCategoryFilter('cat-filter', function (categories) {
44+
catFilter = categories;
45+
rerender();
2946
});
3047
})();
3148
</script>

docs/static/probe/render.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,13 +345,91 @@ window.ProbeRender = (function () {
345345
});
346346
}
347347

348+
// ── Category filter ──────────────────────────────────────────
349+
function filterByCategory(data, categories) {
350+
return {
351+
commit: data.commit,
352+
servers: data.servers.map(function (sv) {
353+
var filtered = sv.results.filter(function (r) {
354+
return categories.indexOf(r.category) !== -1;
355+
});
356+
var scored = filtered.filter(function (r) { return r.scored !== false; });
357+
return {
358+
name: sv.name,
359+
language: sv.language,
360+
results: filtered,
361+
summary: {
362+
total: filtered.length,
363+
scored: scored.length,
364+
passed: scored.filter(function (r) { return r.verdict === 'Pass'; }).length,
365+
failed: scored.filter(function (r) { return r.verdict === 'Fail'; }).length,
366+
warnings: filtered.filter(function (r) { return r.verdict === 'Warn'; }).length,
367+
errors: filtered.filter(function (r) { return r.verdict === 'Error'; }).length
368+
}
369+
};
370+
})
371+
};
372+
}
373+
374+
function renderCategoryFilter(targetId, onChange) {
375+
var el = document.getElementById(targetId);
376+
if (!el) return;
377+
378+
var isDark = document.documentElement.classList.contains('dark');
379+
var baseBg = isDark ? '#21262d' : '#f6f8fa';
380+
var baseFg = isDark ? '#c9d1d9' : '#24292f';
381+
var baseBorder = isDark ? '#30363d' : '#d0d7de';
382+
var activeBg = isDark ? '#1f6feb' : '#0969da';
383+
384+
var btnStyle = 'display:inline-block;padding:4px 12px;font-size:12px;font-weight:600;'
385+
+ 'border-radius:20px;cursor:pointer;border:1px solid ' + baseBorder + ';'
386+
+ 'margin-right:6px;margin-bottom:6px;transition:all 0.15s;';
387+
388+
var filters = [
389+
{ label: 'All', categories: null },
390+
{ label: 'Compliance', categories: ['Compliance', 'Malformed Input'] },
391+
{ label: 'Smuggling', categories: ['Smuggling'] }
392+
];
393+
394+
var html = '<div style="margin-bottom:12px;">';
395+
filters.forEach(function (f, i) {
396+
var isActive = i === 0;
397+
html += '<button class="probe-cat-btn" data-idx="' + i + '" style="' + btnStyle
398+
+ 'background:' + (isActive ? activeBg : baseBg) + ';color:' + (isActive ? '#fff' : baseFg)
399+
+ ';border-color:' + (isActive ? activeBg : baseBorder) + ';">' + f.label + '</button>';
400+
});
401+
html += '</div>';
402+
el.innerHTML = html;
403+
404+
var buttons = el.querySelectorAll('.probe-cat-btn');
405+
buttons.forEach(function (btn) {
406+
btn.addEventListener('click', function () {
407+
var idx = parseInt(btn.getAttribute('data-idx'));
408+
buttons.forEach(function (b) {
409+
if (b === btn) {
410+
b.style.background = activeBg;
411+
b.style.color = '#fff';
412+
b.style.borderColor = activeBg;
413+
} else {
414+
b.style.background = baseBg;
415+
b.style.color = baseFg;
416+
b.style.borderColor = baseBorder;
417+
}
418+
});
419+
onChange(filters[idx].categories);
420+
});
421+
});
422+
}
423+
348424
return {
349425
pill: pill,
350426
verdictBg: verdictBg,
351427
buildLookups: buildLookups,
352428
renderSummary: renderSummary,
353429
renderTable: renderTable,
354430
renderLanguageFilter: renderLanguageFilter,
431+
filterByCategory: filterByCategory,
432+
renderCategoryFilter: renderCategoryFilter,
355433
EXPECT_BG: EXPECT_BG
356434
};
357435
})();

0 commit comments

Comments
 (0)