From 70822d803309c31a30ec2a2886809ad2add0afaf Mon Sep 17 00:00:00 2001 From: Brian Krabach Date: Wed, 15 Apr 2026 14:05:28 -0700 Subject: [PATCH] feat: remove 'filtered' gridViewMode, keep only flat and grouped MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - renderGrid: remove all _gridViewMode === 'filtered' branches (device filter application and filter bar rendering); filter bar is now always cleared for flat/grouped modes - loadGridViewMode: add 'filtered' → 'flat' fallback so existing users who had the setting stored don't get a broken state - _setGridViewMode (test helper): same guard so tests can't accidentally set the removed mode - test_frontend_js.py: three new static-analysis tests assert the guards are present and the renderGrid filtered checks are gone --- muxplex/frontend/app.js | 31 +++++------------ muxplex/tests/test_frontend_js.py | 57 +++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 22 deletions(-) diff --git a/muxplex/frontend/app.js b/muxplex/frontend/app.js index 0435be8..4653ea3 100644 --- a/muxplex/frontend/app.js +++ b/muxplex/frontend/app.js @@ -762,11 +762,6 @@ function renderGrid(sessions) { var visible = getVisibleSessions(sessions); - // In filtered mode, apply device filter - if (_gridViewMode === 'filtered' && _activeFilterDevice !== 'all') { - visible = visible.filter(function(s) { return s.deviceName === _activeFilterDevice; }); - } - if (visible.length === 0) { // Build status tiles for auth_failed/unreachable sessions even when no regular sessions exist var statusTilesHtml = ''; @@ -781,14 +776,7 @@ function renderGrid(sessions) { if (statusTilesHtml) emptyState.classList.add('hidden'); else emptyState.classList.remove('hidden'); } - // Show filter bar even when filtered to empty (so user can switch back) - if (filterBar) { - if (_gridViewMode === 'filtered') { - renderFilterBar(filterBar, sessions); - } else { - filterBar.innerHTML = ''; - } - } + if (filterBar) filterBar.innerHTML = ''; return; } @@ -821,14 +809,8 @@ function renderGrid(sessions) { }); if (grid) grid.innerHTML = html + statusTilesHtml; - // Render filter bar - if (filterBar) { - if (_gridViewMode === 'filtered') { - renderFilterBar(filterBar, sessions); - } else { - filterBar.innerHTML = ''; - } - } + // Clear filter bar (filtered mode removed; bar is a no-op for flat/grouped) + if (filterBar) filterBar.innerHTML = ''; // Bind interaction handlers on each tile document.querySelectorAll('.session-tile').forEach(function(tile) { @@ -1551,7 +1533,10 @@ function applyDisplaySettings(ds) { */ function loadGridViewMode() { var ds = getDisplaySettings(); - return ds.gridViewMode || 'flat'; + var mode = ds.gridViewMode || 'flat'; + // 'filtered' was removed in the Views feature — fall back to 'flat' + if (mode === 'filtered') mode = 'flat'; + return mode; } /** @@ -2482,6 +2467,8 @@ function _getGridViewMode() { /** Test-only: set _gridViewMode directly. */ function _setGridViewMode(mode) { + // 'filtered' was removed in the Views feature — fall back to 'flat' + if (mode === 'filtered') mode = 'flat'; _gridViewMode = mode; } diff --git a/muxplex/tests/test_frontend_js.py b/muxplex/tests/test_frontend_js.py index 2a99f5a..c82e8f2 100644 --- a/muxplex/tests/test_frontend_js.py +++ b/muxplex/tests/test_frontend_js.py @@ -2872,3 +2872,60 @@ def test_create_new_session_uses_device_id_variable_internally() -> None: "createNewSession must declare 'var deviceId' internally (assigned from the remoteId parameter) " "to reflect that the value is now a device_id string used in federation API URLs" ) + + +# ─── Task 12: Remove 'filtered' from gridViewMode options ───────────────────── + + +def test_load_grid_view_mode_guards_filtered_value() -> None: + """loadGridViewMode must remap 'filtered' to 'flat' for users who had it set.""" + match = re.search( + r"function loadGridViewMode\s*\(\s*\)\s*\{(.*?)(?=\nfunction |\n// |\n/\*\*)", + _JS, + re.DOTALL, + ) + assert match, "loadGridViewMode function not found" + body = match.group(1) + assert "filtered" in body, ( + "loadGridViewMode must guard against 'filtered': " + "if (mode === 'filtered') mode = 'flat'; — graceful fallback for existing users" + ) + assert "flat" in body, ( + "loadGridViewMode must fall back to 'flat' when mode is 'filtered'" + ) + + +def test_set_grid_view_mode_guards_filtered_value() -> None: + """_setGridViewMode (test helper) must remap 'filtered' to 'flat'.""" + match = re.search( + r"function _setGridViewMode\s*\(\w+\)\s*\{(.*?)(?=\n\})", + _JS, + re.DOTALL, + ) + assert match, "_setGridViewMode function not found" + body = match.group(1) + assert "filtered" in body, ( + "_setGridViewMode must guard against 'filtered': " + "if (mode === 'filtered') mode = 'flat';" + ) + assert "flat" in body, "_setGridViewMode must remap 'filtered' to 'flat'" + + +def test_render_grid_no_filtered_mode_check() -> None: + """renderGrid must not contain any _gridViewMode === 'filtered' check. + + The 'filtered' gridViewMode has been removed. All references in renderGrid + that branch on _gridViewMode === 'filtered' must be deleted so the filter bar + is never rendered and the device-filter logic is never applied. + """ + match = re.search( + r"function renderGrid\s*\(\w+\)\s*\{(.*?)(?=\n(?:function|//|window\.))", + _JS, + re.DOTALL, + ) + assert match, "renderGrid function not found in app.js" + body = match.group(1) + assert "'filtered'" not in body and '"filtered"' not in body, ( + "renderGrid must not check _gridViewMode === 'filtered' — " + "the 'filtered' mode has been removed; only 'flat' and 'grouped' remain" + )