fix(sidebar): align session source counts with rendered rows (#3966)
This commit is contained in:
@@ -4766,6 +4766,28 @@ function _partitionSidebarSessionRows(allMatched, activeSidForSidebar){
|
||||
};
|
||||
}
|
||||
|
||||
function _renderSidebarRowsFromRawSessions(sessionsRaw){
|
||||
return _attachChildSessionsToSidebarRows(_collapseSessionLineageForSidebar(sessionsRaw), sessionsRaw);
|
||||
}
|
||||
|
||||
function _countRenderedSidebarRows(allMatched, activeSidForSidebar, showCliOnly){
|
||||
const sessionsRaw=[];
|
||||
for(const s of allMatched){
|
||||
if(!_sidebarRowHasVisibleMessages(s, activeSidForSidebar)) continue;
|
||||
const isCli=_isCliSession(s);
|
||||
if(showCliOnly ? !isCli : isCli) continue;
|
||||
if(s.default_hidden&&!(_activeProject&&_activeProject!==NO_PROJECT_FILTER&&s.project_id===_activeProject)) continue;
|
||||
if(_activeProject===NO_PROJECT_FILTER){
|
||||
if(s.project_id) continue;
|
||||
} else if(_activeProject){
|
||||
if(s.project_id!==_activeProject) continue;
|
||||
}
|
||||
if(!_showArchived&&s.archived) continue;
|
||||
sessionsRaw.push(s);
|
||||
}
|
||||
return _renderSidebarRowsFromRawSessions(sessionsRaw).length;
|
||||
}
|
||||
|
||||
function renderSessionListFromCache(){
|
||||
// Don't re-render while user is actively renaming a session (would destroy the input)
|
||||
if(_renamingSid) return;
|
||||
@@ -4795,7 +4817,13 @@ function renderSessionListFromCache(){
|
||||
sessionsRaw,
|
||||
archivedCount,
|
||||
}=_partitionSidebarSessionRows(allMatched, activeSidForSidebar);
|
||||
const sessions=_attachChildSessionsToSidebarRows(_collapseSessionLineageForSidebar(sessionsRaw), sessionsRaw);
|
||||
const sessions=_renderSidebarRowsFromRawSessions(sessionsRaw);
|
||||
const renderedWebuiSessionCount=_sessionSourceFilter==='webui'
|
||||
? sessions.length
|
||||
: _countRenderedSidebarRows(allMatched, activeSidForSidebar, false);
|
||||
const renderedCliSessionCount=_sessionSourceFilter==='cli'
|
||||
? sessions.length
|
||||
: _countRenderedSidebarRows(allMatched, activeSidForSidebar, true);
|
||||
_syncSidebarExpansionForActiveSession(sessions, activeSidForSidebar);
|
||||
const list=$('sessionList');
|
||||
const animateRefresh=_sessionListRefreshAnimationPending;
|
||||
@@ -4830,7 +4858,7 @@ function renderSessionListFromCache(){
|
||||
const sourceTabs=document.createElement('div');
|
||||
sourceTabs.className='session-source-tabs';
|
||||
for(const filter of ['webui','cli']){
|
||||
const count=filter==='cli'?cliSessionCount:webuiSessionCount;
|
||||
const count=filter==='cli'?renderedCliSessionCount:renderedWebuiSessionCount;
|
||||
const btn=document.createElement('button');
|
||||
btn.type='button';
|
||||
btn.className='session-source-tab'+(_sessionSourceFilter===filter?' active':'');
|
||||
|
||||
32
tests/test_issue3966_session_count_label.py
Normal file
32
tests/test_issue3966_session_count_label.py
Normal file
@@ -0,0 +1,32 @@
|
||||
"""Regression coverage for sidebar source counts using rendered rows."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
SESSIONS_JS = (ROOT / "static" / "sessions.js").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def test_render_counts_use_post_collapse_rows():
|
||||
render_start = SESSIONS_JS.index("function renderSessionListFromCache()")
|
||||
render_end = SESSIONS_JS.index("function _showProjectPicker", render_start)
|
||||
render_body = SESSIONS_JS[render_start:render_end]
|
||||
|
||||
assert "const sessions=_renderSidebarRowsFromRawSessions(sessionsRaw);" in render_body
|
||||
assert "? sessions.length" in render_body
|
||||
assert ": _countRenderedSidebarRows(allMatched, activeSidForSidebar, false);" in render_body
|
||||
assert ": _countRenderedSidebarRows(allMatched, activeSidForSidebar, true);" in render_body
|
||||
assert "const count=filter==='cli'?renderedCliSessionCount:renderedWebuiSessionCount;" in render_body
|
||||
assert "const count=filter==='cli'?cliSessionCount:webuiSessionCount;" not in render_body
|
||||
|
||||
|
||||
def test_rendered_count_helper_collapses_before_counting():
|
||||
helper_start = SESSIONS_JS.index("function _countRenderedSidebarRows(")
|
||||
helper_end = SESSIONS_JS.index("function renderSessionListFromCache()", helper_start)
|
||||
helper_body = SESSIONS_JS[helper_start:helper_end]
|
||||
|
||||
assert "sessionsRaw.push(s);" in helper_body
|
||||
assert "return _renderSidebarRowsFromRawSessions(sessionsRaw).length;" in helper_body
|
||||
assert "function _renderSidebarRowsFromRawSessions(sessionsRaw){" in SESSIONS_JS
|
||||
assert "_attachChildSessionsToSidebarRows(_collapseSessionLineageForSidebar(sessionsRaw), sessionsRaw)" in SESSIONS_JS
|
||||
@@ -20,6 +20,7 @@ def test_render_uses_single_pass_partition_helper():
|
||||
render_body = SESSIONS_JS[render_start:render_end]
|
||||
|
||||
assert "_partitionSidebarSessionRows(allMatched, activeSidForSidebar)" in render_body
|
||||
assert "_renderSidebarRowsFromRawSessions(sessionsRaw)" in render_body
|
||||
assert "withMessages.filter(" not in render_body
|
||||
|
||||
|
||||
@@ -35,3 +36,14 @@ def test_partition_helper_applies_message_source_project_and_archive_gates():
|
||||
assert "return {" in block
|
||||
assert "profileFiltered," in block
|
||||
assert "sessionsRaw," in block
|
||||
|
||||
|
||||
def test_partition_helper_keeps_raw_source_counts_while_render_owns_visible_counts():
|
||||
render_start = SESSIONS_JS.index("function renderSessionListFromCache()")
|
||||
render_end = SESSIONS_JS.index("function _showProjectPicker", render_start)
|
||||
render_body = SESSIONS_JS[render_start:render_end]
|
||||
|
||||
assert "webuiSessionCount," in _partition_block()
|
||||
assert "cliSessionCount," in _partition_block()
|
||||
assert "const renderedWebuiSessionCount=" in render_body
|
||||
assert "const renderedCliSessionCount=" in render_body
|
||||
|
||||
Reference in New Issue
Block a user