Enhance LLM import preview with detailed M2M field handling and improved exclusion toggle functionality
This commit is contained in:
@@ -34,22 +34,100 @@
|
||||
</p>
|
||||
<p><strong>Feedback:</strong> {{ item.payload.feedback|default:''|safe }}</p>
|
||||
{% endif %}
|
||||
<p><strong>Missing M2M:</strong>
|
||||
{% if item.missing_m2m %}
|
||||
<ul>
|
||||
{% for m in item.missing_m2m %}
|
||||
<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>
|
||||
<p><strong>M2M fields (click to exclude)</strong></p>
|
||||
<p class="small text-muted">Green = will be created/attached. Click a value to exclude it (grey).</p>
|
||||
<div class="mb-2">
|
||||
<!-- Finding -->
|
||||
<div class="m2m-group" data-model="Finding"><strong>Finding:</strong>
|
||||
{% if item.resolved_m2m.finding %}
|
||||
{% for val in item.resolved_m2m.finding %}
|
||||
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Finding" data-value="{{ val }}">{{ val }}</button>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
None
|
||||
{% endif %}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if item.missing_map.Finding %}
|
||||
{% for val in item.missing_map.Finding %}
|
||||
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Finding" data-value="{{ val }}">{{ val }}</button>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<span class="text-muted m2m-none" style="display:none">(none)</span>
|
||||
{% if item.missing_map.Finding %}
|
||||
<div class="small text-info">Would create: {{ item.missing_map.Finding|join:", " }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Structure -->
|
||||
<div class="m2m-group" data-model="Structure"><strong>Structure:</strong>
|
||||
{% if item.resolved_m2m.structure %}
|
||||
{% for val in item.resolved_m2m.structure %}
|
||||
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Structure" data-value="{{ val }}">{{ val }}</button>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if item.missing_map.Structure %}
|
||||
{% for val in item.missing_map.Structure %}
|
||||
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Structure" data-value="{{ val }}">{{ val }}</button>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<span class="text-muted m2m-none" style="display:none">(none)</span>
|
||||
{% if item.missing_map.Structure %}
|
||||
<div class="small text-info">Would create: {{ item.missing_map.Structure|join:", " }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Condition -->
|
||||
<div class="m2m-group" data-model="Condition"><strong>Condition:</strong>
|
||||
{% if item.resolved_m2m.condition %}
|
||||
{% for val in item.resolved_m2m.condition %}
|
||||
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Condition" data-value="{{ val }}">{{ val }}</button>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if item.missing_map.Condition %}
|
||||
{% for val in item.missing_map.Condition %}
|
||||
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Condition" data-value="{{ val }}">{{ val }}</button>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<span class="text-muted m2m-none" style="display:none">(none)</span>
|
||||
{% if item.missing_map.Condition %}
|
||||
<div class="small text-info">Would create: {{ item.missing_map.Condition|join:", " }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Presentation -->
|
||||
<div class="m2m-group" data-model="Presentation"><strong>Presentation:</strong>
|
||||
{% if item.resolved_m2m.presentation %}
|
||||
{% for val in item.resolved_m2m.presentation %}
|
||||
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Presentation" data-value="{{ val }}">{{ val }}</button>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if item.missing_map.Presentation %}
|
||||
{% for val in item.missing_map.Presentation %}
|
||||
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Presentation" data-value="{{ val }}">{{ val }}</button>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<span class="text-muted m2m-none" style="display:none">(none)</span>
|
||||
{% if item.missing_map.Presentation %}
|
||||
<div class="small text-info">Would create: {{ item.missing_map.Presentation|join:", " }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Subspecialty -->
|
||||
<div class="m2m-group" data-model="Subspecialty"><strong>Subspecialty:</strong>
|
||||
{% if item.resolved_m2m.subspecialty %}
|
||||
{% for val in item.resolved_m2m.subspecialty %}
|
||||
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Subspecialty" data-value="{{ val }}">{{ val }}</button>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if item.missing_map.Subspecialty %}
|
||||
{% for val in item.missing_map.Subspecialty %}
|
||||
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Subspecialty" data-value="{{ val }}">{{ val }}</button>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<span class="text-muted m2m-none" style="display:none">(none)</span>
|
||||
{% if item.missing_map.Subspecialty %}
|
||||
<div class="small text-info">Would create: {{ item.missing_map.Subspecialty|join:", " }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label><input type="checkbox" name="selected" value="{{ item.index }}" checked> Include</label>
|
||||
</div>
|
||||
@@ -68,8 +146,8 @@
|
||||
</form>
|
||||
|
||||
<script>
|
||||
// Toggle exclude: clicking a missing M2M button will add/remove a hidden input
|
||||
document.querySelectorAll('.toggle-exclude').forEach(function(btn){
|
||||
// Toggle exclude: clicking a M2M button will add/remove a hidden input and update styles
|
||||
function setupToggle(btn){
|
||||
btn.addEventListener('click', function(){
|
||||
const idx = btn.dataset.idx;
|
||||
const model = btn.dataset.model;
|
||||
@@ -77,12 +155,14 @@
|
||||
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 + '"]');
|
||||
const selector = 'input[data-model="' + model + '"][data-value="' + value + '"]';
|
||||
const existing = container ? container.querySelector(selector) : null;
|
||||
if(existing){
|
||||
// remove input and toggle style
|
||||
// remove input and toggle style to outline
|
||||
existing.remove();
|
||||
btn.classList.remove('btn-danger');
|
||||
btn.classList.add('btn-outline-danger');
|
||||
btn.classList.remove('btn-outline-secondary');
|
||||
btn.classList.remove('btn-secondary');
|
||||
btn.classList.add('btn-success');
|
||||
} else {
|
||||
const inp = document.createElement('input');
|
||||
inp.type = 'hidden';
|
||||
@@ -91,11 +171,36 @@
|
||||
inp.setAttribute('data-model', model);
|
||||
inp.setAttribute('data-value', value);
|
||||
container.appendChild(inp);
|
||||
btn.classList.remove('btn-outline-danger');
|
||||
btn.classList.add('btn-danger');
|
||||
// set button to excluded appearance
|
||||
btn.classList.remove('btn-success');
|
||||
btn.classList.add('btn-outline-secondary');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
document.querySelectorAll('.m2m-toggle').forEach(setupToggle);
|
||||
// keep backward compatibility with older toggle-exclude class
|
||||
document.querySelectorAll('.toggle-exclude').forEach(setupToggle);
|
||||
|
||||
// Show '(none)' for empty groups
|
||||
function refreshEmptyPlaceholders(){
|
||||
document.querySelectorAll('.m2m-group').forEach(function(group){
|
||||
const buttons = group.querySelectorAll('.m2m-toggle');
|
||||
const none = group.querySelector('.m2m-none');
|
||||
if(!none) return;
|
||||
if(buttons.length === 0){
|
||||
none.style.display = '';
|
||||
} else {
|
||||
none.style.display = 'none';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// run on load
|
||||
refreshEmptyPlaceholders();
|
||||
|
||||
// when toggling, buttons are not removed from DOM, so no need to re-run on click;
|
||||
// however if you later add server-side mutation that rewrites the fragment, call refreshEmptyPlaceholders after update.
|
||||
</script>
|
||||
|
||||
<!-- Bottom controls removed: submit and cancel are inside the form above -->
|
||||
|
||||
Reference in New Issue
Block a user