From 13d73020eeef653cdc67578cd46c50125f25a170 Mon Sep 17 00:00:00 2001 From: Ross Date: Mon, 23 Mar 2026 13:59:28 +0000 Subject: [PATCH] Enhance finding and display set pickers with dynamic case filtering and badge indicators --- atlas/static/atlas/js/markup_inserter.js | 57 +++++++++++++++++------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/atlas/static/atlas/js/markup_inserter.js b/atlas/static/atlas/js/markup_inserter.js index ab974670..3e4cbb4f 100644 --- a/atlas/static/atlas/js/markup_inserter.js +++ b/atlas/static/atlas/js/markup_inserter.js @@ -198,11 +198,25 @@ Object.assign(overlay.style, {position:'fixed',left:0,top:0,right:0,bottom:0,background:'rgba(0,0,0,0.4)',zIndex:1050,display:'flex',alignItems:'center',justifyContent:'center'}); const dialog = document.createElement('div'); dialog.className='markup-case-picker-dialog card'; Object.assign(dialog.style, {width:'min(900px,95%)',maxHeight:'80vh',overflow:'auto'}); const header = document.createElement('div'); header.className='card-header d-flex justify-content-between align-items-center'; header.innerHTML = 'Select finding'; - var detectedF = detectCurrentCase(textarea); - if(detectedF && detectedF.id){ - var badgeF = document.createElement('span'); badgeF.className = 'badge bg-secondary ms-2'; badgeF.style.marginLeft='8px'; badgeF.textContent = 'Filtering: ' + (detectedF.title || ('#'+detectedF.id)); - header.appendChild(badgeF); + var detectedF = detectCurrentCase(textarea) || {}; + var currentCaseF = caseId || detectedF.id || null; + var currentTitleF = detectedF.title || null; + var badgeContainerF = document.createElement('div'); badgeContainerF.className = 'd-flex align-items-center'; + var badgeTextF = document.createElement('span'); badgeTextF.className = 'badge bg-secondary ms-2'; badgeTextF.style.marginLeft='8px'; + function updateBadgeF(){ + if(currentCaseF){ + badgeTextF.textContent = 'Filtering: ' + (currentTitleF || ('#'+currentCaseF)); + removeBtnF.style.display = ''; + } else { + badgeTextF.textContent = 'No case filter'; + removeBtnF.style.display = 'none'; + } } + var removeBtnF = document.createElement('button'); removeBtnF.type='button'; removeBtnF.className='btn btn-sm btn-outline-light ms-2'; removeBtnF.style.padding='0 .4rem'; removeBtnF.textContent='✕'; + removeBtnF.addEventListener('click', function(){ currentCaseF = null; currentTitleF = null; updateBadgeF(); fetchInitialFindings(); }); + badgeContainerF.appendChild(badgeTextF); badgeContainerF.appendChild(removeBtnF); + updateBadgeF(); + header.appendChild(badgeContainerF); const closeBtn = document.createElement('button'); closeBtn.type='button'; closeBtn.className='btn-close'; closeBtn.setAttribute('aria-label','Close'); closeBtn.addEventListener('click', function(){ document.body.removeChild(overlay); }); header.appendChild(closeBtn); const body = document.createElement('div'); body.className='card-body'; const input = document.createElement('input'); input.type='search'; input.className='form-control mb-2'; input.placeholder='Type to search findings...'; @@ -210,12 +224,12 @@ dialog.appendChild(header); dialog.appendChild(body); overlay.appendChild(dialog); document.body.appendChild(overlay); input.focus(); var timer = null; - input.addEventListener('input', function(){ if(timer) clearTimeout(timer); timer = setTimeout(function(){ var q = encodeURIComponent(input.value || ''); var url = window.location.origin + '/atlas/search/findings/?q=' + q + (caseId ? '&case=' + caseId : ''); fetch(url, {credentials:'same-origin'}).then(function(r){ return r.text(); }).then(function(html){ results.innerHTML = html; }).catch(function(e){ console.error('finding picker fetch error', e); results.innerHTML = '
Search failed
'; }); }, 300); }); + input.addEventListener('input', function(){ if(timer) clearTimeout(timer); timer = setTimeout(function(){ var q = encodeURIComponent(input.value || ''); var url = window.location.origin + '/atlas/search/findings/?q=' + q + (currentCaseF ? '&case=' + currentCaseF : ''); fetch(url, {credentials:'same-origin'}).then(function(r){ return r.text(); }).then(function(html){ results.innerHTML = html; }).catch(function(e){ console.error('finding picker fetch error', e); results.innerHTML = '
Search failed
'; }); }, 300); }); results.addEventListener('click', function(e){ var item = e.target.closest('.list-group-item'); if(!item) return; var pk = item.getAttribute('data-finding-pk'); if(!pk) return; insertAtCursor(textarea, '[['+'finding:'+pk+']]' ); if(overlay && overlay.parentNode) overlay.parentNode.removeChild(overlay); }); overlay.tabIndex = -1; overlay.focus(); - var initFindingsUrl = window.location.origin + '/atlas/search/findings/' + (caseId ? '?case=' + caseId : ''); - fetch(initFindingsUrl).then(function(r){ return r.text(); }).then(function(html){ results.innerHTML = html; }).catch(function(){}); + function fetchInitialFindings(){ var initFindingsUrl = window.location.origin + '/atlas/search/findings/' + (currentCaseF ? '?case=' + currentCaseF : ''); fetch(initFindingsUrl).then(function(r){ return r.text(); }).then(function(html){ results.innerHTML = html; }).catch(function(){}); } + fetchInitialFindings(); }catch(err){ console.error('openFindingPicker error', err); } } @@ -228,12 +242,25 @@ const dialog = document.createElement('div'); dialog.className='markup-case-picker-dialog card'; Object.assign(dialog.style, {width:'min(900px,95%)',maxHeight:'80vh',overflow:'auto'}); const header = document.createElement('div'); header.className='card-header d-flex justify-content-between align-items-center'; header.innerHTML = 'Select display set'; - // show current case filter if present - var detected = detectCurrentCase(textarea); - if(detected && detected.id){ - var badge = document.createElement('span'); badge.className = 'badge bg-secondary ms-2'; badge.style.marginLeft='8px'; badge.textContent = 'Filtering: ' + (detected.title || ('#'+detected.id)); - header.appendChild(badge); + var detectedD = detectCurrentCase(textarea) || {}; + var currentCaseD = caseId || detectedD.id || null; + var currentTitleD = detectedD.title || null; + var badgeContainerD = document.createElement('div'); badgeContainerD.className = 'd-flex align-items-center'; + var badgeTextD = document.createElement('span'); badgeTextD.className = 'badge bg-secondary ms-2'; badgeTextD.style.marginLeft='8px'; + function updateBadgeD(){ + if(currentCaseD){ + badgeTextD.textContent = 'Filtering: ' + (currentTitleD || ('#'+currentCaseD)); + removeBtnD.style.display = ''; + } else { + badgeTextD.textContent = 'No case filter'; + removeBtnD.style.display = 'none'; + } } + var removeBtnD = document.createElement('button'); removeBtnD.type='button'; removeBtnD.className='btn btn-sm btn-outline-light ms-2'; removeBtnD.style.padding='0 .4rem'; removeBtnD.textContent='✕'; + removeBtnD.addEventListener('click', function(){ currentCaseD = null; currentTitleD = null; updateBadgeD(); fetchInitialDisplaysets(); }); + badgeContainerD.appendChild(badgeTextD); badgeContainerD.appendChild(removeBtnD); + updateBadgeD(); + header.appendChild(badgeContainerD); const closeBtn = document.createElement('button'); closeBtn.type='button'; closeBtn.className='btn-close'; closeBtn.setAttribute('aria-label','Close'); closeBtn.addEventListener('click', function(){ document.body.removeChild(overlay); }); header.appendChild(closeBtn); const body = document.createElement('div'); body.className='card-body'; const input = document.createElement('input'); input.type='search'; input.className='form-control mb-2'; input.placeholder='Type to search display sets...'; @@ -241,12 +268,12 @@ dialog.appendChild(header); dialog.appendChild(body); overlay.appendChild(dialog); document.body.appendChild(overlay); input.focus(); var timer = null; - input.addEventListener('input', function(){ if(timer) clearTimeout(timer); timer = setTimeout(function(){ var q = encodeURIComponent(input.value || ''); var url = window.location.origin + '/atlas/search/displaysets/?q=' + q + (caseId ? '&case=' + caseId : ''); fetch(url, {credentials:'same-origin'}).then(function(r){ return r.text(); }).then(function(html){ results.innerHTML = html; }).catch(function(e){ console.error('displayset picker fetch error', e); results.innerHTML = '
Search failed
'; }); }, 300); }); + input.addEventListener('input', function(){ if(timer) clearTimeout(timer); timer = setTimeout(function(){ var q = encodeURIComponent(input.value || ''); var url = window.location.origin + '/atlas/search/displaysets/?q=' + q + (currentCaseD ? '&case=' + currentCaseD : ''); fetch(url, {credentials:'same-origin'}).then(function(r){ return r.text(); }).then(function(html){ results.innerHTML = html; }).catch(function(e){ console.error('displayset picker fetch error', e); results.innerHTML = '
Search failed
'; }); }, 300); }); results.addEventListener('click', function(e){ var item = e.target.closest('.list-group-item'); if(!item) return; var pk = item.getAttribute('data-ds-pk'); if(!pk) return; insertAtCursor(textarea, '[['+'displayset:'+pk+']]' ); if(overlay && overlay.parentNode) overlay.parentNode.removeChild(overlay); }); overlay.tabIndex = -1; overlay.focus(); - var initDisplaysetsUrl = window.location.origin + '/atlas/search/displaysets/' + (caseId ? '?case=' + caseId : ''); - fetch(initDisplaysetsUrl).then(function(r){ return r.text(); }).then(function(html){ results.innerHTML = html; }).catch(function(){}); + function fetchInitialDisplaysets(){ var initDisplaysetsUrl = window.location.origin + '/atlas/search/displaysets/' + (currentCaseD ? '?case=' + currentCaseD : ''); fetch(initDisplaysetsUrl).then(function(r){ return r.text(); }).then(function(html){ results.innerHTML = html; }).catch(function(){}); } + fetchInitialDisplaysets(); }catch(err){ console.error('openDisplaysetPicker error', err); } }