Enhance finding and display set pickers with dynamic case filtering and badge indicators
This commit is contained in:
@@ -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'});
|
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 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 finding</strong>';
|
const header = document.createElement('div'); header.className='card-header d-flex justify-content-between align-items-center'; header.innerHTML = '<strong>Select finding</strong>';
|
||||||
var detectedF = detectCurrentCase(textarea);
|
var detectedF = detectCurrentCase(textarea) || {};
|
||||||
if(detectedF && detectedF.id){
|
var currentCaseF = caseId || detectedF.id || null;
|
||||||
var badgeF = document.createElement('span'); badgeF.className = 'badge bg-secondary ms-2'; badgeF.style.marginLeft='8px'; badgeF.textContent = 'Filtering: ' + (detectedF.title || ('#'+detectedF.id));
|
var currentTitleF = detectedF.title || null;
|
||||||
header.appendChild(badgeF);
|
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 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 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...';
|
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();
|
dialog.appendChild(header); dialog.appendChild(body); overlay.appendChild(dialog); document.body.appendChild(overlay); input.focus();
|
||||||
|
|
||||||
var timer = null;
|
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 = '<div class="alert alert-danger">Search failed</div>'; }); }, 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 = '<div class="alert alert-danger">Search failed</div>'; }); }, 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); });
|
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();
|
overlay.tabIndex = -1; overlay.focus();
|
||||||
var initFindingsUrl = window.location.origin + '/atlas/search/findings/' + (caseId ? '?case=' + caseId : '');
|
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(){}); }
|
||||||
fetch(initFindingsUrl).then(function(r){ return r.text(); }).then(function(html){ results.innerHTML = html; }).catch(function(){});
|
fetchInitialFindings();
|
||||||
}catch(err){ console.error('openFindingPicker error', err); }
|
}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 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';
|
const header = document.createElement('div'); header.className='card-header d-flex justify-content-between align-items-center';
|
||||||
header.innerHTML = '<strong>Select display set</strong>';
|
header.innerHTML = '<strong>Select display set</strong>';
|
||||||
// show current case filter if present
|
var detectedD = detectCurrentCase(textarea) || {};
|
||||||
var detected = detectCurrentCase(textarea);
|
var currentCaseD = caseId || detectedD.id || null;
|
||||||
if(detected && detected.id){
|
var currentTitleD = detectedD.title || null;
|
||||||
var badge = document.createElement('span'); badge.className = 'badge bg-secondary ms-2'; badge.style.marginLeft='8px'; badge.textContent = 'Filtering: ' + (detected.title || ('#'+detected.id));
|
var badgeContainerD = document.createElement('div'); badgeContainerD.className = 'd-flex align-items-center';
|
||||||
header.appendChild(badge);
|
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 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 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...';
|
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();
|
dialog.appendChild(header); dialog.appendChild(body); overlay.appendChild(dialog); document.body.appendChild(overlay); input.focus();
|
||||||
|
|
||||||
var timer = null;
|
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 = '<div class="alert alert-danger">Search failed</div>'; }); }, 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 = '<div class="alert alert-danger">Search failed</div>'; }); }, 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); });
|
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();
|
overlay.tabIndex = -1; overlay.focus();
|
||||||
var initDisplaysetsUrl = window.location.origin + '/atlas/search/displaysets/' + (caseId ? '?case=' + caseId : '');
|
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(){}); }
|
||||||
fetch(initDisplaysetsUrl).then(function(r){ return r.text(); }).then(function(html){ results.innerHTML = html; }).catch(function(){});
|
fetchInitialDisplaysets();
|
||||||
}catch(err){ console.error('openDisplaysetPicker error', err); }
|
}catch(err){ console.error('openDisplaysetPicker error', err); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user