Implement case picker modal for enhanced case linking in markup inserter
This commit is contained in:
@@ -40,7 +40,7 @@
|
||||
btn.addEventListener('click', function(){
|
||||
const t = btn.dataset.type;
|
||||
if(t === 'case'){
|
||||
const id = prompt('Case ID to link to:'); if(!id) return; insertAtCursor(textarea, '[['+t+':'+id+']]' );
|
||||
openCasePicker(textarea);
|
||||
} else if(t === 'finding'){
|
||||
const id = prompt('Finding ID to link to:'); if(!id) return; insertAtCursor(textarea, '[['+t+':'+id+']]' );
|
||||
} else if(t === 'displayset'){
|
||||
@@ -122,4 +122,69 @@
|
||||
attachToSelector: attachToSelector
|
||||
};
|
||||
|
||||
// --- Case picker modal ---
|
||||
function openCasePicker(textarea){
|
||||
try{
|
||||
console.log('Opening case picker for', textarea);
|
||||
// Create overlay
|
||||
const overlay = document.createElement('div');
|
||||
overlay.className = 'markup-case-picker-overlay';
|
||||
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 = '<strong>Select case</strong>';
|
||||
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 cases...';
|
||||
const results = document.createElement('div'); results.className='case-search-results';
|
||||
body.appendChild(input); body.appendChild(results);
|
||||
|
||||
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 || '');
|
||||
// Fetch server-side partial that renders result list-group
|
||||
var url = window.location.origin + '/atlas/search/cases/?q=' + q;
|
||||
fetch(url, {credentials:'same-origin'}).then(function(r){ return r.text(); }).then(function(html){
|
||||
results.innerHTML = html;
|
||||
}).catch(function(e){ console.error('case picker fetch error', e); results.innerHTML = '<div class="alert alert-danger">Search failed</div>'; });
|
||||
}, 300);
|
||||
});
|
||||
|
||||
// Delegate click on result items
|
||||
results.addEventListener('click', function(e){
|
||||
var item = e.target.closest('.list-group-item');
|
||||
if(!item) return;
|
||||
var pk = item.getAttribute('data-case-pk');
|
||||
if(!pk){
|
||||
var a = item.querySelector('a');
|
||||
if(a){ var m = a.getAttribute('href').match(/case\/(\d+)\/?.*$/); if(m) pk = m[1]; }
|
||||
}
|
||||
if(!pk) return;
|
||||
insertAtCursor(textarea, '[['+'case:'+pk+']]' );
|
||||
// remove modal
|
||||
if(overlay && overlay.parentNode) overlay.parentNode.removeChild(overlay);
|
||||
});
|
||||
|
||||
// Allow ESC to close
|
||||
overlay.addEventListener('keydown', function(ev){ if(ev.key === 'Escape'){ if(overlay.parentNode) overlay.parentNode.removeChild(overlay); } });
|
||||
// make overlay focusable so keydown works
|
||||
overlay.tabIndex = -1; overlay.focus();
|
||||
// load initial recent results (empty query)
|
||||
fetch(window.location.origin + '/atlas/search/cases/').then(function(r){ return r.text(); }).then(function(html){ results.innerHTML = html; }).catch(function(){});
|
||||
}catch(err){ console.error('openCasePicker error', err); }
|
||||
}
|
||||
|
||||
})(window);
|
||||
|
||||
Reference in New Issue
Block a user