Add select/deselect all buttons for series in user uploads view and enhance styles for better visibility
This commit is contained in:
@@ -21,6 +21,10 @@
|
|||||||
<summary>
|
<summary>
|
||||||
<strong>{{ study.description|default:"(no description)" }}</strong>
|
<strong>{{ study.description|default:"(no description)" }}</strong>
|
||||||
<small class="text-muted"> ({{ study_uid }}) — {{ study.series|length }} series</small>
|
<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>
|
</summary>
|
||||||
<ul class="study-series-list">
|
<ul class="study-series-list">
|
||||||
{% for series, n, tags, date in study.series %}
|
{% for series, n, tags, date in study.series %}
|
||||||
@@ -98,7 +102,7 @@
|
|||||||
<button id="import-dicoms-sequential-button"
|
<button id="import-dicoms-sequential-button"
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-primary"
|
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>
|
<div id="import-status"></div>
|
||||||
|
|
||||||
@@ -184,19 +188,62 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</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 %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
<style>
|
<style>
|
||||||
.indicator {
|
/* Dark theme friendly styles for uploads page */
|
||||||
display: none;
|
:root {
|
||||||
|
--bg: #0f1115;
|
||||||
|
--panel: #111217;
|
||||||
|
--muted: #9aa0a6;
|
||||||
|
--border: #242629;
|
||||||
|
--accent: #7c3aed;
|
||||||
|
--success: #16a34a;
|
||||||
|
--danger: #dc2626;
|
||||||
|
--card: #0f1216;
|
||||||
}
|
}
|
||||||
|
|
||||||
.indicator.htmx-request {
|
body {
|
||||||
display: block;
|
background: var(--bg);
|
||||||
|
color: #e6eef6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.indicator { display: none; }
|
||||||
|
.indicator.htmx-request { display: block; }
|
||||||
|
|
||||||
.loader {
|
.loader {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
aspect-ratio: 1;
|
aspect-ratio: 1;
|
||||||
@@ -204,9 +251,9 @@
|
|||||||
}
|
}
|
||||||
.loader::before,
|
.loader::before,
|
||||||
.loader::after {
|
.loader::after {
|
||||||
content:"";
|
content: "";
|
||||||
grid-area: 1/1;
|
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:
|
background:
|
||||||
var(--c) 50% 0,
|
var(--c) 50% 0,
|
||||||
var(--c) 50% 100%,
|
var(--c) 50% 100%,
|
||||||
@@ -214,51 +261,64 @@
|
|||||||
var(--c) 0 50%;
|
var(--c) 0 50%;
|
||||||
background-size: 12px 12px;
|
background-size: 12px 12px;
|
||||||
animation: l12 1s infinite;
|
animation: l12 1s infinite;
|
||||||
|
opacity: 0.95;
|
||||||
}
|
}
|
||||||
.loader::before {
|
.loader::before { margin: 4px; filter: hue-rotate(45deg); background-size: 8px 8px; }
|
||||||
margin: 4px;
|
@keyframes l12 { 100% { transform: rotate(.5turn) } }
|
||||||
filter: hue-rotate(45deg);
|
|
||||||
background-size: 8px 8px;
|
|
||||||
animation-timing-function: linear
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes l12 {
|
#series-list { user-select: none; }
|
||||||
100%{transform: rotate(.5turn)}
|
|
||||||
}
|
|
||||||
|
|
||||||
#series-list {
|
|
||||||
user-select: none;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.study-block {
|
.study-block {
|
||||||
margin: 8px 0;
|
margin: 8px 0;
|
||||||
padding: 6px;
|
padding: 8px;
|
||||||
border: 1px solid #e9ecef;
|
border: 1px solid var(--border);
|
||||||
border-radius: 6px;
|
border-radius: 8px;
|
||||||
background: #fafafa;
|
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 {
|
.study-block summary { font-size: 1rem; cursor: pointer; padding: 4px 6px; color: #e6eef6; }
|
||||||
font-size: 1rem;
|
|
||||||
cursor: pointer;
|
|
||||||
list-style: none;
|
|
||||||
padding: 4px 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.study-series-list {
|
.study-series-list { list-style: none; margin: 8px 0 0 0; padding: 0; }
|
||||||
list-style: none;
|
|
||||||
margin: 8px 0 0 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.study-series-list li {
|
.study-series-list li {
|
||||||
padding: 6px;
|
padding: 10px;
|
||||||
border-bottom: 1px solid #eee;
|
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; }
|
.study-series-list li:last-child { border-bottom: 0; }
|
||||||
.series-tags { font-size: 0.9rem; color: #666; }
|
|
||||||
|
.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 {
|
#series-list li {
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user