Implement hiding and showing functionality for user exams and collections

This commit is contained in:
Ross
2026-06-15 11:23:00 +01:00
parent 35ab7443d2
commit c50ace771e
11 changed files with 400 additions and 50 deletions
@@ -5,40 +5,73 @@
<h5 class="card-title">Your collections</h5>
<h6 class="mt-3">Available to start</h6>
<ul class="list-unstyled">
<ul class="list-group list-group-sm mb-3">
{% for collection in available_collections %}
<li>
<a href="{% url 'atlas:collection_take_start' collection.pk %}">{{ collection.name }}</a>
{% if collection.description %}<small class="text-muted">{{ collection.description }}</small>{% endif %}
<li class="list-group-item d-flex justify-content-between align-items-center {% if collection.is_hidden %}opacity-50 bg-secondary bg-opacity-10{% endif %}">
<div>
<a href="{% url 'atlas:collection_take_start' collection.pk %}">{{ collection.name }}</a>
{% if collection.description %}<small class="text-muted"> — {{ collection.description }}</small>{% endif %}
{% if collection.is_hidden %}<span class="badge bg-warning text-dark ms-2">Hidden</span>{% endif %}
</div>
<form method="post" action="{% url 'generic:toggle_hide_item' %}" hx-post="{% url 'generic:toggle_hide_item' %}" class="d-inline">
{% csrf_token %}
<input type="hidden" name="content_type_id" value="{{ collection.content_type_id }}">
<input type="hidden" name="object_id" value="{{ collection.pk }}">
<button type="submit" class="btn btn-sm btn-link text-muted p-0" title="{% if collection.is_hidden %}Unhide collection{% else %}Hide collection{% endif %}">
<i class="bi {% if collection.is_hidden %}bi-eye-slash-fill text-warning{% else %}bi-eye{% endif %}" style="font-size: 1.15rem;"></i>
</button>
</form>
</li>
{% empty %}
<li class="text-muted">No collections available to start.</li>
<li class="list-group-item text-muted">No collections available to start.</li>
{% endfor %}
</ul>
<h6 class="mt-3">In progress</h6>
<ul class="list-unstyled">
<ul class="list-group list-group-sm mb-3">
{% for collection in in_progress_collections %}
<li>
<a href="{% url 'atlas:collection_take_start' collection.pk %}">{{ collection.name }}</a>
<span class="badge bg-warning text-dark ms-2">In progress</span>
{% if collection.description %}<small class="text-muted"> — {{ collection.description }}</small>{% endif %}
<li class="list-group-item d-flex justify-content-between align-items-center {% if collection.is_hidden %}opacity-50 bg-secondary bg-opacity-10{% endif %}">
<div>
<a href="{% url 'atlas:collection_take_start' collection.pk %}">{{ collection.name }}</a>
<span class="badge bg-warning text-dark ms-2">In progress</span>
{% if collection.description %}<small class="text-muted"> — {{ collection.description }}</small>{% endif %}
{% if collection.is_hidden %}<span class="badge bg-warning text-dark ms-2">Hidden</span>{% endif %}
</div>
<form method="post" action="{% url 'generic:toggle_hide_item' %}" hx-post="{% url 'generic:toggle_hide_item' %}" class="d-inline">
{% csrf_token %}
<input type="hidden" name="content_type_id" value="{{ collection.content_type_id }}">
<input type="hidden" name="object_id" value="{{ collection.pk }}">
<button type="submit" class="btn btn-sm btn-link text-muted p-0" title="{% if collection.is_hidden %}Unhide collection{% else %}Hide collection{% endif %}">
<i class="bi {% if collection.is_hidden %}bi-eye-slash-fill text-warning{% else %}bi-eye{% endif %}" style="font-size: 1.15rem;"></i>
</button>
</form>
</li>
{% empty %}
<li class="text-muted">No in-progress collections.</li>
<li class="list-group-item text-muted">No in-progress collections.</li>
{% endfor %}
</ul>
<h6 class="mt-3">Finished</h6>
<ul class="list-unstyled">
<ul class="list-group list-group-sm">
{% for collection in finished_collections %}
<li>
<a href="{% url 'atlas:collection_take_start' collection.pk %}">{{ collection.name }}</a>
<span class="badge bg-success ms-2">Completed</span>
{% if collection.description %}<small class="text-muted"> — {{ collection.description }}</small>{% endif %}
<li class="list-group-item d-flex justify-content-between align-items-center {% if collection.is_hidden %}opacity-50 bg-secondary bg-opacity-10{% endif %}">
<div>
<a href="{% url 'atlas:collection_take_start' collection.pk %}">{{ collection.name }}</a>
<span class="badge bg-success ms-2">Completed</span>
{% if collection.description %}<small class="text-muted"> — {{ collection.description }}</small>{% endif %}
{% if collection.is_hidden %}<span class="badge bg-warning text-dark ms-2">Hidden</span>{% endif %}
</div>
<form method="post" action="{% url 'generic:toggle_hide_item' %}" hx-post="{% url 'generic:toggle_hide_item' %}" class="d-inline">
{% csrf_token %}
<input type="hidden" name="content_type_id" value="{{ collection.content_type_id }}">
<input type="hidden" name="object_id" value="{{ collection.pk }}">
<button type="submit" class="btn btn-sm btn-link text-muted p-0" title="{% if collection.is_hidden %}Unhide collection{% else %}Hide collection{% endif %}">
<i class="bi {% if collection.is_hidden %}bi-eye-slash-fill text-warning{% else %}bi-eye{% endif %}" style="font-size: 1.15rem;"></i>
</button>
</form>
</li>
{% empty %}
<li class="text-muted">No finished collections.</li>
<li class="list-group-item text-muted">No finished collections.</li>
{% endfor %}
</ul>
+25 -3
View File
@@ -112,6 +112,7 @@ from .forms import (
UserQuestionAnswerForm,
UserReportAnswerForm,
)
from generic.models import UserHiddenItem
from .models import (
Case,
CaseCollection,
@@ -2786,11 +2787,32 @@ def user_collections(request):
# Finished (completed)
finished_qs = CaseCollection.objects.filter(pk__in=list(finished_ids)).order_by("name")
show_hidden = request.GET.get("show_hidden") in ("true", "1")
# Get content type for CaseCollection
ct_cc = ContentType.objects.get_for_model(CaseCollection)
hidden_ids = set(
UserHiddenItem.objects.filter(user=target_user, content_type=ct_cc).values_list("object_id", flat=True)
)
if not show_hidden:
available_qs = available_qs.exclude(pk__in=hidden_ids)
in_progress_qs = in_progress_qs.exclude(pk__in=hidden_ids)
finished_qs = finished_qs.exclude(pk__in=hidden_ids)
available_list = list(available_qs)
in_progress_list = list(in_progress_qs)
finished_list = list(finished_qs)
for coll in available_list + in_progress_list + finished_list:
coll.is_hidden = coll.pk in hidden_ids
context = {
"target_user": target_user,
"available_collections": available_qs,
"in_progress_collections": in_progress_qs,
"finished_collections": finished_qs,
"available_collections": available_list,
"in_progress_collections": in_progress_list,
"finished_collections": finished_list,
"show_hidden": show_hidden,
}
# If called via HTMX return a small fragment suitable for swapping