diff --git a/atlas/templates/atlas/user_uploads.html b/atlas/templates/atlas/user_uploads.html index 2c259cc5..b5e2c821 100644 --- a/atlas/templates/atlas/user_uploads.html +++ b/atlas/templates/atlas/user_uploads.html @@ -199,8 +199,10 @@ // disable action buttons if none selected const deleteBtn = document.getElementById('delete-uploads-button'); const importBtn = document.getElementById('import-dicoms-sequential-button'); + const importIntoCaseBtn = document.getElementById('import-into-case-button'); if (deleteBtn) deleteBtn.disabled = selected === 0; if (importBtn) importBtn.disabled = selected === 0; + if (importIntoCaseBtn) importIntoCaseBtn.disabled = selected === 0; } // Keep count up-to-date on checkbox changes and attribute changes @@ -288,7 +290,8 @@ checkbox.disabled = true; checkbox.checked = false; } - li.querySelector('span')?.onclick = null; + const _sp = li.querySelector('span'); + if (_sp) _sp.onclick = null; li.style.pointerEvents = "none"; li.style.opacity = "0.7"; } @@ -300,6 +303,39 @@ }); } + // 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('.series-item'); + if (li) li.classList.add('selected'); + cb.dispatchEvent(new Event('change', { bubbles: true })); + } + }); + if (typeof updateSelectionCount === 'function') updateSelectionCount(); + } + 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('.series-item'); + if (li) li.classList.remove('selected'); + cb.dispatchEvent(new Event('change', { bubbles: true })); + } + }); + if (typeof updateSelectionCount === 'function') updateSelectionCount(); + } + }); + // Listen for `case:selected` events dispatched by the case-search widget and perform the import document.body.addEventListener('case:selected', async function (e) { try { @@ -326,7 +362,7 @@ // Build import URL and POST const importTemplate = "{% url 'api-1:import_dicoms_case' 0 %}"; - const importUrl = importTemplate.replace(/0\/?$/, casePk + '/'); + const importUrl = importTemplate.replace(/0\/?$/, casePk ); const form = new URLSearchParams(); for (const s of selectionList) form.append('selection', s); const orderSeriesInput = document.querySelector('input[name="order-series"]:checked'); @@ -357,18 +393,17 @@ } }); - // Row click toggles selection (avoid when clicking interactive elements inside) + // Row click toggles selection when clicking any non-interactive part of the series card document.body.addEventListener('click', function (e) { - const el = e.target.closest('.series-left'); - if (!el) return; - // ignore clicks on links, buttons or inputs inside the block - if (e.target.closest('a,button,input')) return; - const cb = el.querySelector('input[name="selection"]'); - if (!cb || cb.disabled) return; - cb.checked = !cb.checked; - const li = el.closest('li'); - if (li) li.classList.toggle('selected', cb.checked); - cb.dispatchEvent(new Event('change', { bubbles: true })); + const item = e.target.closest('.series-item'); + if (!item) return; + // ignore clicks on links, buttons, inputs or forms inside the item + if (e.target.closest('a,button,input,form')) return; + const cb = item.querySelector('input[name="selection"]'); + if (!cb || cb.disabled) return; + cb.checked = !cb.checked; + item.classList.toggle('selected', cb.checked); + cb.dispatchEvent(new Event('change', { bubbles: true })); });