feat: remove 'filtered' gridViewMode, keep only flat and grouped

- 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
This commit is contained in:
Brian Krabach
2026-04-15 14:05:28 -07:00
parent 68fa80b694
commit 70822d8033
2 changed files with 66 additions and 22 deletions
+9 -22
View File
@@ -762,11 +762,6 @@ function renderGrid(sessions) {
var visible = getVisibleSessions(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) { if (visible.length === 0) {
// Build status tiles for auth_failed/unreachable sessions even when no regular sessions exist // Build status tiles for auth_failed/unreachable sessions even when no regular sessions exist
var statusTilesHtml = ''; var statusTilesHtml = '';
@@ -781,14 +776,7 @@ function renderGrid(sessions) {
if (statusTilesHtml) emptyState.classList.add('hidden'); if (statusTilesHtml) emptyState.classList.add('hidden');
else emptyState.classList.remove('hidden'); else emptyState.classList.remove('hidden');
} }
// Show filter bar even when filtered to empty (so user can switch back) if (filterBar) filterBar.innerHTML = '';
if (filterBar) {
if (_gridViewMode === 'filtered') {
renderFilterBar(filterBar, sessions);
} else {
filterBar.innerHTML = '';
}
}
return; return;
} }
@@ -821,14 +809,8 @@ function renderGrid(sessions) {
}); });
if (grid) grid.innerHTML = html + statusTilesHtml; if (grid) grid.innerHTML = html + statusTilesHtml;
// Render filter bar // Clear filter bar (filtered mode removed; bar is a no-op for flat/grouped)
if (filterBar) { if (filterBar) filterBar.innerHTML = '';
if (_gridViewMode === 'filtered') {
renderFilterBar(filterBar, sessions);
} else {
filterBar.innerHTML = '';
}
}
// Bind interaction handlers on each tile // Bind interaction handlers on each tile
document.querySelectorAll('.session-tile').forEach(function(tile) { document.querySelectorAll('.session-tile').forEach(function(tile) {
@@ -1551,7 +1533,10 @@ function applyDisplaySettings(ds) {
*/ */
function loadGridViewMode() { function loadGridViewMode() {
var ds = getDisplaySettings(); 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. */ /** Test-only: set _gridViewMode directly. */
function _setGridViewMode(mode) { function _setGridViewMode(mode) {
// 'filtered' was removed in the Views feature — fall back to 'flat'
if (mode === 'filtered') mode = 'flat';
_gridViewMode = mode; _gridViewMode = mode;
} }
+57
View File
@@ -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) " "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" "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"
)