Add buttons for copying and downloading prompts in LLM view; enhance user interaction

This commit is contained in:
Ross
2025-11-01 08:27:19 +00:00
parent 0de7c345a2
commit b32d265c2c
+140 -1
View File
@@ -7,7 +7,16 @@
</p>
<h3>Question Generation Prompt</h3>
<pre>
<div class="d-flex align-items-center mb-2">
<div class="btn-group me-2" role="group" aria-label="Prompt actions">
<button type="button" class="btn btn-outline-secondary btn-sm" id="copy-llm-prompt">Copy prompt</button>
<button type="button" class="btn btn-outline-secondary btn-sm" id="download-llm-prompt">Download prompt</button>
<button class="btn btn-outline-primary btn-sm" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-llm-question-prompt" aria-expanded="false" aria-controls="collapse-llm-question-prompt">Show</button>
</div>
<small class="text-muted" id="llm-prompt-feedback" style="display:none;">Copied ✓</small>
</div>
<div class="collapse" id="collapse-llm-question-prompt">
<pre id="llm-question-prompt">
You are an expert radiologist tasked with generating high-quality multiple-choice questions for medical imaging education. Each question should consist of a clinical vignette, an image description, and five answer choices (A through E), with one correct answer and four plausible distractors.
Please adhere to the following guidelines when creating each question:
@@ -25,6 +34,7 @@ Please adhere to the following guidelines when creating each question:
12. References should be included inline within the feedback fields.
13. Sources can also be included in the sources field as a list.
14. Questions need to have a radiology focus, please avoid questions that are purely clinical or biochemical without imaging relevance.
15. Category names should match one of the following options exactly: 'Central Nervous and Head & Neck', 'Paediatric', 'Genito-urinary, Adrenal, Obstetrics & Gynaecology and Breast', 'Gastro-intestinal', 'Musculoskeletal and Trauma', 'Cardiothoracic and Vascular'
JSON Schema (draft-07 compatible)
{
@@ -138,5 +148,134 @@ JSON Schema (draft-07 compatible)
}
</pre>
</div>
<h3>Question generation text</h3>
<div class="d-flex align-items-center mb-2">
<div class="btn-group me-2" role="group" aria-label="Prompt actions">
<button type="button" class="btn btn-outline-secondary btn-sm" id="copy-llm-prompt-text">Copy prompt</button>
<button type="button" class="btn btn-outline-secondary btn-sm" id="download-llm-prompt-text">Download prompt</button>
<button class="btn btn-outline-primary btn-sm" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-llm-question-prompt-text" aria-expanded="false" aria-controls="collapse-llm-question-prompt-text">Show</button>
</div>
<small class="text-muted" id="llm-prompt-text-feedback" style="display:none;">Copied ✓</small>
</div>
<div class="collapse" id="collapse-llm-question-prompt-text">
<pre id="llm-question-prompt-text">
Paying particular attention to the content in the source "prompt" please generate 10 questions
</pre>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const copyBtn = document.getElementById('copy-llm-prompt');
const downloadBtn = document.getElementById('download-llm-prompt');
const pre = document.getElementById('llm-question-prompt');
const feedback = document.getElementById('llm-prompt-feedback');
function showFeedback(msg) {
if (!feedback) return;
feedback.textContent = msg;
feedback.style.display = 'inline';
setTimeout(() => feedback.style.display = 'none', 2000);
}
if (copyBtn && pre) {
copyBtn.addEventListener('click', function() {
const text = pre.textContent;
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(function() {
showFeedback('Copied ✓');
}).catch(function() {
// Fallback to older execCommand
const ta = document.createElement('textarea');
ta.value = text;
document.body.appendChild(ta);
ta.select();
try { document.execCommand('copy'); showFeedback('Copied ✓'); } catch (e) { showFeedback('Copy failed'); }
ta.remove();
});
} else {
const ta = document.createElement('textarea');
ta.value = text;
document.body.appendChild(ta);
ta.select();
try { document.execCommand('copy'); showFeedback('Copied ✓'); } catch (e) { showFeedback('Copy failed'); }
ta.remove();
}
});
}
if (downloadBtn && pre) {
downloadBtn.addEventListener('click', function() {
const text = pre.textContent;
const blob = new Blob([text], { type: 'text/plain;charset=utf-8' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'llm_prompt.txt';
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
showFeedback('Downloaded');
// Handlers for the second prompt (llm-question-prompt-text)
const copyBtnText = document.getElementById('copy-llm-prompt-text');
const downloadBtnText = document.getElementById('download-llm-prompt-text');
const preText = document.getElementById('llm-question-prompt-text');
const feedbackText = document.getElementById('llm-prompt-text-feedback');
function showTextFeedback(msg) {
if (!feedbackText) return;
feedbackText.textContent = msg;
feedbackText.style.display = 'inline';
setTimeout(() => feedbackText.style.display = 'none', 2000);
}
if (copyBtnText && preText) {
copyBtnText.addEventListener('click', function() {
const text = preText.textContent;
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(function() {
showTextFeedback('Copied ✓');
}).catch(function() {
const ta = document.createElement('textarea');
ta.value = text;
document.body.appendChild(ta);
ta.select();
try { document.execCommand('copy'); showTextFeedback('Copied ✓'); } catch (e) { showTextFeedback('Copy failed'); }
ta.remove();
});
} else {
const ta = document.createElement('textarea');
ta.value = text;
document.body.appendChild(ta);
ta.select();
try { document.execCommand('copy'); showTextFeedback('Copied ✓'); } catch (e) { showTextFeedback('Copy failed'); }
ta.remove();
}
});
}
if (downloadBtnText && preText) {
downloadBtnText.addEventListener('click', function() {
const text = preText.textContent;
const blob = new Blob([text], { type: 'text/plain;charset=utf-8' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'llm_prompt_text.txt';
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
showTextFeedback('Downloaded');
});
}
});
</script>
{% endblock %}