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();