diff --git a/public/components/assistant.html b/public/components/assistant.html index 4c0ec274..37671251 100644 --- a/public/components/assistant.html +++ b/public/components/assistant.html @@ -39,13 +39,6 @@
-
diff --git a/public/css/assistant.css b/public/css/assistant.css index 91c49b2b..0807b78a 100644 --- a/public/css/assistant.css +++ b/public/css/assistant.css @@ -19,7 +19,7 @@ body.assistant-workspace .assistant-topbar-title h2 { position:absolute; width:1 .assistant-new-chat:hover { border-color:var(--purple); background:var(--purple-light); } .assistant-main { display:flex; flex-direction:column; min-height:calc(100vh - 200px); min-width:0; } #assistant-chat-view { display:grid; grid-template-rows:auto minmax(420px,1fr) auto; min-height:calc(100vh - 200px); min-width:0; } -#assistant-chat-view[hidden], .assistant-workspace-view[hidden] { display:none; } +#assistant-chat-view[hidden] { display:none; } .assistant-toolbar { display:flex; justify-content:space-between; align-items:center; gap:10px; padding:10px 14px; border-bottom:1px solid var(--g200); background:var(--g50); } .assistant-toolbar-actions { display:flex; gap:6px; flex-wrap:wrap; } .assistant-messages { padding:16px; max-height:65vh; overflow-y:auto; overflow-x:hidden; background:linear-gradient(180deg,#fff,var(--g50)); min-width:0; } @@ -161,16 +161,10 @@ body.assistant-workspace .assistant-topbar-title h2 { position:absolute; width:1 .assistant-mode-switch button i { font-size:11px; } .assistant-mode-switch button.active { background:white; color:var(--purple); box-shadow:var(--shadow); } -/* Workspace mode fills the chat column with the app's own menu. */ -.assistant-workspace-view { padding:22px; overflow-y:auto; min-height:0; } -.assistant-workspace-head h2 { margin:0 0 4px; font-size:18px; color:var(--g900); } -.assistant-workspace-head p { margin:0 0 18px; font-size:13px; color:var(--g500); } -.assistant-workspace-cards { display:grid; grid-template-columns:repeat(auto-fill,minmax(190px,1fr)); gap:10px; } -.assistant-workspace-card { display:flex; align-items:center; gap:10px; border:1px solid var(--g200); background:white; border-radius:12px; padding:14px; font-size:13px; color:var(--g800); text-align:left; cursor:pointer; } -.assistant-workspace-card:hover { border-color:var(--purple-light); background:#faf5ff; color:var(--purple); } -.assistant-workspace-card i { width:18px; text-align:center; color:var(--g400); font-size:14px; } -.assistant-workspace-card:hover i { color:var(--purple); } -@media (max-width:640px) { .assistant-workspace-view { padding:14px; } .assistant-workspace-cards { grid-template-columns:1fr 1fr; } } +/* Workspace mode: the sources column goes with it, and the track goes too — + hiding the panel alone left an empty 330px gutter. */ +body.assistant-mode-workspace .assistant-layout { grid-template-columns:260px minmax(0,1fr); } +body.assistant-mode-workspace .assistant-layout.history-collapsed { grid-template-columns:0 minmax(0,1fr); } /* Workspace section in the rail: the app's own menu, one level down, the way Claude's sidebar carries both its chats and its top-level navigation. */ diff --git a/public/js/clinicalAssistant.js b/public/js/clinicalAssistant.js index fc7d1b6a..10b5535c 100644 --- a/public/js/clinicalAssistant.js +++ b/public/js/clinicalAssistant.js @@ -165,10 +165,8 @@ import { // added, renamed or hidden in index.html shows up here with no extra work. var renderWorkspaceLinks = function() { var host = document.getElementById('assistant-workspace-links'); - var cards = document.getElementById('assistant-workspace-cards'); if (!host) return; host.innerHTML = ''; - if (cards) cards.innerHTML = ''; Array.prototype.forEach.call(document.querySelectorAll('.tab-btn'), function(tab) { var name = tab.getAttribute('data-tab'); if (!name || name === 'assistant' || tab.classList.contains('hidden')) return; @@ -181,15 +179,6 @@ import { link.innerHTML = '' + '' + escapeHtml(label ? label.textContent : name) + ''; host.appendChild(link); - if (cards) { - var card = document.createElement('button'); - card.type = 'button'; - card.className = 'assistant-workspace-card'; - card.setAttribute('data-assistant-workspace-tab', name); - card.innerHTML = '' + - '' + escapeHtml(label ? label.textContent : name) + ''; - cards.appendChild(card); - } }); }; @@ -202,15 +191,13 @@ import { var chats = document.querySelector('.assistant-history .card'); var newChat = document.getElementById('btn-assistant-clear'); var createImage = document.getElementById('btn-assistant-create-image'); - var chatView = document.getElementById('assistant-chat-view'); - var workspaceView = document.getElementById('assistant-workspace-view'); if (workspace) renderWorkspaceLinks(); if (rail) rail.hidden = !workspace; if (chats) chats.hidden = workspace; if (newChat) newChat.hidden = workspace; if (createImage) createImage.hidden = workspace; - if (chatView) chatView.hidden = workspace; - if (workspaceView) workspaceView.hidden = !workspace; + // The chat column stays put. Only the rail swaps, so switching modes is a + // change of menu rather than a jump to a page that looks nothing like it. var side = document.querySelector('.assistant-side'); if (side) side.hidden = workspace || !citationsOn; document.body.classList.toggle('assistant-mode-workspace', workspace); diff --git a/test/assistant-workspace-layout.test.js b/test/assistant-workspace-layout.test.js index 010df918..2544307d 100644 --- a/test/assistant-workspace-layout.test.js +++ b/test/assistant-workspace-layout.test.js @@ -188,14 +188,18 @@ test('the rail switches between Assistant and Workspace like Home and Code', () assert.match(html, /assistant-mode-switch/, 'a two-pill switch sits at the top of the rail'); assert.match(html, /data-assistant-mode="assistant"/); assert.match(html, /data-assistant-mode="workspace"/); - assert.match(html, /id="assistant-workspace-view"[^>]*hidden/, 'workspace view starts hidden'); + // ONE menu, not two: switching modes swaps the rail, it does not jump to a + // page that looks nothing like the assistant. + assert.doesNotMatch(html, /assistant-workspace-cards/, 'no second copy of the menu in the main column'); const js = fs.readFileSync(path.join(root, 'public/js/clinicalAssistant.js'), 'utf8'); - // Workspace must REPLACE the chat column and the sources panel, not sit beside them. - assert.match(js, /if \(chatView\) chatView\.hidden = workspace;/); - assert.match(js, /if \(workspaceView\) workspaceView\.hidden = !workspace;/); - assert.match(js, /if \(side\) side\.hidden = workspace \|\| !citationsOn;/, 'sources go too'); + assert.match(js, /if \(side\) side\.hidden = workspace \|\| !citationsOn;/, 'sources are hidden in workspace mode'); assert.match(js, /if \(chats\) chats\.hidden = workspace;/, 'and the saved-chat list'); + + const css = fs.readFileSync(path.join(root, 'public/css/assistant.css'), 'utf8'); + // Hiding the panel without dropping its track leaves an empty 330px gutter. + assert.match(css, /body\.assistant-mode-workspace \.assistant-layout \{ grid-template-columns:260px minmax\(0,1fr\); \}/); + assert.match(css, /body\.assistant-mode-workspace \.assistant-layout\.history-collapsed \{ grid-template-columns:0 minmax\(0,1fr\); \}/); }); test('Learning Hub sits with the content tools, not above the clinical ones', () => {