Add select/deselect all buttons for series in user uploads view and enhance styles for better visibility

This commit is contained in:
Ross
2026-03-02 10:36:21 +00:00
parent 0c6d33e26a
commit ed6418efad
+104 -44
View File
@@ -21,6 +21,10 @@
<summary>
<strong>{{ study.description|default:"(no description)" }}</strong>
<small class="text-muted"> ({{ study_uid }}) — {{ study.series|length }} series</small>
<span class="ms-2">
<button type="button" class="btn btn-sm btn-outline-secondary select-all-btn" title="Select all in study">Select all</button>
<button type="button" class="btn btn-sm btn-outline-secondary deselect-all-btn" title="Deselect all in study">Deselect all</button>
</span>
</summary>
<ul class="study-series-list">
{% for series, n, tags, date in study.series %}
@@ -98,7 +102,7 @@
<button id="import-dicoms-sequential-button"
type="button"
class="btn btn-primary"
>Import {% if case %}into case{% endif %} (one at a time)</button>
>Import {% if case %}into case{% endif %}</button>
<div id="import-status"></div>
@@ -184,19 +188,62 @@
}
</script>
<script>
// Select / Deselect all series within a study block
document.addEventListener('click', function (e) {
const target = e.target;
if (target.matches('.select-all-btn')) {
const detail = target.closest('.study-block');
if (!detail) return;
const inputs = detail.querySelectorAll('input[name="selection"]');
inputs.forEach(cb => {
if (!cb.disabled) {
cb.checked = true;
const li = cb.closest('li');
if (li) li.classList.add('selected');
}
});
}
if (target.matches('.deselect-all-btn')) {
const detail = target.closest('.study-block');
if (!detail) return;
const inputs = detail.querySelectorAll('input[name="selection"]');
inputs.forEach(cb => {
if (!cb.disabled) {
cb.checked = false;
const li = cb.closest('li');
if (li) li.classList.remove('selected');
}
});
}
});
</script>
{% endblock %}
{% block css %}
<style>
.indicator {
display: none;
/* Dark theme friendly styles for uploads page */
:root {
--bg: #0f1115;
--panel: #111217;
--muted: #9aa0a6;
--border: #242629;
--accent: #7c3aed;
--success: #16a34a;
--danger: #dc2626;
--card: #0f1216;
}
.indicator.htmx-request {
display: block;
body {
background: var(--bg);
color: #e6eef6;
}
.indicator { display: none; }
.indicator.htmx-request { display: block; }
.loader {
width: 50px;
aspect-ratio: 1;
@@ -204,61 +251,74 @@
}
.loader::before,
.loader::after {
content:"";
content: "";
grid-area: 1/1;
--c:no-repeat radial-gradient(farthest-side,#25b09b 92%,#0000);
--c: no-repeat radial-gradient(farthest-side, var(--accent) 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;
opacity: 0.95;
}
.loader::before {
margin: 4px;
filter: hue-rotate(45deg);
background-size: 8px 8px;
animation-timing-function: linear
}
.loader::before { margin: 4px; filter: hue-rotate(45deg); background-size: 8px 8px; }
@keyframes l12 { 100% { transform: rotate(.5turn) } }
@keyframes l12 {
100%{transform: rotate(.5turn)}
}
#series-list {
user-select: none;
cursor: pointer;
}
#series-list { user-select: none; }
.study-block {
margin: 8px 0;
padding: 6px;
border: 1px solid #e9ecef;
border-radius: 6px;
background: #fafafa;
padding: 8px;
border: 1px solid var(--border);
border-radius: 8px;
background: linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01));
box-shadow: 0 1px 0 rgba(255,255,255,0.02) inset;
}
.study-block summary {
font-size: 1rem;
cursor: pointer;
list-style: none;
padding: 4px 6px;
}
.study-block summary { font-size: 1rem; cursor: pointer; padding: 4px 6px; color: #e6eef6; }
.study-series-list {
list-style: none;
margin: 8px 0 0 0;
padding: 0;
}
.study-series-list { list-style: none; margin: 8px 0 0 0; padding: 0; }
.study-series-list li {
padding: 6px;
border-bottom: 1px solid #eee;
padding: 10px;
border-bottom: 1px solid rgba(255,255,255,0.03);
background: transparent;
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
}
.series-meta { font-weight: 600; }
.series-tags { font-size: 0.9rem; color: #666; }
.study-series-list li:last-child { border-bottom: 0; }
.series-meta { font-weight: 600; color: #f1f5f9; }
.series-tags { font-size: 0.9rem; color: var(--muted); margin-top: 4px; }
.series-block-popup-link a { color: var(--muted); text-decoration: underline; }
/* Selected state */
#series-list .selected {
color: #fff;
background: linear-gradient(90deg, rgba(124,58,237,0.12), rgba(124,58,237,0.08));
border: 1px solid rgba(124,58,237,0.25);
border-radius: 6px;
padding: 6px;
}
/* Imported badge */
.badge.bg-success { background-color: var(--success); color: #000; }
/* Placeholder for tags */
.series-tags-placeholder { color: var(--muted); padding: 6px 0; }
/* Buttons */
button { background: transparent; color: #e6eef6; border: 1px solid var(--border); }
button.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
/* small helpers */
.text-muted { color: var(--muted) !important; }
#series-list li {
}