Refactor modal handling for display sets and findings; extract modals into partials for improved maintainability

This commit is contained in:
Ross
2026-03-23 16:13:56 +00:00
parent 90e22435a5
commit de5b6c36f3
4 changed files with 92 additions and 65 deletions
+26 -1
View File
@@ -331,7 +331,32 @@
var popup = document.createElement('div'); popup.id = 'markup-popup'; popup.className = 'markup-popup';
popup.innerHTML = '<div style="font-weight:600;margin-bottom:.25rem;">'+ (label||type+':'+pk) +'</div>';
var openBtn = document.createElement('button'); openBtn.type='button'; openBtn.className='btn btn-sm btn-outline-primary me-2'; openBtn.textContent='Open';
openBtn.addEventListener('click', function(){ var url = getDetailUrl(type, pk); if(url) showModalForUrl(url, label); popup.remove(); });
openBtn.addEventListener('click', function(){
var url = getDetailUrl(type, pk);
try{
// Prefer page-specific modal loaders if present so we reuse existing Bootstrap modals/viewers
if(type === 'displayset'){
if(typeof window.loadDisplaysetModal === 'function'){
window.loadDisplaysetModal(url, pk);
popup.remove();
return;
}
var dsBtn = document.querySelector('.view-displayset-modal[data-ds-id="'+pk+'"]');
if(dsBtn){ dsBtn.click(); popup.remove(); return; }
}
if(type === 'seriesfinding' || type === 'finding'){
if(typeof window.loadFindingModal === 'function'){
window.loadFindingModal(pk, url);
popup.remove();
return;
}
var fBtn = document.querySelector('.view-finding-modal[data-finding-id="'+pk+'"]');
if(fBtn){ fBtn.click(); popup.remove(); return; }
}
}catch(e){ console.warn('error invoking page modal loader', e); }
if(url) showModalForUrl(url, label);
popup.remove();
});
var closeBtn = document.createElement('button'); closeBtn.type='button'; closeBtn.className='btn btn-sm btn-outline-secondary'; closeBtn.textContent='Close'; closeBtn.addEventListener('click', function(){ popup.remove(); });
popup.appendChild(openBtn); popup.appendChild(closeBtn);
document.body.appendChild(popup);
+2 -64
View File
@@ -868,53 +868,7 @@
{% include 'question_notes.html' %}
</div>
<div class="modal fade" id="displaysetModal" tabindex="-1" aria-labelledby="displaysetModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="displaysetModalLabel">Display Set Details</h5>
<button type="button" class="btn btn-sm btn-outline-primary ms-2 displayset-fullscreen-btn" title="Open fullscreen"></button>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" id="displaysetModalBody">
<p>Loading...</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- Fullscreen displayset modal: viewer left, details right -->
<div class="modal fade" id="displaysetFullscreenModal" tabindex="-1" aria-labelledby="displaysetFullscreenModalLabel" aria-hidden="true">
<div class="modal-dialog modal-fullscreen">
<div class="modal-content" style="height:100vh;">
<div class="modal-header">
<h5 class="modal-title" id="displaysetFullscreenModalLabel">Display Set — Fullscreen</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body p-0" id="displaysetFullscreenBody">
<div class="container-fluid h-100">
<div class="row g-0 h-100">
<div class="col-8" id="displaysetFullscreenLeft" style="height:100%; overflow:auto; background:#000; display:flex;">
</div>
<div class="col-4" id="displaysetFullscreenRight" style="height:100%; overflow:auto; padding:1rem;"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<style>
/* Ensure fullscreen modal and viewer stretch vertically */
#displaysetFullscreenModal .modal-content { height: 100vh; }
#displaysetFullscreenModal .modal-body { height: calc(100vh - 56px); padding: 0; }
#displaysetFullscreenModal .container-fluid, #displaysetFullscreenModal .row { height: 100%; }
#displaysetFullscreenLeft { display:flex; align-items:stretch; }
#displaysetFullscreenLeft .dicom-viewer-root { height:100% !important; min-height:100% !important; width:100% !important; flex:1 1 auto; }
</style>
{% include 'atlas/partials/_displayset_modals.html' %}
<p><b>Checked by:</b> {% for verified in case.verified.all %} <a
href="{% url 'atlas:verified_detail' pk=verified.pk %}">{{verified}}</a>, {% endfor %}</p>
@@ -925,23 +879,7 @@
<p><b>Case size:</b> {{ case.get_total_series_images_size | filesizeformat }}</p>
<div class="modal fade" id="findingModal" tabindex="-1" aria-labelledby="findingModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="findingModalLabel">Finding Details</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" id="findingModalBody">
<!-- Finding details will be loaded here dynamically -->
<p>Loading...</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
{% include 'atlas/partials/_finding_modal.html' %}
<!-- Reorder Series Modal -->
<div class="modal fade" id="reorderSeriesModal" tabindex="-1" aria-labelledby="reorderSeriesModalLabel" aria-hidden="true">
<div class="modal-dialog">
@@ -0,0 +1,47 @@
<div class="modal fade" id="displaysetModal" tabindex="-1" aria-labelledby="displaysetModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="displaysetModalLabel">Display Set Details</h5>
<button type="button" class="btn btn-sm btn-outline-primary ms-2 displayset-fullscreen-btn" title="Open fullscreen"></button>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" id="displaysetModalBody">
<p>Loading...</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- Fullscreen displayset modal: viewer left, details right -->
<div class="modal fade" id="displaysetFullscreenModal" tabindex="-1" aria-labelledby="displaysetFullscreenModalLabel" aria-hidden="true">
<div class="modal-dialog modal-fullscreen">
<div class="modal-content" style="height:100vh;">
<div class="modal-header">
<h5 class="modal-title" id="displaysetFullscreenModalLabel">Display Set — Fullscreen</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body p-0" id="displaysetFullscreenBody">
<div class="container-fluid h-100">
<div class="row g-0 h-100">
<div class="col-8" id="displaysetFullscreenLeft" style="height:100%; overflow:auto; background:#000; display:flex;">
</div>
<div class="col-4" id="displaysetFullscreenRight" style="height:100%; overflow:auto; padding:1rem;"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<style>
/* Ensure fullscreen modal and viewer stretch vertically */
#displaysetFullscreenModal .modal-content { height: 100vh; }
#displaysetFullscreenModal .modal-body { height: calc(100vh - 56px); padding: 0; }
#displaysetFullscreenModal .modal-content .container-fluid, #displaysetFullscreenModal .modal-content .row { height: 100%; }
#displaysetFullscreenLeft { display:flex; align-items:stretch; }
#displaysetFullscreenLeft .dicom-viewer-root { height:100% !important; min-height:100% !important; width:100% !important; flex:1 1 auto; }
</style>
@@ -0,0 +1,17 @@
<div class="modal fade" id="findingModal" tabindex="-1" aria-labelledby="findingModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="findingModalLabel">Finding Details</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" id="findingModalBody">
<!-- Finding details will be loaded here dynamically -->
<p>Loading...</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>