Add case search functionality with HTMX support and results partial

This commit is contained in:
Ross
2025-11-05 21:37:57 +00:00
parent 89a767034c
commit 03a24615ab
4 changed files with 57 additions and 0 deletions
+15
View File
@@ -10,6 +10,21 @@
<div class="row">
<div class="col-12 col-md-8">
<div class="card mb-3">
<div class="card-body">
<h5 class="card-title">Search cases</h5>
<div class="mb-2">
<input class="form-control" id="case-search-input" name="q" placeholder="Search cases by title or description"
hx-get="{% url 'atlas:case_search_partial' %}"
hx-trigger="keyup changed delay:500ms"
hx-target="#case-search-results"
hx-include="#case-search-input">
</div>
<div id="case-search-results" hx-swap-oob="true">
{% include 'atlas/partials/_case_search_results.html' with cases=None %}
</div>
</div>
</div>
<div class="card mb-3">
<div class="card-body">
<h5 class="card-title">Collections</h5>
@@ -0,0 +1,16 @@
{# partial: list of cases for HTMX search results #}
<div class="list-group">
{% if cases and cases.exists %}
{% for case in cases %}
<a href="{% url 'atlas:case_detail' case.pk %}" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h6 class="mb-1">{{ case.title }}</h6>
<small class="text-muted">{{ case.created_date|date:"Y-m-d" }}</small>
</div>
<p class="mb-1 text-truncate">{{ case.description }}</p>
</a>
{% endfor %}
{% else %}
<div class="list-group-item">No cases found</div>
{% endif %}
</div>
+1
View File
@@ -348,6 +348,7 @@ urlpatterns = [
path("condition/", views.ConditionView.as_view(), name="condition_view"),
path("categories/", views.categories_list, name="categories_list"),
path("categories/search_partial/", views.categories_search_partial, name="categories_search_partial"),
path("search/cases/", views.case_search_partial, name="case_search_partial"),
path("condition/<int:pk>", views.condition_detail, name="condition_detail"),
path(
"condition/<int:pk>/delete",
+25
View File
@@ -183,6 +183,31 @@ from helpers.cimar import CimarAPI
logger = logging.getLogger(__name__)
@login_required
def case_search_partial(request):
"""Return an HTMX partial listing cases matching the query parameter `q`.
This view returns a small list-group fragment that can be swapped into
the index page. It respects the user's available cases via
get_cases_available_to_user.
"""
q = request.GET.get('q', '') or request.GET.get('case-search-input', '')
q = q.strip()
# Start with cases available to the user
qs = get_cases_available_to_user(request.user)
if q:
from django.db.models import Q
qs = qs.filter(Q(title__icontains=q) | Q(description__icontains=q)).distinct()
qs = qs.order_by('-created_date')[:20]
html = render_to_string('atlas/partials/_case_search_results.html', {'cases': qs}, request=request)
return HttpResponse(html)
class AuthorOrCheckerRequiredMixin(object):
def get_object(self, *args, **kwargs):
obj = super().get_object(*args, **kwargs)