From c14ad2dcf71207b5df7fff88dbf46afe23ad3cc5 Mon Sep 17 00:00:00 2001 From: Ross Date: Mon, 2 Mar 2026 13:04:14 +0000 Subject: [PATCH] Refactor case import functionality and enhance logging in views --- atlas/templates/atlas/user_uploads.html | 273 ++++++++++-------------- atlas/views.py | 6 +- 2 files changed, 122 insertions(+), 157 deletions(-) diff --git a/atlas/templates/atlas/user_uploads.html b/atlas/templates/atlas/user_uploads.html index d854b0fe..2c259cc5 100644 --- a/atlas/templates/atlas/user_uploads.html +++ b/atlas/templates/atlas/user_uploads.html @@ -190,82 +190,6 @@ - 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'); - cb.dispatchEvent(new Event('change', { bubbles: true })); + } catch (e) { + document.getElementById(`import-status-${seriesId}`).innerHTML = `Series ${seriesId}: Failed`; } + } + statusDiv.innerHTML += "
All done.
"; + }); + } + + // Listen for `case:selected` events dispatched by the case-search widget and perform the import + document.body.addEventListener('case:selected', async function (e) { + try { + const detail = e.detail || {}; + const casePk = detail.casePk; + const caseTitle = detail.caseTitle || `#${casePk}`; + if (!casePk) { + console.error('case:selected without casePk'); + return; + } + + // Gather selected series + const checkboxes = Array.from(document.querySelectorAll('input[name="selection"]:checked')); + const allCheckboxes = Array.from(document.querySelectorAll('input[name="selection"]')); + const selectable = allCheckboxes.filter(cb => !cb.disabled).map(cb => cb.value); + const selectionList = checkboxes.length ? checkboxes.map(cb => cb.value) : selectable; + if (!selectionList.length) { + alert('Please select at least one series to import into the case.'); + return; + } + + const confirmMsg = `Import ${selectionList.length} series into case "${caseTitle}" (ID ${casePk})?`; + if (!window.confirm(confirmMsg)) return; + + // Build import URL and POST + const importTemplate = "{% url 'api-1:import_dicoms_case' 0 %}"; + 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'); + if (orderSeriesInput) form.append('order-series', orderSeriesInput.value); + const csrfToken = '{{ csrf_token }}'; + + const resp = await fetch(importUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'X-CSRFToken': csrfToken, + }, + body: form.toString(), + credentials: 'same-origin' }); - if (typeof updateSelectionCount === 'function') updateSelectionCount(); + const text = await resp.text(); + // Close modal and show result in import-status + const modalEl = document.getElementById('caseSelectModal'); + if (modalEl && window.bootstrap && bootstrap.Modal) { + bootstrap.Modal.getInstance(modalEl)?.hide(); + } + const statusDiv = document.getElementById('import-status'); + if (statusDiv) statusDiv.innerHTML = `
Imported into case ${casePk}: ${text}
`; + setTimeout(function(){ location.reload(); }, 1200); + } catch (err) { + console.error('Import handler error', err); + alert('Import failed — check console for details.'); } }); - // Row click toggles selection (avoid when clicking interactive elements inside) - 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 })); - }); + // Row click toggles selection (avoid when clicking interactive elements inside) + 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 })); + });