Enhance LLM import preview with improved question display and missing M2M handling

This commit is contained in:
Ross
2025-10-20 11:14:44 +01:00
parent 9be48140a4
commit 80171da78d
2 changed files with 81 additions and 32 deletions
+3 -3
View File
@@ -20,9 +20,9 @@ Please adhere to the following guidelines when creating each question:
7. Relevance: Ensure that the question is relevant to current radiological practices and guidelines. 7. Relevance: Ensure that the question is relevant to current radiological practices and guidelines.
8. Questions should feature metadata tags for finding, structure, condition, presentation, and subspecialty. 8. Questions should feature metadata tags for finding, structure, condition, presentation, and subspecialty.
9. Each question output should be a json object with the following schema: 9. Each question output should be a json object with the following schema:
10. For article sources pleese reference the article doi within the explanation field in the format [doi:10.xxxx/xxxxx]. 10. For article sources pleese reference the article doi within the explanation field in the format [doi:10.xxxx/xxxxx], if you do not know the doi please use the article name.
11. For statdx sources please reference the article in the format [statdx:article_id]. 11. For statdx sources please reference the article name in the format [statdx:article_id].
12. References should be included inline within the explanation field. 12. References should be included inline within the feedback fields.
13. Questions need to have a radiology focus, please avoid questions that are purely clinical or biochemical without imaging relevance. 13. Questions need to have a radiology focus, please avoid questions that are purely clinical or biochemical without imaging relevance.
JSON Schema (draft-07 compatible) JSON Schema (draft-07 compatible)
@@ -1,7 +1,10 @@
<form id="llm-import-confirm-form" method="post" hx-post="{% url 'sbas:import_llm_confirm' %}" hx-target="#import-result" hx-swap="innerHTML">
{% csrf_token %}
<input type="hidden" name="session_key" value="{{ session_key }}">
{% for item in items %} {% for item in items %}
<div class="card mb-2"> <div class="card mb-2">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">Question {{ item.index|add:1 }}</h5> <h5 class="card-title">Question {{ item.index }}</h5>
{% if item.payload %} {% if item.payload %}
<p><strong>Stem:</strong> {{ item.payload.stem|default:''|safe }}</p> <p><strong>Stem:</strong> {{ item.payload.stem|default:''|safe }}</p>
<p><strong>Answers:</strong> <p><strong>Answers:</strong>
@@ -18,7 +21,12 @@
{% if item.missing_m2m %} {% if item.missing_m2m %}
<ul> <ul>
{% for m in item.missing_m2m %} {% for m in item.missing_m2m %}
<li>{{ m.model }}: {{ m.values|join:", " }}</li> <li>
{{ m.model }}:
{% for val in m.values %}
<button type="button" class="btn btn-sm btn-outline-danger ms-1 toggle-exclude" data-idx="{{ item.index }}" data-model="{{ m.model }}" data-value="{{ val }}">{{ val }}</button>
{% endfor %}
</li>
{% endfor %} {% endfor %}
</ul> </ul>
{% else %} {% else %}
@@ -28,10 +36,51 @@
<div> <div>
<label><input type="checkbox" name="selected" value="{{ item.index }}" checked> Include</label> <label><input type="checkbox" name="selected" value="{{ item.index }}" checked> Include</label>
</div> </div>
<!-- container for hidden exclude inputs for this item -->
<div id="exclude-container-{{ item.index }}"></div>
</div> </div>
</div> </div>
{% endfor %} {% endfor %}
<div class="d-flex gap-2">
<label class="me-2"><input type="checkbox" name="allow_create_m2m" {% if allow_create_m2m %}checked{% endif %}> Create missing M2M</label>
<button class="btn btn-success" type="submit">Import selected</button>
<button class="btn btn-secondary" type="button" hx-get="{% url 'sbas:import_llm_questions' %}" hx-target="#import-preview">Cancel</button>
</div>
<div id="import-result" class="mt-3"></div>
</form>
<script>
// Toggle exclude: clicking a missing M2M button will add/remove a hidden input
document.querySelectorAll('.toggle-exclude').forEach(function(btn){
btn.addEventListener('click', function(){
const idx = btn.dataset.idx;
const model = btn.dataset.model;
const value = btn.dataset.value;
const container = document.getElementById('exclude-container-' + idx);
const inputName = 'exclude_' + idx;
// check if an input for this value already exists
const existing = container.querySelector('input[data-model="' + model + '"][data-value="' + value + '"]');
if(existing){
// remove input and toggle style
existing.remove();
btn.classList.remove('btn-danger');
btn.classList.add('btn-outline-danger');
} else {
const inp = document.createElement('input');
inp.type = 'hidden';
inp.name = inputName;
inp.value = model + ':::' + value;
inp.setAttribute('data-model', model);
inp.setAttribute('data-value', value);
container.appendChild(inp);
btn.classList.remove('btn-outline-danger');
btn.classList.add('btn-danger');
}
});
});
</script>
<div class="d-flex gap-2"> <div class="d-flex gap-2">
<button class="btn btn-success" hx-post="{% url 'sbas:import_llm_confirm' %}" hx-target="#import-result" hx-include="closest form">Import selected</button> <button class="btn btn-success" hx-post="{% url 'sbas:import_llm_confirm' %}" hx-target="#import-result" hx-include="closest form">Import selected</button>
<button class="btn btn-secondary" hx-get="{% url 'sbas:import_llm_questions' %}" hx-target="#import-result">Cancel</button> <button class="btn btn-secondary" hx-get="{% url 'sbas:import_llm_questions' %}" hx-target="#import-result">Cancel</button>