Add modal for viewing series DICOM tags with HTMX integration and improved styling

This commit is contained in:
Ross
2026-03-02 11:14:28 +00:00
parent 6ff8706fa4
commit af2dcd95b2
+61 -1
View File
@@ -37,7 +37,11 @@
<span class="series-block-popup-link"> <span class="series-block-popup-link">
<a href="#" onclick="return window.create_popup_window('/atlas/uploads/series_id/{{series}}', 'Series')">Popup</a> <a href="#" onclick="return window.create_popup_window('/atlas/uploads/series_id/{{series}}', 'Series')">Popup</a>
&nbsp;|&nbsp; &nbsp;|&nbsp;
<a hx-get="{% url 'atlas:series_tags_partial' series %}" hx-target="[id='series-tags-{{ series }}']" hx-swap="innerHTML">View tags</a> <a
hx-get="{% url 'atlas:series_tags_partial' series %}"
hx-target="#seriesTagsModal .modal-body"
hx-swap="innerHTML"
>View tags</a>
</span> </span>
<div id="series-tags-{{ series }}" class="series-tags-placeholder mt-2"></div> <div id="series-tags-{{ series }}" class="series-tags-placeholder mt-2"></div>
</li> </li>
@@ -119,7 +123,45 @@
<p><a href="{% url 'atlas:series_view' %}?case=null&sort=-modified_date">View orphan series</a></p> <p><a href="{% url 'atlas:series_view' %}?case=null&sort=-modified_date">View orphan series</a></p>
<!-- Global modal used for HTMX-loaded fragments (e.g. series tags) -->
<div class="modal fade" id="seriesTagsModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Series DICOM Tags</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- HTMX will swap content here -->
<div class="text-muted">Loading…</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script> <script>
// Show modal when HTMX swaps content into the modal body
document.body.addEventListener('htmx:afterSwap', function (e) {
try {
var target = e.detail && e.detail.target ? e.detail.target : null;
if (!target) return;
// If the swapped target is (or is inside) the modal body, show modal
var modalBody = document.querySelector('#seriesTagsModal .modal-body');
if (modalBody && (modalBody === target || modalBody.contains(target))) {
var modalEl = document.getElementById('seriesTagsModal');
if (modalEl && window.bootstrap && bootstrap.Modal) {
bootstrap.Modal.getOrCreateInstance(modalEl).show();
}
}
} catch (err) {
console.error('Error showing seriesTagsModal after HTMX swap', err);
}
});
const importButton = document.getElementById('import-dicoms-sequential-button'); const importButton = document.getElementById('import-dicoms-sequential-button');
if (importButton) { if (importButton) {
document.getElementById('import-dicoms-sequential-button').addEventListener('click', async function() { document.getElementById('import-dicoms-sequential-button').addEventListener('click', async function() {
@@ -350,6 +392,24 @@
border-color: #e6ffe6; border-color: #e6ffe6;
opacity: 0.7; opacity: 0.7;
} }
/* Wider modal for long dicom tags and wrapping behaviour */
#seriesTagsModal .modal-dialog {
max-width: 95%;
width: 95%;
}
/* Make tag table layout fixed so long values wrap neatly */
#seriesTagsModal .series-tags-fragment table {
table-layout: fixed;
width: 100%;
}
#seriesTagsModal .series-tags-fragment th,
#seriesTagsModal .series-tags-fragment td {
white-space: normal !important;
word-break: break-word;
overflow-wrap: anywhere;
}
</style> </style>
{% endblock css %} {% endblock css %}