Collections
diff --git a/atlas/templates/atlas/partials/_case_search_results.html b/atlas/templates/atlas/partials/_case_search_results.html
new file mode 100644
index 00000000..1b7665f9
--- /dev/null
+++ b/atlas/templates/atlas/partials/_case_search_results.html
@@ -0,0 +1,16 @@
+{# partial: list of cases for HTMX search results #}
+
diff --git a/atlas/urls.py b/atlas/urls.py
index 5606d170..28a63118 100755
--- a/atlas/urls.py
+++ b/atlas/urls.py
@@ -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/
", views.condition_detail, name="condition_detail"),
path(
"condition//delete",
diff --git a/atlas/views.py b/atlas/views.py
index d59de28f..75168c7c 100755
--- a/atlas/views.py
+++ b/atlas/views.py
@@ -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)