Refactor case management links and add case list item partial for improved organization and rendering in collection detail view
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<span id="add-case-form">
|
<span id="add-case-form">
|
||||||
This form allows you to add an existing case to the collection. You may find it easier to do this from the individual case pages or the <a href="{% url 'atlas:case_view' %}">case overview view</a> which allows you to add multiple cases at once.
|
This form allows you to add an existing case to the collection. You may find it easier to do this from the individual case pages or the <a href="{% url 'atlas:case_view' %}">case overview view</a> which allows you to add multiple cases at once.
|
||||||
<form hx-post="{% url 'atlas:add_case_to_collection' collection.id %}" hx-swap="outerHTML">
|
<form hx-post="{% url 'atlas:add_case_to_collection' collection.id %}" hx-target="#full-question-list" hx-swap="beforeend">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<label for="case">Select Case to add:</label>
|
<label for="case">Select Case to add:</label>
|
||||||
<select name="case" id="case">
|
<select name="case" id="case">
|
||||||
@@ -11,4 +11,4 @@
|
|||||||
<button type="submit">Add</button>
|
<button type="submit">Add</button>
|
||||||
<button _="on click remove #add-case-form">Cancel</button>
|
<button _="on click remove #add-case-form">Cancel</button>
|
||||||
</form>
|
</form>
|
||||||
</span
|
</span>
|
||||||
@@ -5,39 +5,7 @@
|
|||||||
{% partialdef casedetails-management-links %}
|
{% partialdef casedetails-management-links %}
|
||||||
|
|
||||||
<div class="btn-toolbar" role="toolbar" aria-label="Case management links">
|
<div class="btn-toolbar" role="toolbar" aria-label="Case management links">
|
||||||
<div class="btn-group btn-group-sm me-2" role="group" aria-label="management-actions">
|
{% include 'atlas/partials/casedetails_management_links.html' %}
|
||||||
<a class="btn btn-outline-secondary" href="{% url 'atlas:collection_case_displaysetup' casedetail.collection.pk casedetail.case.pk %}" title="Setup default display">
|
|
||||||
<i class="bi bi-display"></i>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a class="btn btn-outline-secondary" href="{% url 'atlas:collection_case_details' casedetail.collection.pk casedetail.case.pk %}" title="Case details">
|
|
||||||
<i class="bi bi-info-square"></i>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{% if collection.collection_type == "QUE" %}
|
|
||||||
<a class="btn btn-outline-secondary" href='{% url "atlas:collection_case_questions" casedetail.collection.pk casedetail.case.pk %}' title="Manage questions">
|
|
||||||
{% if casedetail.question_schema %}
|
|
||||||
<i class="bi bi-question-square text-success"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="bi bi-question-square text-danger"></i>
|
|
||||||
{% endif %}
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if casedetail.case.previous_case %}
|
|
||||||
<a class="btn btn-outline-secondary" href='{% url "atlas:collection_case_priors" casedetail.collection.pk casedetail.case.pk %}' title="Manage priors">
|
|
||||||
<i class="bi bi-link-45deg"></i>
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="btn-group btn-group-sm" role="group" aria-label="status-indicator">
|
|
||||||
{% if casedetail.default_viewerstate %}
|
|
||||||
<button type="button" class="btn btn-sm btn-outline-success" aria-disabled="true" title="This case has a default viewerstate defined">
|
|
||||||
<i class="bi bi-check"></i>
|
|
||||||
</button>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endpartialdef %}
|
{% endpartialdef %}
|
||||||
@@ -122,32 +90,11 @@
|
|||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<h3 class="mb-3">Cases</h3>
|
<h3 class="mb-3">Cases</h3>
|
||||||
|
|
||||||
<div class="list-group sortable" id="full-question-list">
|
<ol id="full-question-list" class="sortable list-group list-group-numbered">
|
||||||
{% for casedetail in casesdetails %}
|
{% for casedetail in casesdetails %}
|
||||||
<div class="list-group-item list-group-item-action mb-2 p-3 d-flex justify-content-between align-items-start" data-question_pk={{ casedetail.case.pk }}>
|
{% include 'atlas/partials/case_list_item.html' %}
|
||||||
<div>
|
|
||||||
<div class="fw-bold">
|
|
||||||
<a href="{% url 'atlas:collection_case_view' pk=collection.pk case_number=forloop.counter0 %}">Case {{ forloop.counter }}</a>
|
|
||||||
<span class="ms-2">{{ casedetail.case.title }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="small text-muted mt-1">
|
|
||||||
{% if casedetail.case.series.count == 0 %}
|
|
||||||
<span class="text-warning">No series attached</span>
|
|
||||||
{% else %}
|
|
||||||
{{ casedetail.case.series.count }} series
|
|
||||||
{% endif %}
|
|
||||||
{% if casedetail.question_schema %}
|
|
||||||
• <span class="text-success">Questions defined</span>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="ms-3 d-flex align-items-center">
|
|
||||||
{% partial casedetails-management-links %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<li class="list-group-item d-flex gap-3 align-items-start" data-question_pk="{{ casedetail.case.pk }}">
|
||||||
|
|
||||||
|
<div class="flex-fill">
|
||||||
|
<div class="d-flex justify-content-between align-items-start">
|
||||||
|
<div>
|
||||||
|
<a class="h6 mb-0 text-decoration-none" href="{% url 'atlas:collection_case_view' pk=collection.pk case_number=forloop.counter0 %}">{{ casedetail.case.title }}</a>
|
||||||
|
<div class="small text-muted">Case {{ forloop.counter }} — <span class="text-truncate">{{ casedetail.case.description|default_if_none:""|truncatechars:80 }}</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-2 small text-muted">
|
||||||
|
{% if casedetail.case.series.count == 0 %}
|
||||||
|
<span class="text-warning">No series attached</span>
|
||||||
|
{% else %}
|
||||||
|
{{ casedetail.case.series.count }} series
|
||||||
|
{% endif %}
|
||||||
|
{% if casedetail.question_schema %}
|
||||||
|
• <span class="text-success">Questions defined</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="d-flex align-items-center ms-3">
|
||||||
|
{% include 'atlas/partials/casedetails_management_links.html' %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</li>
|
||||||
@@ -1,26 +1,33 @@
|
|||||||
{# Partial: per-case management links shown on collection detail case list.
|
<span class="btn-group btn-group-sm me-2" role="group" aria-label="management-actions">
|
||||||
Expects variables available from parent loop: casedetail, collection, forloop
|
<a class="btn btn-outline-secondary" href="{% url 'atlas:collection_case_displaysetup' casedetail.collection.pk casedetail.case.pk %}" title="Setup default display">
|
||||||
Keep markup minimal and safe — icons use Bootstrap Icons classes if available. #}
|
<i class="bi bi-display"></i>
|
||||||
<span class="d-inline-flex gap-2 align-items-center">
|
|
||||||
<a class="text-decoration-none" href="{% url 'atlas:collection_case_view' pk=collection.pk case_number=forloop.counter0 %}" title="Open case view">
|
|
||||||
<i class="bi bi-eye"></i> View
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a class="text-decoration-none" href="{% url 'atlas:case_detail' casedetail.case.pk %}" title="Case details">
|
|
||||||
<i class="bi bi-info-circle"></i> Details
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{% if casedetail.case.series.count > 0 %}
|
|
||||||
<a class="text-decoration-none" href="{% url 'atlas:case_displaysets' casedetail.case.pk %}" title="Series ({{ casedetail.case.series.count }})">
|
|
||||||
<i class="bi bi-images"></i> Series ({{ casedetail.case.series.count }})
|
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
|
||||||
<span class="text-muted small">No series</span>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if can_edit %}
|
<a class="btn btn-outline-secondary" href="{% url 'atlas:collection_case_details' casedetail.collection.pk casedetail.case.pk %}" title="Case details">
|
||||||
<a class="text-decoration-none" href="{% url 'atlas:case_series_update' pk=casedetail.case.pk %}" title="Edit case series">
|
<i class="bi bi-info-square"></i>
|
||||||
<i class="bi bi-pencil-square"></i> Edit series
|
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
|
||||||
</span>
|
{% if collection.collection_type == "QUE" %}
|
||||||
|
<a class="btn btn-outline-secondary" href='{% url "atlas:collection_case_questions" casedetail.collection.pk casedetail.case.pk %}' title="Manage questions">
|
||||||
|
{% if casedetail.question_schema %}
|
||||||
|
<i class="bi bi-question-square text-success"></i>
|
||||||
|
{% else %}
|
||||||
|
<i class="bi bi-question-square text-danger"></i>
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if casedetail.case.previous_case %}
|
||||||
|
<a class="btn btn-outline-secondary" href='{% url "atlas:collection_case_priors" casedetail.collection.pk casedetail.case.pk %}' title="Manage priors">
|
||||||
|
<i class="bi bi-link-45deg"></i>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-group btn-group-sm" role="group" aria-label="status-indicator">
|
||||||
|
{% if casedetail.default_viewerstate %}
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-success" aria-disabled="true" title="This case has a default viewerstate defined">
|
||||||
|
<i class="bi bi-check"></i>
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
+24
-1
@@ -1151,7 +1151,25 @@ def add_case_to_collection(request, collection_id):
|
|||||||
|
|
||||||
print(case)
|
print(case)
|
||||||
collection.add_case(case)
|
collection.add_case(case)
|
||||||
return HttpResponse(f"Case added to collection {collection.name} (refresh to see)")
|
# Render the new case list item and return it so HTMX can append it
|
||||||
|
try:
|
||||||
|
casedetail = collection.casedetail_set.get(case=case)
|
||||||
|
except Exception:
|
||||||
|
return HttpResponse("Case added, but could not render item.")
|
||||||
|
|
||||||
|
total = collection.casedetail_set.count()
|
||||||
|
can_edit = request.user.is_superuser or collection.author.filter(pk=request.user.pk).exists()
|
||||||
|
rendered = render_to_string(
|
||||||
|
"atlas/partials/case_list_item.html",
|
||||||
|
{
|
||||||
|
"casedetail": casedetail,
|
||||||
|
"collection": collection,
|
||||||
|
"forloop": {"counter": total, "counter0": max(0, total - 1)},
|
||||||
|
"can_edit": can_edit,
|
||||||
|
},
|
||||||
|
request=request,
|
||||||
|
)
|
||||||
|
return HttpResponse(rendered)
|
||||||
|
|
||||||
# if request.method == "POST":
|
# if request.method == "POST":
|
||||||
|
|
||||||
@@ -4215,6 +4233,11 @@ def remove_case_from_collection(request, case_pk, collection_pk):
|
|||||||
# Remove the case from the collection
|
# Remove the case from the collection
|
||||||
collection.cases.remove(case)
|
collection.cases.remove(case)
|
||||||
|
|
||||||
|
# If this was an HTMX request, return an empty response so the caller
|
||||||
|
# can swap out (remove) the surrounding element (e.g., the <li>).
|
||||||
|
if request.htmx:
|
||||||
|
return HttpResponse("")
|
||||||
|
|
||||||
return HttpResponse(f"Case removed from collection: {collection.name}")
|
return HttpResponse(f"Case removed from collection: {collection.name}")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user