From cc7c23a9c73214ccd46d7e6f5c7a5211a34e0a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D1=82=D0=BE=D0=BD=20=D0=A2=D1=80=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Mon, 26 Oct 2026 14:53:36 +0300 Subject: [PATCH] file manager: blue filter button when a filter is active A non-'All' selection turns the collapsed filter button blue (like the active sort pill) so it stands out; 'All' keeps the default style. Frontend 1161 tests green. --- frontend/index.html | 12 +++++++++++- frontend/tests/fs_filter.test.js | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) 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();