Enhance Supervisor Dashboard and Trainee Feedback Features

- Redesigned the supervisor overview page to include a header card with supervisor details and trainee statistics.
- Implemented a tabbed interface for viewing trainees and their recent attempts.
- Improved the trainee detail page with a profile card and a table for displaying attempt history.
- Added a new view for supervisors to provide feedback on case collections, including outstanding feedback items and previous conversations.
- Updated URL routing to support new feedback functionality.
- Enhanced backend logic to ensure proper sharing permissions for exam attempts and case collections.
- Added comprehensive tests for supervisor access to trainee data and feedback functionalities.
This commit is contained in:
Ross
2026-06-15 12:28:00 +01:00
parent c52cf46d65
commit a573ed78a4
16 changed files with 1150 additions and 100 deletions
@@ -1,9 +1,18 @@
{% extends 'atlas/base.html' %}
{% load crispy_forms_tags %}
{% load django_htmx %}
{% block content %}
<div class="mb-2"><small class="text-muted">Collection: <strong>{{collection}}</strong></small></div>
{% if viewing_as_user %}
<div class="alert alert-info d-flex align-items-center gap-2 py-2 px-3 mb-3" role="alert">
<i class="bi bi-eye-fill me-1"></i>
<span><strong>Reviewer mode</strong> &mdash; Viewing <strong>{{ target_user.get_full_name|default:target_user.username }}</strong>&rsquo;s answers. This screen is read-only.</span>
<a href="{% url 'atlas:collection_history_user' exam_id=collection.id user_pk=target_user.pk %}" class="btn btn-outline-info btn-sm ms-auto">Back to overview</a>
</div>
{% endif %}
<div class="d-flex justify-content-between align-items-start mb-3">
<div>
<h2 class="h4 mb-0">Case {{case_number|add:1}}
@@ -306,6 +315,7 @@
{% endif %}
{% endif %}
{% if not viewing_as_user %}
<div class="mb-2">
{% if previous %}
<button type="submit" name="previous" class="btn btn-outline-secondary btn-sm me-2">Previous</button>
@@ -323,11 +333,24 @@
<button type="submit" name="complete_case" class="btn btn-success btn-sm">Finish Case</button>
{% endif %}
<div class="mt-3">
<button type="submit" name="finish" class="btn btn-outline-secondary btn-sm">Overview</button>
<button type="submit" id="goto-button" value="test" name="goto" class="hide">goto</button>
</div>
{% else %}
{# Read-only navigation for reviewer mode — uses anchor links to avoid mutating POST #}
<div class="mb-2 d-flex gap-2 flex-wrap">
{% if previous %}
<a href="{% url 'atlas:collection_case_view_take_review_user' pk=collection.id case_number=case_number|add:'-1' user_pk=target_user.pk %}" class="btn btn-outline-secondary btn-sm">Previous</a>
{% endif %}
{% if next %}
<a href="{% url 'atlas:collection_case_view_take_review_user' pk=collection.id case_number=case_number|add:'1' user_pk=target_user.pk %}" class="btn btn-primary btn-sm">Next</a>
{% endif %}
</div>
<div class="mt-3">
<a href="{% url 'atlas:collection_history_user' exam_id=collection.id user_pk=target_user.pk %}" class="btn btn-outline-secondary btn-sm">Overview</a>
</div>
{% endif %}
</form>
{% if question_completed and collection.case_query_messaging_enabled %}
@@ -45,7 +45,7 @@
</div>
<div class="d-flex flex-wrap gap-2">
<a class="btn btn-sm btn-primary"
href="{% url 'atlas:collection_case_view' pk=collection.id case_number=forloop.counter0 %}">
href="{% url 'atlas:collection_case_view_take_review_user' pk=collection.id case_number=forloop.counter0 user_pk=user.pk %}">
Open Case
</a>
{% if request.user.is_superuser and row.user_answer %}