Add case search functionality with HTMX support and results partial
This commit is contained in:
@@ -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>
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user