From c237826ef620579786d5582675a6517c732cfa85 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 7 Sep 2026 21:10:23 +0200 Subject: [PATCH] feat: clinical handoff as the standard site modal, closes back to the chat --- public/components/assistant.html | 25 ++++++++++++++++++------- public/js/clinicalAssistant.js | 10 +++++++++- test/frontend-prompt-env.test.js | 6 +++++- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/public/components/assistant.html b/public/components/assistant.html index c27a596c..0efc3638 100644 --- a/public/components/assistant.html +++ b/public/components/assistant.html @@ -44,13 +44,7 @@

Loading conversation limit; history and draft are counted in UTF-16 code units. The server validates each request.

- + + + + diff --git a/public/js/clinicalAssistant.js b/public/js/clinicalAssistant.js index 0a485b06..babc3dd4 100644 --- a/public/js/clinicalAssistant.js +++ b/public/js/clinicalAssistant.js @@ -74,6 +74,13 @@ import { if (typeof showToast === 'function') showToast('Could not copy; select the summary text instead.', 'error'); }); }); + function closeHandoffModal() { setHandoff(''); } + var handoffModal = document.getElementById('assistant-handoff-modal'); + if (handoffModal) { + document.getElementById('btn-assistant-handoff-close').addEventListener('click', closeHandoffModal); + document.getElementById('btn-assistant-handoff-done').addEventListener('click', closeHandoffModal); + handoffModal.addEventListener('click', function(e) { if (e.target === handoffModal) closeHandoffModal(); }); + } if (input) input.addEventListener('input', updateConversationBudget); if (cancelBtn) cancelBtn.addEventListener('click', cancelAssistantSearch); if (copyBtn) copyBtn.addEventListener('click', copyLastAnswer); @@ -878,7 +885,8 @@ import { preview.innerHTML = text ? renderMarkdown(text, []) : ''; if (text) renderEmbeddedBlocks(preview); } - document.getElementById('assistant-handoff-panel').hidden = !text; + var modal = document.getElementById('assistant-handoff-modal'); + if (modal) modal.classList.toggle('hidden', !text); } function requestHandoff() { diff --git a/test/frontend-prompt-env.test.js b/test/frontend-prompt-env.test.js index 60ce5711..4a8cf262 100644 --- a/test/frontend-prompt-env.test.js +++ b/test/frontend-prompt-env.test.js @@ -273,7 +273,11 @@ test('handoff renders Markdown while preserving exact copy text and clearing on assert.equal(preview.querySelector('strong').textContent, 'Plan'); assert.equal(preview.querySelector('li').textContent, 'Follow up'); assert.equal(preview.querySelector('tbody td:last-child').textContent, '1.25 mg'); - assert.doesNotMatch(ui.document.getElementById('assistant-handoff-panel').textContent, /not.*verified clinical/i); + assert.doesNotMatch(ui.document.getElementById('assistant-handoff-modal').textContent, /not.*verified clinical/i); + assert.equal(ui.document.getElementById('assistant-handoff-modal').classList.contains('hidden'), false, 'modal visible'); + ui.document.getElementById('btn-assistant-handoff-done').click(); await tick(); + assert.equal(ui.document.getElementById('assistant-handoff-modal').classList.contains('hidden'), true, 'Close returns to the chat'); + assert.equal(ui.document.querySelectorAll('.assistant-msg').length, 1, 'chat state untouched'); await loadChat(ui); assert.equal(raw.value, ''); assert.equal(preview.textContent, '');