Enhance user uploads view by grouping series by StudyInstanceUID and adding a partial template for displaying common DICOM tags

This commit is contained in:
Ross
2026-03-02 10:31:04 +00:00
parent b43d441da1
commit 0c6d33e26a
5 changed files with 168 additions and 24 deletions
@@ -0,0 +1,17 @@
<div class="series-tags-fragment">
<h6>Series DICOM tags (common across series)</h6>
{% if common_tags %}
<table class="table table-sm">
<tbody>
{% for k, v in common_tags.items %}
<tr>
<th style="width:35%">{{ k }}</th>
<td>{{ v }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<div class="text-muted">No consistent tags found across images in this series.</div>
{% endif %}
</div>
+78 -23
View File
@@ -14,25 +14,51 @@
{% if series_list %}
<ul id="series-list">
{% for series, n, tags, date in series_list %}
<li>
<span _="
on click toggle .selected on me.closest('li')
then set i to the first <input/> in me
then set i.checked to not i.checked" >
Uploaded: {{date}}<br/>
Series: {{series}} [{{n}} images] <br/>
{{tags}}
<input class="hidden" type="checkbox" name="selection" value="{{ series }}">
</span>
<span class="series-block-popup-link">
<a href="#"
onclick="return window.create_popup_window('/atlas/uploads/series_id/{{series}}', 'Series')">Popup</a>
</span>
</li>
{% endfor %}
</ul>
<div id="series-list">
{% if grouped_series %}
{% for study_uid, study in grouped_series %}
<details class="study-block" open>
<summary>
<strong>{{ study.description|default:"(no description)" }}</strong>
<small class="text-muted"> ({{ study_uid }}) — {{ study.series|length }} series</small>
</summary>
<ul class="study-series-list">
{% for series, n, tags, date in study.series %}
<li>
<span _="on click toggle .selected on me.closest('li') then set i to the first <input/> in me then set i.checked to not i.checked">
<div class="series-meta">Uploaded: {{ date }} — Series: {{ series }} [{{ n }} images]</div>
<div class="series-tags">{{ tags }}</div>
<input class="hidden" type="checkbox" name="selection" value="{{ series }}">
</span>
<span class="series-block-popup-link">
<a href="#" onclick="return window.create_popup_window('/atlas/uploads/series_id/{{series}}', 'Series')">Popup</a>
&nbsp;|&nbsp;
<a hx-get="{% url 'atlas:series_tags_partial' series %}" hx-target="[id='series-tags-{{ series }}']" hx-swap="innerHTML">View tags</a>
</span>
<div id="series-tags-{{ series }}" class="series-tags-placeholder mt-2"></div>
</li>
{% endfor %}
</ul>
</details>
{% endfor %}
{% else %}
<ul>
{% for series, n, tags, date in series_list %}
<li>
<span _="on click toggle .selected on me.closest('li') then set i to the first <input/> in me then set i.checked to not i.checked">
Uploaded: {{date}}<br/>
Series: {{series}} [{{n}} images] <br/>
{{tags}}
<input class="hidden" type="checkbox" name="selection" value="{{ series }}">
</span>
<span class="series-block-popup-link">
<a href="#" onclick="return window.create_popup_window('/atlas/uploads/series_id/{{series}}', 'Series')">Popup</a>
</span>
</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% if case %}
<p>Importing into case: <a href='{% url "atlas:case_detail" case.pk %}'>{{case}}</a></p>
@@ -182,10 +208,10 @@
grid-area: 1/1;
--c:no-repeat radial-gradient(farthest-side,#25b09b 92%,#0000);
background:
var(--c) 50% 0,
var(--c) 50% 100%,
var(--c) 100% 50%,
var(--c) 0 50%;
var(--c) 50% 0,
var(--c) 50% 100%,
var(--c) 100% 50%,
var(--c) 0 50%;
background-size: 12px 12px;
animation: l12 1s infinite;
}
@@ -205,6 +231,35 @@
cursor: pointer;
}
.study-block {
margin: 8px 0;
padding: 6px;
border: 1px solid #e9ecef;
border-radius: 6px;
background: #fafafa;
}
.study-block summary {
font-size: 1rem;
cursor: pointer;
list-style: none;
padding: 4px 6px;
}
.study-series-list {
list-style: none;
margin: 8px 0 0 0;
padding: 0;
}
.study-series-list li {
padding: 6px;
border-bottom: 1px solid #eee;
}
.series-meta { font-weight: 600; }
.series-tags { font-size: 0.9rem; color: #666; }
#series-list li {
}
#series-list .selected {