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">
|
||||
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 %}
|
||||
<label for="case">Select Case to add:</label>
|
||||
<select name="case" id="case">
|
||||
@@ -11,4 +11,4 @@
|
||||
<button type="submit">Add</button>
|
||||
<button _="on click remove #add-case-form">Cancel</button>
|
||||
</form>
|
||||
</span
|
||||
</span>
|
||||
@@ -5,39 +5,7 @@
|
||||
{% partialdef casedetails-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">
|
||||
<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>
|
||||
{% include 'atlas/partials/casedetails_management_links.html' %}
|
||||
</div>
|
||||
|
||||
{% endpartialdef %}
|
||||
@@ -122,32 +90,11 @@
|
||||
<div class="col-12">
|
||||
<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 %}
|
||||
<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 }}>
|
||||
<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>
|
||||
{% include 'atlas/partials/case_list_item.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</ol>
|
||||
</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.
|
||||
Expects variables available from parent loop: casedetail, collection, forloop
|
||||
Keep markup minimal and safe — icons use Bootstrap Icons classes if available. #}
|
||||
<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 }})
|
||||
<span class="btn-group btn-group-sm me-2" role="group" aria-label="management-actions">
|
||||
<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>
|
||||
{% else %}
|
||||
<span class="text-muted small">No series</span>
|
||||
{% endif %}
|
||||
|
||||
{% if can_edit %}
|
||||
<a class="text-decoration-none" href="{% url 'atlas:case_series_update' pk=casedetail.case.pk %}" title="Edit case series">
|
||||
<i class="bi bi-pencil-square"></i> Edit series
|
||||
<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>
|
||||
{% 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)
|
||||
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":
|
||||
|
||||
@@ -4215,6 +4233,11 @@ def remove_case_from_collection(request, case_pk, collection_pk):
|
||||
# Remove the case from the collection
|
||||
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}")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user