Add fullscreen display set modal and button for enhanced viewing experience

This commit is contained in:
Ross
2026-03-23 10:24:07 +00:00
parent 64d4958744
commit 8733f59882
@@ -873,6 +873,7 @@
<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">
@@ -885,6 +886,36 @@
</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>
<p><b>Checked by:</b> {% for verified in case.verified.all %} <a
href="{% url 'atlas:verified_detail' pk=verified.pk %}">{{verified}}</a>, {% endfor %}</p>
@@ -1167,6 +1198,7 @@
// Display Set modal handler
const dsModal = new bootstrap.Modal(document.getElementById("displaysetModal"));
const dsModalBody = document.getElementById("displaysetModalBody");
const dsFullscreenModal = new bootstrap.Modal(document.getElementById("displaysetFullscreenModal"));
document.querySelectorAll(".view-displayset-modal").forEach(button => {
button.addEventListener("click", function () {
@@ -1176,6 +1208,11 @@
.then(response => response.text())
.then(html => {
dsModalBody.innerHTML = html;
// attach url to fullscreen button so it knows what to load
try {
const fsBtn = document.querySelector('.displayset-fullscreen-btn');
if (fsBtn) fsBtn.dataset.url = url;
} catch (e) { console.warn(e); }
setTimeout(function () {
try { window.mountDicomViewers(); } catch (e) { console.warn('mountDicomViewers not available', e); }
}, 500);
@@ -1188,6 +1225,59 @@
});
});
// Fullscreen button handler: fetch the same displayset content but lay out viewer left, details right
document.querySelectorAll('.displayset-fullscreen-btn').forEach(btn => {
btn.addEventListener('click', function () {
const url = btn.dataset.url;
if (!url) return;
// show loading state
document.getElementById('displaysetFullscreenLeft').innerHTML = '<p style="color:#fff; padding:1rem;">Loading viewer...</p>';
document.getElementById('displaysetFullscreenRight').innerHTML = '<p>Loading details...</p>';
fetch(url)
.then(response => response.text())
.then(html => {
const tmp = document.createElement('div');
tmp.innerHTML = html;
// find viewer element
const viewer = tmp.querySelector('.dicom-viewer-root');
if (viewer) {
// move viewer into left pane
const left = document.getElementById('displaysetFullscreenLeft');
left.innerHTML = '';
left.appendChild(viewer);
// force the viewer to fill the available space
try {
viewer.style.height = '100%';
viewer.style.minHeight = '100%';
viewer.style.width = '100%';
viewer.style.display = 'block';
viewer.style.flex = '1 1 auto';
} catch (e) { console.warn('failed to resize viewer element', e); }
} else {
document.getElementById('displaysetFullscreenLeft').innerHTML = '<p style="color:#fff; padding:1rem;">No viewer available</p>';
}
// remaining content (without viewer) goes to right pane
// remove viewer from tmp to avoid duplication
const viewerInTmp = tmp.querySelector('.dicom-viewer-root');
if (viewerInTmp) viewerInTmp.remove();
document.getElementById('displaysetFullscreenRight').innerHTML = tmp.innerHTML;
dsFullscreenModal.show();
// allow viewer to initialize
setTimeout(function () {
try { window.mountDicomViewers(); } catch (e) { console.warn('mountDicomViewers not available for fullscreen', e); }
}, 500);
})
.catch(error => {
console.error('Error loading fullscreen display set:', error);
document.getElementById('displaysetFullscreenLeft').innerHTML = '<p style="color:#fff; padding:1rem;">Failed to load viewer</p>';
document.getElementById('displaysetFullscreenRight').innerHTML = '<p>Failed to load details.</p>';
});
});
});
});