Add inline collection management features; implement search and add functionality for collections in case view

This commit is contained in:
Ross
2026-02-02 11:55:43 +00:00
parent 00680c8b9e
commit f362be43ef
9 changed files with 196 additions and 13 deletions
+107
View File
@@ -2286,6 +2286,35 @@ def add_collection_to_case_form(request, case_id):
return render(request, "web/htmx_contact_form_confirm.html")
else:
form = AddCollectionToCaseForm(user=request.user)
# Resolve the Case early so templates always receive it when available
try:
case = Case.objects.get(pk=case_id)
except Exception:
case = None
# If called via HTMX (inline from case view) return a compact fragment
is_htmx = getattr(request, "htmx", False) or request.headers.get("HX-Request", "").lower() == "true"
if is_htmx:
# Provide the 10 most recently updated collections for this user by default
user = request.user
recent_base = (
CaseCollection.objects.filter(Q(author=user) | Q(markers=user))
.distinct()
.order_by("-updated")
)
# Exclude collections that already contain the case (if resolved)
if case is not None:
recent_base = recent_base.exclude(pk__in=case.casecollection_set.values_list("pk", flat=True))
recent_qs = recent_base[:10]
html = render_to_string(
"atlas/partials/add_collection_inline.html",
{"recent_collections": recent_qs, "case": case},
request=request,
)
return HttpResponse(html)
return render(
request,
"generic_form.html",
@@ -2296,6 +2325,84 @@ def add_collection_to_case_form(request, case_id):
)
@login_required
def collection_inline_search(request, case_id):
# HTMX endpoint: return recent collections or search results for the user
if not request.htmx:
return Http404
q = request.GET.get("q", "").strip()
user = request.user
base_qs = (
CaseCollection.objects.filter(Q(author=user) | Q(markers=user) | Q(valid_user_users=user) | Q(open_access=True))
.distinct()
)
try:
case = Case.objects.get(pk=case_id)
except Exception:
case = None
# Exclude collections already containing the case
if case is not None:
base_qs = base_qs.exclude(pk__in=case.casecollection_set.values_list("pk", flat=True))
if q:
results = base_qs.filter(name__icontains=q).order_by("-updated")[:30]
else:
results = base_qs.order_by("-updated")[:10]
html = render_to_string(
"atlas/partials/collection_inline_list.html",
{"collections": results, "case": case},
request=request,
)
return HttpResponse(html)
@login_required
@require_http_methods(["POST"])
def add_collection_to_case_inline(request, case_id, collection_id):
# HTMX endpoint to add a single collection to a case and return the new list item
if not request.htmx:
return Http404
case = get_object_or_404(Case, pk=case_id)
collection = get_object_or_404(CaseCollection, pk=collection_id)
# Permission: user must be able to edit the case
if not case.check_user_can_edit(request.user):
return HttpResponse("You do not have permission to add collections to this case.", status=403)
# Add the association
if collection in case.casecollection_set.all():
return HttpResponse("Already in collection")
case.casecollection_set.add(collection)
# Render a list item to insert into the case's collection list
rendered = render_to_string(
"atlas/partials/collection_list_item.html",
{"collection": collection, "case": case, "can_edit": case.check_user_can_edit(request.user)},
request=request,
)
# Also instruct the client to remove the collection entry from the inline search list
remove_script = (
'<script>'
'(function(){'
'try {'
"var pk = '%s';" % collection.pk +
"document.querySelectorAll('#collection-inline-list [data-collection-pk=\"' + pk + '\"]').forEach(function(el){ el.remove(); });" +
'} catch(e) { console.error("remove added collection from inline list error", e); }'
'})();'
'</script>'
)
return HttpResponse(rendered + remove_script)
# class AddCollectionToCaseView(FormView):
# form_class = AddCollectionToCaseForm
# template_name = "generic_form.html"