Add finding and displayset search functionality with corresponding widgets and endpoints
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
<div class="list-group">
|
||||
{% if displaysets %}
|
||||
{% for ds in displaysets %}
|
||||
<div class="list-group-item d-flex justify-content-between align-items-center" data-ds-pk="{{ ds.pk }}">
|
||||
<div class="flex-fill">
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<strong class="mb-1">{{ ds.name }}</strong>
|
||||
<small class="text-muted">{{ ds.pk }}</small>
|
||||
</div>
|
||||
<p class="mb-1 text-truncate">{{ ds.description }}</p>
|
||||
</div>
|
||||
<div class="ms-2">
|
||||
<a class="btn btn-sm btn-outline-secondary" href="{% url 'atlas:case_displaysets_detail' ds.pk %}">View</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="list-group-item">No display sets found</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -0,0 +1,20 @@
|
||||
<div class="list-group">
|
||||
{% if findings %}
|
||||
{% for f in findings %}
|
||||
<div class="list-group-item d-flex justify-content-between align-items-center" data-finding-pk="{{ f.pk }}">
|
||||
<div class="flex-fill">
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<strong class="mb-1">{{ f.name }}</strong>
|
||||
<small class="text-muted">{{ f.pk }}</small>
|
||||
</div>
|
||||
<p class="mb-1 text-truncate">{{ f.description }}</p>
|
||||
</div>
|
||||
<div class="ms-2">
|
||||
<a class="btn btn-sm btn-outline-secondary" href="{% url 'atlas:finding_detail' f.pk %}">View</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="list-group-item">No findings found</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -0,0 +1,45 @@
|
||||
<div class="displayset-search-widget">
|
||||
{% with input_id=input_id|default:'displayset-search-input' target_id=target_id|default:'displayset-search-results' %}
|
||||
<label for="{{ input_id }}" class="form-label">Search display sets</label>
|
||||
<input id="{{ input_id }}" name="q" class="form-control" type="search"
|
||||
placeholder="Type to search display sets..."
|
||||
hx-get="{% url 'atlas:displayset_search_partial' %}"
|
||||
hx-include="#{{ input_id }}"
|
||||
{% if case %}hx-vals='{"case": "{{ case.pk }}"}'{% endif %}
|
||||
hx-target="#{{ target_id }}"
|
||||
hx-trigger="keyup changed delay:400ms"
|
||||
autocomplete="off">
|
||||
|
||||
<div id="{{ target_id }}" class="mt-2">
|
||||
{% include 'atlas/partials/_displayset_search_results.html' with displaysets=displaysets case=case %}
|
||||
</div>
|
||||
{% endwith %}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function(){
|
||||
try {
|
||||
var input = document.getElementById('{{ input_id|default:"displayset-search-input" }}');
|
||||
if (!input) return;
|
||||
var timer = null;
|
||||
input.addEventListener('input', function(){
|
||||
if (timer) clearTimeout(timer);
|
||||
timer = setTimeout(function(){
|
||||
try {
|
||||
var q = encodeURIComponent(input.value || '');
|
||||
var url = "{% url 'atlas:displayset_search' %}?q=" + q + ({% if case %} "&case={{ case.pk }}" {% else %} '' {% endif %});
|
||||
var target = '#{{ target_id|default:"displayset-search-results" }}';
|
||||
if (window.htmx && typeof window.htmx.ajax === 'function') {
|
||||
window.htmx.ajax('GET', url, { target: target, swap: 'innerHTML' });
|
||||
} else {
|
||||
fetch(url, { credentials: 'same-origin' }).then(function(r){ return r.text(); }).then(function(html){
|
||||
var el = document.querySelector(target);
|
||||
if (el) el.innerHTML = html;
|
||||
}).catch(function(e){ console.error('displayset search fetch error', e); });
|
||||
}
|
||||
} catch(e) { console.error(e); }
|
||||
}, 400);
|
||||
});
|
||||
} catch(e) { console.error('displayset search widget init error', e); }
|
||||
})();
|
||||
</script>
|
||||
@@ -0,0 +1,45 @@
|
||||
<div class="finding-search-widget">
|
||||
{% with input_id=input_id|default:'finding-search-input' target_id=target_id|default:'finding-search-results' %}
|
||||
<label for="{{ input_id }}" class="form-label">Search findings</label>
|
||||
<input id="{{ input_id }}" name="q" class="form-control" type="search"
|
||||
placeholder="Type to search findings..."
|
||||
hx-get="{% url 'atlas:finding_search_partial' %}"
|
||||
hx-include="#{{ input_id }}"
|
||||
{% if case %}hx-vals='{"case": "{{ case.pk }}"}'{% endif %}
|
||||
hx-target="#{{ target_id }}"
|
||||
hx-trigger="keyup changed delay:400ms"
|
||||
autocomplete="off">
|
||||
|
||||
<div id="{{ target_id }}" class="mt-2">
|
||||
{% include 'atlas/partials/_finding_search_results.html' with findings=findings case=case %}
|
||||
</div>
|
||||
{% endwith %}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function(){
|
||||
try {
|
||||
var input = document.getElementById('{{ input_id|default:"finding-search-input" }}');
|
||||
if (!input) return;
|
||||
var timer = null;
|
||||
input.addEventListener('input', function(){
|
||||
if (timer) clearTimeout(timer);
|
||||
timer = setTimeout(function(){
|
||||
try {
|
||||
var q = encodeURIComponent(input.value || '');
|
||||
var url = "{% url 'atlas:finding_search' %}?q=" + q + ({% if case %} "&case={{ case.pk }}" {% else %} '' {% endif %});
|
||||
var target = '#{{ target_id|default:"finding-search-results" }}';
|
||||
if (window.htmx && typeof window.htmx.ajax === 'function') {
|
||||
window.htmx.ajax('GET', url, { target: target, swap: 'innerHTML' });
|
||||
} else {
|
||||
fetch(url, { credentials: 'same-origin' }).then(function(r){ return r.text(); }).then(function(html){
|
||||
var el = document.querySelector(target);
|
||||
if (el) el.innerHTML = html;
|
||||
}).catch(function(e){ console.error('finding search fetch error', e); });
|
||||
}
|
||||
} catch(e) { console.error(e); }
|
||||
}, 400);
|
||||
});
|
||||
} catch(e) { console.error('finding search widget init error', e); }
|
||||
})();
|
||||
</script>
|
||||
Reference in New Issue
Block a user