fix(sidebar): refresh project-chip payload after filter switch (#4775)
This commit is contained in:
parent
e27b7cf042
commit
df6dba7a94
2 changed files with 51 additions and 5 deletions
|
|
@ -1652,6 +1652,14 @@ function _sessionSourceTabCount(filter, renderedWebuiSessionCount, renderedCliSe
|
|||
return filter === 'cli' ? renderedCliSessionCount : renderedWebuiSessionCount;
|
||||
}
|
||||
|
||||
function _setActiveProjectFilter(projectId) {
|
||||
const next = projectId === NO_PROJECT_FILTER ? NO_PROJECT_FILTER : (projectId || null);
|
||||
if (_activeProject === next) return;
|
||||
_activeProject = next;
|
||||
renderSessionListFromCache();
|
||||
void renderSessionList({deferWhileInteracting:false});
|
||||
}
|
||||
|
||||
function _setSessionSourceFilter(filter) {
|
||||
const next = filter === 'cli' ? 'cli' : 'webui';
|
||||
if (_sessionSourceFilter === next) return;
|
||||
|
|
@ -5740,7 +5748,7 @@ function renderSessionListFromCache(){
|
|||
const allChip=document.createElement('span');
|
||||
allChip.className='project-chip'+(!_activeProject?' active':'');
|
||||
allChip.textContent='All';
|
||||
allChip.onclick=()=>{_activeProject=null;renderSessionListFromCache();};
|
||||
allChip.onclick=()=>{_setActiveProjectFilter(null);};
|
||||
bar.appendChild(allChip);
|
||||
// "Unassigned" chip — only when there are sessions with no project to
|
||||
// filter to. Hidden in the common case where every session is already
|
||||
|
|
@ -5750,7 +5758,7 @@ function renderSessionListFromCache(){
|
|||
noneChip.className='project-chip no-project'+(_activeProject===NO_PROJECT_FILTER?' active':'');
|
||||
noneChip.textContent='Unassigned';
|
||||
noneChip.title='Show conversations not yet assigned to a project';
|
||||
noneChip.onclick=()=>{_activeProject=NO_PROJECT_FILTER;renderSessionListFromCache();};
|
||||
noneChip.onclick=()=>{_setActiveProjectFilter(NO_PROJECT_FILTER);};
|
||||
bar.appendChild(noneChip);
|
||||
}
|
||||
// Project chips
|
||||
|
|
@ -5769,7 +5777,7 @@ function renderSessionListFromCache(){
|
|||
let _pClickTimer=null;
|
||||
chip.onclick=(e)=>{
|
||||
clearTimeout(_pClickTimer);
|
||||
_pClickTimer=setTimeout(()=>{_pClickTimer=null;_activeProject=p.project_id;renderSessionListFromCache();},220);
|
||||
_pClickTimer=setTimeout(()=>{_pClickTimer=null;_setActiveProjectFilter(p.project_id);},220);
|
||||
};
|
||||
chip.ondblclick=(e)=>{e.stopPropagation();clearTimeout(_pClickTimer);_pClickTimer=null;_startProjectRename(p,chip);};
|
||||
chip.oncontextmenu=(e)=>{e.preventDefault();_showProjectContextMenu(e,p,chip);};
|
||||
|
|
|
|||
|
|
@ -238,6 +238,7 @@ def test_omit_exclude_hidden_still_returns_default_hidden_rows(monkeypatch):
|
|||
def test_default_and_unassigned_queries_send_exclude_hidden(monkeypatch):
|
||||
src = SESSIONS_JS.read_text(encoding="utf-8")
|
||||
requested_source_fn = _extract_function(src, "_requestedSessionSidebarSource")
|
||||
project_filter_fn = _extract_function(src, "_setActiveProjectFilter")
|
||||
query_fn = _extract_function(src, "_sessionListQueryString")
|
||||
script = f"""
|
||||
global.window = {{ _showCliSessions: false }};
|
||||
|
|
@ -246,12 +247,15 @@ global._showAllProfiles = false;
|
|||
global._showArchived = false;
|
||||
global._activeProject = null;
|
||||
global.NO_PROJECT_FILTER = '__none__';
|
||||
global.renderSessionListFromCache = () => {{}};
|
||||
global.renderSessionList = () => Promise.resolve();
|
||||
{requested_source_fn}
|
||||
{project_filter_fn}
|
||||
{query_fn}
|
||||
const default_query = _sessionListQueryString();
|
||||
global._activeProject = '__none__';
|
||||
_setActiveProjectFilter('__none__');
|
||||
const unassigned_query = _sessionListQueryString();
|
||||
global._activeProject = 'demo-project';
|
||||
_setActiveProjectFilter('demo-project');
|
||||
const named_project_query = _sessionListQueryString();
|
||||
console.log(JSON.stringify({{ default_query, unassigned_query, named_project_query }}));
|
||||
"""
|
||||
|
|
@ -262,6 +266,40 @@ console.log(JSON.stringify({{ default_query, unassigned_query, named_project_que
|
|||
assert body["named_project_query"] == "?sidebar_source=webui"
|
||||
|
||||
|
||||
@pytest.mark.skipif(NODE is None, reason="node not on PATH")
|
||||
def test_project_filter_click_path_triggers_fresh_session_load():
|
||||
src = SESSIONS_JS.read_text(encoding="utf-8")
|
||||
project_filter_fn = _extract_function(src, "_setActiveProjectFilter")
|
||||
script = f"""
|
||||
const calls = [];
|
||||
global.NO_PROJECT_FILTER = '__none__';
|
||||
global._activeProject = null;
|
||||
global.renderSessionListFromCache = () => {{
|
||||
calls.push('cache');
|
||||
}};
|
||||
global.renderSessionList = (opts) => {{
|
||||
calls.push(opts);
|
||||
return Promise.resolve();
|
||||
}};
|
||||
{project_filter_fn}
|
||||
_setActiveProjectFilter('demo-project');
|
||||
_setActiveProjectFilter('__none__');
|
||||
console.log(JSON.stringify({{
|
||||
activeProject: global._activeProject,
|
||||
calls,
|
||||
}}));
|
||||
"""
|
||||
body = _run_node(script)
|
||||
|
||||
assert body["activeProject"] == "__none__"
|
||||
assert body["calls"] == [
|
||||
"cache",
|
||||
{"deferWhileInteracting": False},
|
||||
"cache",
|
||||
{"deferWhileInteracting": False},
|
||||
]
|
||||
|
||||
|
||||
def test_cache_key_varies_for_exclude_hidden_and_visible_only():
|
||||
key_without_filters = routes._session_list_cache_key(
|
||||
active_profile="default",
|
||||
|
|
|
|||
Loading…
Reference in a new issue