diff --git a/public/components/assistant.html b/public/components/assistant.html index cd43d42..3ccc7fc 100644 --- a/public/components/assistant.html +++ b/public/components/assistant.html @@ -19,6 +19,7 @@
diff --git a/public/js/clinicalAssistant.js b/public/js/clinicalAssistant.js index 03a712d..900375c 100644 --- a/public/js/clinicalAssistant.js +++ b/public/js/clinicalAssistant.js @@ -53,12 +53,14 @@ var form = document.getElementById('assistant-form'); var clearBtn = document.getElementById('btn-assistant-clear'); var copyBtn = document.getElementById('btn-assistant-copy'); + var exportBtn = document.getElementById('btn-assistant-export-pdf'); var imageBtn = document.getElementById('btn-assistant-image'); var input = document.getElementById('assistant-input'); if (form) form.addEventListener('submit', onAsk); if (clearBtn) clearBtn.addEventListener('click', clearConversation); if (copyBtn) copyBtn.addEventListener('click', copyLastAnswer); + if (exportBtn) exportBtn.addEventListener('click', exportAnswerPdf); if (imageBtn) imageBtn.addEventListener('click', generateImage); if (input) input.addEventListener('keydown', function (e) { if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') onAsk(e); @@ -110,7 +112,7 @@ if (input) input.value = ''; if (isImageRequest(text)) { - generateImage(text, true); + prepareSidebarImagePrompt(text); return; } @@ -378,6 +380,26 @@ }); } + function buildContextualImagePrompt(request) { + var prompt = String(request || '').trim(); + if (!lastAnswer) return prompt; + var sourceText = lastSources.slice(0, 6).map(function (s, idx) { + return '[' + (s.number || idx + 1) + '] ' + (s.title || s.resource || 'Source') + (s.page ? ', page ' + s.page : ''); + }).join('\n'); + return prompt + '\n\nUse this clinical answer as the required context. Do not switch topics or introduce unrelated scenes such as gardening. Create a medical teaching visual faithful to the answer.\n\nAnswer:\n' + lastAnswer.slice(0, 3000) + '\n\nSources:\n' + sourceText; + } + + function prepareSidebarImagePrompt(request) { + var promptEl = document.getElementById('assistant-image-prompt'); + var prompt = buildContextualImagePrompt(request); + if (promptEl) { + promptEl.value = prompt; + promptEl.focus(); + } + appendMessage('assistant', 'I prepared the image prompt in the **Image / Graph** box on the right. Click **Generate image** there so the visual uses the current answer as context instead of treating this as a separate chat request.'); + setBusy(false, 'Ready'); + } + function clearConversation() { messages = []; lastAnswer = ''; @@ -435,6 +457,45 @@ }); } + function exportAnswerPdf() { + if (!lastAnswer) { if (typeof showToast === 'function') showToast('No answer to export', 'error'); return; } + setBusy(true, 'Preparing PDF...'); + fetch('/api/clinical-assistant/export-summary', { + method: 'POST', headers: getAuthHeaders(), credentials: 'same-origin', + body: JSON.stringify({ answer: lastAnswer, sources: lastSources }) + }) + .then(function (r) { return r.json().then(function (data) { data._status = r.status; return data; }); }) + .then(function (data) { + setBusy(false, 'Ready'); + openPrintableExport(data.success && data.summary ? data.summary : lastAnswer, lastSources); + }) + .catch(function () { + setBusy(false, 'Ready'); + openPrintableExport(lastAnswer, lastSources); + }); + } + + function openPrintableExport(answer, sources) { + var doc = window.open('', '_blank', 'width=900,height=1100'); + if (!doc) { if (typeof showToast === 'function') showToast('Allow popups to export PDF', 'error'); return; } + var refs = (sources || []).map(function (s, idx) { + var n = s.number || idx + 1; + var title = s.title || s.resource || 'Untitled source'; + var page = s.page || s.page_number || s.pageNumber; + return '