From 5f965cdb300bc46ff1791cf26d7e0e78afc38255 Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sun, 15 Nov 2026 06:27:19 -0600 Subject: [PATCH] fix(webui): sp7 review shots, a pane header keeps its title, Full view, Messages and close on one row with the organization and project below (#1873, lane sp7-polish) --- packages/webui/src/public/assistant.css | 5 ++++- packages/webui/src/public/assistant.js | 8 +++++--- .../tests/assistant-threads-browser.test.mjs | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/packages/webui/src/public/assistant.css b/packages/webui/src/public/assistant.css index 98cd61b92..a3708e91b 100644 --- a/packages/webui/src/public/assistant.css +++ b/packages/webui/src/public/assistant.css @@ -38,7 +38,10 @@ html[data-organizations] .assist-pane{display:flex;flex-direction:column;min-wid html[data-organizations] .assist-pane-h{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid var(--line);box-shadow:inset 0 3px 0 var(--org,var(--line));min-width:0;flex-wrap:wrap} html[data-organizations] .assist-pane-h h2{margin:0;font-size:15px;font-weight:700;color:var(--strong,var(--text));overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:5em;flex:1 1 0} html[data-organizations] .assist-pane-h h2:focus{outline:none} -html[data-organizations] .assist-chips{display:inline-flex;gap:6px;flex-wrap:wrap;min-width:0} +html[data-organizations] .assist-chips{display:inline-flex;gap:6px;flex-wrap:wrap;min-width:0;order:1;flex:1 0 100%} +html[data-organizations] .assist-chips:empty{display:none} +/* SP7: a pane's tools (Full view, Messages, close) stay together on the title's row; the chips take the row under it. */ +html[data-organizations] .assist-pane-tools{display:inline-flex;align-items:center;gap:2px;flex:none} html[data-organizations] .assist-chips .ws-chip{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} html[data-organizations] .assist .pane-tool{display:inline-grid;place-items:center;width:28px;height:28px;border-radius:var(--r);color:var(--muted);border:0;background:none;padding:0;min-height:0;cursor:pointer;flex:none} html[data-organizations] .assist .pane-tool:hover{background:var(--raised);color:var(--text)} diff --git a/packages/webui/src/public/assistant.js b/packages/webui/src/public/assistant.js index f361f3cfb..58a5eb690 100644 --- a/packages/webui/src/public/assistant.js +++ b/packages/webui/src/public/assistant.js @@ -132,9 +132,11 @@

Reading…

- Full view - Messages - + + Full view + Messages + +
diff --git a/packages/webui/tests/assistant-threads-browser.test.mjs b/packages/webui/tests/assistant-threads-browser.test.mjs index b2de14575..79f2ffe39 100644 --- a/packages/webui/tests/assistant-threads-browser.test.mjs +++ b/packages/webui/tests/assistant-threads-browser.test.mjs @@ -374,3 +374,22 @@ test('SP7: a link marked as the full view stays in the organization\'s own view, await b.evaluate(`(() => { const a = document.createElement('a'); a.href = '#/orgs/alpha/projects/threads/${T.a1}'; a.setAttribute('data-full-view', ''); a.textContent = 'thread'; document.body.append(a); a.click(); a.remove(); })()`); await wait(`location.hash === '#/orgs/alpha/projects/threads/${T.a1}' && !document.querySelector('[data-assistant]')`); }); + +// SP7 review shots: the title and the pane's tools (Full view, Messages, close) share the header's +// first row, the organization and project chips sit under it, and nothing spills out of the pane. +const headerRows = `[...document.querySelectorAll('[data-assist-pane]')].map(p => { + const h = p.querySelector('.assist-pane-h').getBoundingClientRect(); + const r = s => p.querySelector(s).getBoundingClientRect(); + const mid = q => Math.round(q.top + q.height / 2); + const row = ['[data-assist-title]', '[data-assist-pane-full]', '[data-assist-pane-messages]', '[data-assist-close]'].map(s => mid(r(s))); + const inside = [...p.querySelectorAll('.assist-pane-h > *, .assist-pane-h a, .assist-pane-h button')].every(e => { const q = e.getBoundingClientRect(); return q.left >= h.left - 1 && q.right <= h.right + 1; }); + return { oneRow: Math.max(...row) - Math.min(...row) <= 4, chipsBelow: r('[data-assist-chips]').top >= r('[data-assist-title]').bottom - 1, inside }; +})`; +for (const [width, height, keys] of [[1440, 900, [`alpha:${T.a1}`, `alpha:${T.a2}`, `beta:${T.b1}`]], [390, 844, [`beta:${T.b1}`]]]) { + test(`SP7: a pane header keeps its title and tools on one row with the chips below, at ${width}`, async t => { + const { b, wait } = await open(t, { width, height, hash: `#/assistant?open=${keys.join(',')}` }); + await wait(keys.map(k => ready(k)).join(' && ')); + await wait(`[...document.querySelectorAll('[data-assist-pane] [data-ws-orgchip]')].length === ${keys.length}`); + assert.deepEqual(await b.evaluate(headerRows), keys.map(() => ({ oneRow: true, chipsBelow: true, inside: true }))); + }); +}