From d4ab01c152dbe8acef4da2f102815088dba98d75 Mon Sep 17 00:00:00 2001 From: Nathan Esquenazi Date: Fri, 3 Apr 2026 19:38:33 +0000 Subject: [PATCH] fix: workspace updates on profile switch; remove redundant topbar workspace chip Two changes: 1. Workspace updates correctly on profile switch switchToProfile() now applies data.default_workspace from the switch response to the current session via /api/session/update, updates S.session.workspace in-memory, and stores S._profileDefaultWorkspace so the next new session also inherits the profile's workspace. newSession() in sessions.js picks up S._profileDefaultWorkspace when creating a new session after a profile switch. 2. Workspace chip removed from topbar The workspace was shown in two places: the topbar chip (wsChip) AND the sidebar bottom display (sidebarWsDisplay with name + full path). The topbar chip was redundant, cluttered the topbar, and pushed other chips (profile, model, clear, settings) off screen. Removed wsChip from the topbar entirely. The sidebar display is now the sole workspace UI, consistent and unambiguous. Moved wsDropdown to live inside the sidebar position:relative wrapper so it opens downward from sidebarWsDisplay. Updated the click-outside listener to close on clicks outside sidebarWsDisplay/wsDropdown. Removed stale wsChip update code from syncTopbar() in ui.js. Tests: 426 passed, 0 failed. --- static/index.html | 20 ++++++++++---------- static/panels.js | 20 +++++++++++++++++++- static/sessions.js | 4 +++- static/style.css | 2 +- static/ui.js | 7 ------- 5 files changed, 33 insertions(+), 20 deletions(-) diff --git a/static/index.html b/static/index.html index a4f87ee..c9bd642 100644 --- a/static/index.html +++ b/static/index.html @@ -145,13 +145,16 @@ -
- 📁 -
-
Workspace
-
+
+
+ 📁 +
+
Workspace
+
+
+
- +
GPT-5.4 Mini
-
-
📁 test-workspace ▾
-
-
+ diff --git a/static/panels.js b/static/panels.js index 4825f59..1ad076c 100644 --- a/static/panels.js +++ b/static/panels.js @@ -490,7 +490,7 @@ function closeWsDropdown(){ if(dd)dd.classList.remove('open'); } document.addEventListener('click',e=>{ - if(!e.target.closest('#wsChipWrap'))closeWsDropdown(); + if(!e.target.closest('#sidebarWsDisplay') && !e.target.closest('#wsDropdown'))closeWsDropdown(); }); async function loadWorkspacesPanel(){ @@ -683,6 +683,24 @@ async function switchToProfile(name) { // Refresh workspace list (now profile-local) _workspaceList = null; await loadWorkspaceList(); + + // Apply the profile's default workspace to the current session + if (data.default_workspace) { + if (S.session) { + // Update existing session's workspace to the profile default + try { + await api('/api/session/update', { method: 'POST', body: JSON.stringify({ + session_id: S.session.session_id, + workspace: data.default_workspace, + model: S.session.model, + })}); + S.session.workspace = data.default_workspace; + } catch (_) {} + } + // Store as the profile default so the next new session picks it up + S._profileDefaultWorkspace = data.default_workspace; + } + // Reset profile filter and refresh session list _showAllProfiles = false; await renderSessionList(); diff --git a/static/sessions.js b/static/sessions.js index 154564f..dba98d5 100644 --- a/static/sessions.js +++ b/static/sessions.js @@ -13,7 +13,9 @@ async function newSession(flash){ MSG_QUEUE.length=0;updateQueueBadge(); S.toolCalls=[]; clearLiveToolCards(); - const inheritWs=S.session?S.session.workspace:null; + // Use profile default workspace for new sessions after a profile switch, + // otherwise inherit from the current session (or let server pick the default) + const inheritWs=S._profileDefaultWorkspace||( S.session?S.session.workspace:null); const data=await api('/api/session/new',{method:'POST',body:JSON.stringify({model:$('modelSelect').value,workspace:inheritWs})}); S.session=data.session;S.messages=data.session.messages||[]; if(flash)S.session._flash=true; diff --git a/static/style.css b/static/style.css index 82d8daa..b13bfda 100644 --- a/static/style.css +++ b/static/style.css @@ -345,7 +345,7 @@ /* ── Workspace dropdown (topbar) ── */ .ws-chip{user-select:none;} -.ws-dropdown{display:none;position:absolute;top:calc(100% + 6px);right:0;min-width:240px;background:#1a2535;border:1px solid var(--border2);border-radius:10px;box-shadow:0 8px 24px rgba(0,0,0,.4);z-index:200;overflow:hidden;max-height:320px;overflow-y:auto;} +.ws-dropdown{display:none;position:absolute;top:calc(100% + 4px);left:0;right:0;min-width:200px;background:#1a2535;border:1px solid var(--border2);border-radius:10px;box-shadow:0 8px 24px rgba(0,0,0,.4);z-index:200;overflow:hidden;max-height:320px;overflow-y:auto;} .ws-dropdown.open{display:block;} .ws-opt{padding:9px 14px;cursor:pointer;transition:background .12s;} .ws-opt:hover{background:rgba(255,255,255,.07);} diff --git a/static/ui.js b/static/ui.js index fae9b7c..a4f8c07 100644 --- a/static/ui.js +++ b/static/ui.js @@ -336,13 +336,6 @@ function syncTopbar(){ const displayModel=$('modelSelect').value||m; $('modelChip').textContent=getModelLabel(displayModel); const ws=S.session.workspace||''; - $('wsChip').textContent=ws.split('/').slice(-2).join('/')||ws; - // Update workspace chip in topbar with friendly name from workspace list - const wsChipEl=$('wsChip'); - if(wsChipEl){ - const wsFriendly=getWorkspaceFriendlyName(ws); - wsChipEl.textContent='\u{1F4C1} '+wsFriendly+' \u25BE'; - } // Update sidebar workspace display const sidebarName=$('sidebarWsName'); const sidebarPath=$('sidebarWsPath');