Refactor series cases handling: extract cases list to a partial and enhance HTMX integration for dynamic updates

This commit is contained in:
Ross
2025-11-14 21:55:28 +00:00
parent 8096a36a11
commit 835d0382ba
3 changed files with 52 additions and 38 deletions
@@ -0,0 +1,17 @@
{# Partial: series cases list. Expects `series` and `can_edit` in context. Returns the <ul> that is inserted into #cases-list. #}
<ul class="list-group list-group-flush">
{% for case in series.case.all %}
<li id="case-link-{{ case.pk }}" class="list-group-item d-flex justify-content-between align-items-center case-item">
<a href="{% url 'atlas:case_detail' pk=case.pk %}">{{case}}</a>
{% if can_edit %}
<button hx-post="{% url 'atlas:remove_series_from_case' series.pk case.pk %}"
hx-target="#cases-list"
hx-swap="innerHTML"
hx-confirm="Are you sure you want to remove this series from the case?"
class="btn btn-link btn-sm text-danger remove-button">Remove</button>
{% endif %}
</li>
{% empty %}
<li class="list-group-item">This series is not associated with any cases.</li>
{% endfor %}
</ul>
+23 -36
View File
@@ -120,42 +120,29 @@
<div class="card mb-3">
<div class="card-header">Cases</div>
<div class="card-body">
<ul class="list-group list-group-flush">
{% for case in series.case.all %}
<li id="case-link-{{ case.pk }}" class="list-group-item d-flex justify-content-between align-items-center case-item">
<a href="{% url 'atlas:case_detail' pk=case.pk %}">{{case}}</a>
{% if can_edit %}
<button hx-post="{% url 'atlas:remove_series_from_case' series.pk case.pk %}"
hx-target="#case-link-{{ case.pk }}"
hx-swap="outerHTML"
hx-confirm="Are you sure you want to remove this series from the case?"
class="btn btn-link btn-sm text-danger remove-button">Remove</button>
{% endif %}
</li>
{% empty %}
<li class="list-group-item">This series is not associated with any cases.</li>
{% if can_edit %}
<li class="list-group-item">
<details>
<summary>Add Series to Case</summary>
<form hx-post="{% url 'atlas:add_series_to_case' series.pk %}" hx-target="#add-series-to-case-result" hx-swap="innerHTML" class="mt-2">
{% csrf_token %}
<div class="mb-2">
<label for="case-select" class="form-label">Select Case</label>
<select name="case_id" id="case-select" class="form-select" required>
{% for case in available_cases %}
<option value="{{ case.pk }}">{{ case.title }}</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-primary btn-sm">Add to Case</button>
</form>
<div id="add-series-to-case-result"></div>
</details>
</li>
{% endif %}
{% endfor %}
</ul>
<div id="cases-list">
{% include 'atlas/partials/series_cases_list.html' %}
</div>
{% if can_edit %}
<details class="mt-2">
<summary>Add Series to Case</summary>
<form hx-post="{% url 'atlas:add_series_to_case' series.pk %}" hx-target="#cases-list" hx-swap="innerHTML" class="mt-2">
{% csrf_token %}
<div class="mb-2">
<label for="case-select" class="form-label">Select Case</label>
<select name="case_id" id="case-select" class="form-select" required>
{% for case in available_cases %}
<option value="{{ case.pk }}">{{ case.title }}</option>
{% endfor %}
</select>
</div>
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary btn-sm">Add to Case</button>
<button type="button" class="btn btn-outline-secondary btn-sm" data-bs-toggle="collapse" data-bs-target=".mt-2">Close</button>
</div>
</form>
</details>
{% endif %}
</div>
</div>
+12 -2
View File
@@ -4295,6 +4295,11 @@ def add_series_to_case(request, series_pk):
# Associate the series with the case
series.case.add(case)
# If this is an HTMX request, return the updated cases list partial so the
# client can replace the #cases-list innerHTML. Otherwise return a simple message.
if request.headers.get("Hx-Request") or request.META.get("HTTP_HX_REQUEST"):
return render(request, 'atlas/partials/series_cases_list.html', {'series': series, 'can_edit': case.check_user_can_edit(request.user)})
return HttpResponse(f"Series {series_pk} added to case {case.title} ({case_id}).")
return HttpResponse("Invalid request.")
@@ -4307,10 +4312,15 @@ def remove_series_from_case(request, series_pk, case_pk):
series = get_object_or_404(Series, pk=series_pk)
# Associate the series with the case
# Remove the association
series.case.remove(case)
return HttpResponse(f"Removed")
# If this is an HTMX request, return the updated cases list partial so the
# client can replace the #cases-list innerHTML. Otherwise return a simple message.
if request.headers.get("Hx-Request") or request.META.get("HTTP_HX_REQUEST"):
return render(request, 'atlas/partials/series_cases_list.html', {'series': series, 'can_edit': case.check_user_can_edit(request.user)})
return HttpResponse("Removed")
return HttpResponse("Invalid request.")
@login_required