Add case jump functionality with HTMX support and corresponding template

This commit is contained in:
Ross
2025-11-24 11:40:52 +00:00
parent f713632fdd
commit efca426359
4 changed files with 79 additions and 8 deletions
@@ -3,19 +3,34 @@
{% block content %}
<span class="collection-name-blend">Collection: {{collection}}</span>
<h2>Case {{case_number|add:1}}
<div class="d-flex justify-content-between align-items-start">
<h2 class="mb-0">Case {{case_number|add:1}}
{% if show_title %}
: {{case.title}}
{% endif %}
{% if show_title %}
: {{case.title}}
{% endif %}
{% if question_completed %}
<span class="stamp-white">REVIEW</span>
{% endif %}
{% if question_completed %}
<span class="stamp-white">REVIEW</span>
{% endif %}
</h2>
</h2>
<!-- Case jump dropdown (loads via HTMX) - placed to the right of the header -->
<div class="dropdown ms-3">
<a class="btn btn-outline-secondary btn-sm dropdown-toggle" href="#" role="button" id="caseJump" data-bs-toggle="dropdown" aria-expanded="false"
hx-get="{% url 'atlas:collection_case_jump_partial' pk=collection.pk %}?current={{case_number}}{% if cid %}&cid={{cid}}&passcode={{passcode}}{% endif %}"
hx-target="#case-jump-menu"
hx-swap="innerHTML"
hx-trigger="click">
Jump
</a>
<div class="dropdown-menu dropdown-menu-end" id="case-jump-menu">
<div class="px-3 py-2 text-muted">Loading...</div>
</div>
</div>
</div>
{% if not question_completed and collection.question_time_limit is not None %}
<div id="question-timer-block" style="margin-top:8px; margin-bottom:8px;" title="This question has a time limit of {{ collection.question_time_limit }} seconds. The timer will start when the page loads.">
@@ -0,0 +1,11 @@
{% for cd in casedetails %}
{% with idx=forloop.counter0 %}
{% if cid %}
<a class="dropdown-item {% if idx == current %}active{% endif %}" href="{% url 'atlas:collection_case_view_take' pk=collection.pk case_number=idx cid=cid passcode=passcode %}">
{% else %}
<a class="dropdown-item {% if idx == current %}active{% endif %}" href="{% url 'atlas:collection_case_view_take_user' pk=collection.pk case_number=idx %}">
{% endif %}
Case {{ forloop.counter }}: {{ cd.case.title|default:cd.case.pk|truncatechars:60 }}
</a>
{% endwith %}
{% endfor %}
+5
View File
@@ -112,6 +112,11 @@ urlpatterns = [
views.CollectionCaseUpdate.as_view(),
name="collection_case_update",
),
path(
"collection/<int:pk>/case_jump",
views.collection_case_jump_partial,
name="collection_case_jump_partial",
),
path(
"collection/add_cases",
views.add_cases_to_collection,
+40
View File
@@ -1134,6 +1134,46 @@ def collection_options(request):
html = render_to_string("atlas/partials/collection_options.html", {"collections": collections}, request=request)
return HttpResponse(html)
@login_required
def collection_case_jump_partial(request, pk: int):
"""Return an HTMX partial containing a jump list for cases in the collection.
Expects optional GET params:
- current: the current case index (0-based) to mark active
- cid, passcode: optional candidate identifiers so links include them when present
"""
# Allow non-HTMX callers to still get the fragment (useful for testing)
collection = get_object_or_404(CaseCollection, pk=pk)
casedetails = (
CaseDetail.objects.filter(collection=collection)
.select_related('case')
.order_by('sort_order')
)
try:
current = int(request.GET.get('current', 0) or 0)
except Exception:
current = 0
cid = request.GET.get('cid')
passcode = request.GET.get('passcode')
html = render_to_string(
'atlas/partials/_collection_case_jump.html',
{
'collection': collection,
'casedetails': casedetails,
'current': current,
'cid': cid,
'passcode': passcode,
},
request=request,
)
return HttpResponse(html)
@login_required
def remove_cases_from_collection(request):
if not request.htmx: