diff --git a/frontend/index.html b/frontend/index.html
index 08d43c5..e11aef1 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -16296,7 +16296,17 @@ function pysimFsFilterRender() {
}
menu.innerHTML = out;
}
- if (btn) btn.textContent = pysimFsFilterSummary();
+ if (btn) {
+ btn.textContent = pysimFsFilterSummary();
+ // a non-"All" selection stands out (blue, like the active sort pill)
+ const active = pysimFsFilter.size > 0 && !pysimFsFilter.has(FS_FILTER_ALL);
+ btn.classList.toggle('bg-blue-600', active);
+ btn.classList.toggle('text-white', active);
+ btn.classList.toggle('text-gray-700', !active);
+ btn.classList.toggle('dark:text-slate-300', !active);
+ btn.classList.toggle('hover:bg-gray-200', !active);
+ btn.classList.toggle('dark:hover:bg-slate-700', !active);
+ }
}
// Expand or collapse the menu (`force` overrides the toggle; the outside
diff --git a/frontend/tests/fs_filter.test.js b/frontend/tests/fs_filter.test.js
index b2c0928..2a447f5 100644
--- a/frontend/tests/fs_filter.test.js
+++ b/frontend/tests/fs_filter.test.js
@@ -73,9 +73,19 @@ globalThis.pysimFsRenderTree = () => { _treeRenders++; };
// menu it expands into. The menu only needs a settable innerHTML (the
// render never reads the DOM back) and a classList for the open/closed state.
function fakeBtn() {
+ const classes = new Set();
return {
textContent: '',
attrs: {},
+ classes,
+ classList: {
+ contains: c => classes.has(c),
+ toggle(c, force) {
+ const on = force === undefined ? !classes.has(c) : !!force;
+ if (on) classes.add(c); else classes.delete(c);
+ return on;
+ },
+ },
setAttribute(k, v) { this.attrs[k] = String(v); },
getAttribute(k) { return this.attrs[k]; },
};
@@ -429,6 +439,21 @@ test('the menu lists all, custom, the three headings and the services', () => {
assert.match(out, /onchange="pysimFsFilterSetEntry\(this\.dataset\.filter, this\.checked\)"/);
});
+test('the button turns blue when a filter is active and back for all', () => {
+ dom.menu = fakeMenu();
+ dom.btn = fakeBtn();
+ pysimFsFilter = new Set(['identifiers']);
+ pysimFsFilterRender();
+ assert.strictEqual(dom.btn.classes.has('bg-blue-600'), true);
+ assert.strictEqual(dom.btn.classes.has('text-white'), true);
+ assert.strictEqual(dom.btn.classes.has('text-gray-700'), false);
+ pysimFsFilter = new Set(['all']);
+ pysimFsFilterRender();
+ assert.strictEqual(dom.btn.classes.has('bg-blue-600'), false);
+ assert.strictEqual(dom.btn.classes.has('text-white'), false);
+ assert.strictEqual(dom.btn.classes.has('text-gray-700'), true);
+});
+
test('the menu marks the saved selection', () => {
pysimFsFilter = new Set(['svc:Short Message Storage (SMS)', 'identifiers']);
dom.menu = fakeMenu();