feat: Consolidate shared attempts functionality into supervision page and remove legacy shared-with-me page
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
<div id="sharing-panel-{{ cid_user_exam.pk }}" class="card border-secondary mt-3">
|
||||
<div class="card-header py-2 px-3 d-flex justify-content-between align-items-center">
|
||||
<span class="fw-semibold small">Result Sharing</span>
|
||||
<a href="{% url 'atlas:collection_shared_with_me' %}" class="btn btn-sm btn-outline-secondary">Shared with me</a>
|
||||
<a href="{% url 'atlas:collection_supervision' %}" class="btn btn-sm btn-outline-secondary">Supervision</a>
|
||||
</div>
|
||||
<div class="card-body py-2 px-3">
|
||||
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
{% extends 'atlas/exams.html' %}
|
||||
{% load static %}
|
||||
|
||||
{% block content %}
|
||||
<div class="mb-3">
|
||||
<h2 class="h4 mb-1">Shared with me</h2>
|
||||
<p class="text-muted small mb-0">
|
||||
Collection attempts shared with you as an author, marker, supervisor, or by direct invitation.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{% if attempt_list %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Collection</th>
|
||||
<th>Learner</th>
|
||||
<th>Started</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for attempt, collection in attempt_list %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if collection %}
|
||||
<strong>{{ collection.name }}</strong>
|
||||
{% else %}
|
||||
<span class="text-muted">Unknown collection</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if attempt.user_user %}
|
||||
{{ attempt.user_user.get_full_name|default:attempt.user_user.username }}
|
||||
{% if attempt.user_user.email %}
|
||||
<br><span class="small text-muted">{{ attempt.user_user.email }}</span>
|
||||
{% endif %}
|
||||
{% elif attempt.cid_user %}
|
||||
CID {{ attempt.cid_user.cid }}
|
||||
{% if attempt.cid_user.name %}<br><span class="small text-muted">{{ attempt.cid_user.name }}</span>{% endif %}
|
||||
{% else %}
|
||||
<span class="text-muted">Unknown</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="small">{{ attempt.start_time|default:"-" }}</td>
|
||||
<td>
|
||||
{% if attempt.completed %}
|
||||
<span class="badge bg-success">Completed</span>
|
||||
{% else %}
|
||||
<span class="badge bg-warning text-dark">In progress</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<a class="btn btn-sm btn-outline-primary"
|
||||
href="{% url 'atlas:collection_shared_attempt_overview' attempt.pk %}">
|
||||
View attempt
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-info">
|
||||
No collection attempts have been shared with you yet.
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -2,135 +2,155 @@
|
||||
{% load static %}
|
||||
|
||||
{% block content %}
|
||||
<div class="d-flex flex-wrap justify-content-between align-items-start gap-3 mb-3">
|
||||
<div>
|
||||
<h2 class="h4 mb-1">Supervision</h2>
|
||||
<p class="text-muted small mb-0">
|
||||
Collection attempts shared with you as author, marker, supervisor or by direct invitation.
|
||||
<strong>{{ total_attempts }}</strong> attempt{{ total_attempts|pluralize }} found.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# ---- Filter / group toolbar ---- #}
|
||||
<form method="get" class="row g-2 align-items-end mb-4">
|
||||
<div class="col-12 col-md-auto">
|
||||
<label class="form-label small mb-1">Group by</label>
|
||||
<div class="btn-group d-flex" role="group">
|
||||
<a href="?group_by=user&date_from={{ date_from }}&date_to={{ date_to }}"
|
||||
class="btn btn-sm {% if group_by == 'user' %}btn-primary{% else %}btn-outline-secondary{% endif %}">
|
||||
By learner
|
||||
</a>
|
||||
<a href="?group_by=collection&date_from={{ date_from }}&date_to={{ date_to }}"
|
||||
class="btn btn-sm {% if group_by == 'collection' %}btn-primary{% else %}btn-outline-secondary{% endif %}">
|
||||
By collection
|
||||
</a>
|
||||
<div class="d-flex flex-wrap justify-content-between align-items-start gap-3 mb-3">
|
||||
<div>
|
||||
<h2 class="h4 mb-1">Supervision</h2>
|
||||
<p class="text-muted small mb-0">
|
||||
Collection attempts shared with you as author, marker, supervisor or by direct invitation.
|
||||
<strong>{{ total_attempts }}</strong> attempt{{ total_attempts|pluralize }} found.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-auto">
|
||||
<label class="form-label small mb-1" for="date_from">From</label>
|
||||
<input type="date" id="date_from" name="date_from" class="form-control form-control-sm"
|
||||
value="{{ date_from }}">
|
||||
</div>
|
||||
<div class="col-12 col-md-auto">
|
||||
<label class="form-label small mb-1" for="date_to">To</label>
|
||||
<input type="date" id="date_to" name="date_to" class="form-control form-control-sm"
|
||||
value="{{ date_to }}">
|
||||
</div>
|
||||
<input type="hidden" name="group_by" value="{{ group_by }}">
|
||||
<div class="col-12 col-md-auto">
|
||||
<button type="submit" class="btn btn-sm btn-outline-primary">Apply filter</button>
|
||||
<a href="{% url 'atlas:collection_supervision' %}" class="btn btn-sm btn-outline-secondary ms-1">Clear</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{# ---- Grouped results ---- #}
|
||||
{% if groups %}
|
||||
{% for group_label, attempt_rows in groups %}
|
||||
<div class="mb-4">
|
||||
<h5 class="h6 fw-semibold border-bottom pb-1 mb-2">
|
||||
{% if group_by == 'user' %}
|
||||
<i class="bi bi-person me-1" aria-hidden="true"></i>
|
||||
{% else %}
|
||||
<i class="bi bi-collection me-1" aria-hidden="true"></i>
|
||||
{% endif %}
|
||||
{{ group_label }}
|
||||
<span class="badge bg-secondary fw-normal ms-1">{{ attempt_rows|length }} attempt{{ attempt_rows|length|pluralize }}</span>
|
||||
</h5>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-sm align-middle mb-0">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
{% if group_by == 'user' %}
|
||||
<th>Collection</th>
|
||||
{% else %}
|
||||
<th>Learner</th>
|
||||
{% endif %}
|
||||
<th>Started</th>
|
||||
<th>Ended</th>
|
||||
<th>Status</th>
|
||||
<th>Progress</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for attempt, collection in attempt_rows %}
|
||||
<tr>
|
||||
{% if group_by == 'user' %}
|
||||
<td>
|
||||
{% if collection %}
|
||||
{{ collection.name }}
|
||||
{% else %}
|
||||
<span class="text-muted">Unknown</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% else %}
|
||||
<td>
|
||||
{% if attempt.user_user %}
|
||||
{{ attempt.user_user.get_full_name|default:attempt.user_user.username }}
|
||||
{% if attempt.user_user.email %}
|
||||
<br><span class="text-muted small">{{ attempt.user_user.email }}</span>
|
||||
{% endif %}
|
||||
{% elif attempt.cid_user %}
|
||||
CID {{ attempt.cid_user.cid }}
|
||||
{% if attempt.cid_user.name %}<br><span class="text-muted small">{{ attempt.cid_user.name }}</span>{% endif %}
|
||||
{% else %}
|
||||
<span class="text-muted">Unknown</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endif %}
|
||||
<td class="small text-nowrap">{{ attempt.start_time|default:"-" }}</td>
|
||||
<td class="small text-nowrap">{{ attempt.end_time|default:"-" }}</td>
|
||||
<td>
|
||||
{% if attempt.completed %}
|
||||
<span class="badge bg-success">Completed</span>
|
||||
{% else %}
|
||||
<span class="badge bg-warning text-dark">In progress</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if attempt.user_user_id %}
|
||||
<a class="btn btn-sm btn-outline-primary"
|
||||
href="{% url 'atlas:collection_history_user' exam_id=collection.pk user_pk=attempt.user_user_id %}">
|
||||
View attempt
|
||||
</a>
|
||||
{% else %}
|
||||
<a class="btn btn-sm btn-outline-primary"
|
||||
href="{% url 'atlas:collection_shared_attempt_overview' attempt.pk %}">
|
||||
View attempt
|
||||
</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{# ---- Filter / group toolbar ---- #}
|
||||
<form method="get" class="row g-2 align-items-end mb-4">
|
||||
{# Group by #}
|
||||
<div class="col-12 col-md-auto">
|
||||
<label class="form-label small mb-1">Group by</label>
|
||||
<div class="btn-group d-flex" role="group">
|
||||
<a href="?group_by=user&date_from={{ date_from }}&date_to={{ date_to }}&q={{ q }}{% if supervisor_only %}&supervisor_only=1{% endif %}"
|
||||
class="btn btn-sm {% if group_by == 'user' %}btn-primary{% else %}btn-outline-secondary{% endif %}">
|
||||
By learner
|
||||
</a>
|
||||
<a href="?group_by=collection&date_from={{ date_from }}&date_to={{ date_to }}&q={{ q }}{% if supervisor_only %}&supervisor_only=1{% endif %}"
|
||||
class="btn btn-sm {% if group_by == 'collection' %}btn-primary{% else %}btn-outline-secondary{% endif %}">
|
||||
By collection
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="alert alert-info">
|
||||
No collection attempts have been shared with you yet. Try adjusting the date filter.
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Learner search #}
|
||||
<div class="col-12 col-md-3">
|
||||
<label class="form-label small mb-1" for="q">Search learner</label>
|
||||
<input type="text" id="q" name="q" class="form-control form-control-sm"
|
||||
placeholder="Name, username or email…" value="{{ q }}">
|
||||
</div>
|
||||
|
||||
{# Date range #}
|
||||
<div class="col-12 col-md-auto">
|
||||
<label class="form-label small mb-1" for="date_from">From</label>
|
||||
<input type="date" id="date_from" name="date_from" class="form-control form-control-sm"
|
||||
value="{{ date_from }}">
|
||||
</div>
|
||||
<div class="col-12 col-md-auto">
|
||||
<label class="form-label small mb-1" for="date_to">To</label>
|
||||
<input type="date" id="date_to" name="date_to" class="form-control form-control-sm"
|
||||
value="{{ date_to }}">
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="group_by" value="{{ group_by }}">
|
||||
|
||||
{# Supervisor-only toggle (only visible when user is a supervisor) #}
|
||||
{% if is_supervisor %}
|
||||
<div class="col-12 col-md-auto d-flex align-items-end">
|
||||
<div class="form-check form-switch mb-0">
|
||||
<input class="form-check-input" type="checkbox" role="switch"
|
||||
id="supervisor_only" name="supervisor_only" value="1"
|
||||
{% if supervisor_only %}checked{% endif %}
|
||||
onchange="this.form.submit()">
|
||||
<label class="form-check-label small" for="supervisor_only">My trainees only</label>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="col-12 col-md-auto">
|
||||
<button type="submit" class="btn btn-sm btn-outline-primary">Apply</button>
|
||||
<a href="{% url 'atlas:collection_supervision' %}" class="btn btn-sm btn-outline-secondary ms-1">Clear</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{# ---- Grouped results ---- #}
|
||||
{% if groups %}
|
||||
{% for group_label, attempt_rows in groups %}
|
||||
<div class="mb-4">
|
||||
<h5 class="h6 fw-semibold border-bottom pb-1 mb-2">
|
||||
{% if group_by == 'user' %}
|
||||
<i class="bi bi-person me-1" aria-hidden="true"></i>
|
||||
{% else %}
|
||||
<i class="bi bi-collection me-1" aria-hidden="true"></i>
|
||||
{% endif %}
|
||||
{{ group_label }}
|
||||
<span class="badge bg-secondary fw-normal ms-1">{{ attempt_rows|length }} attempt{{ attempt_rows|length|pluralize }}</span>
|
||||
</h5>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-sm align-middle mb-0">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
{% if group_by == 'user' %}
|
||||
<th>Collection</th>
|
||||
{% else %}
|
||||
<th>Learner</th>
|
||||
{% endif %}
|
||||
<th>Started</th>
|
||||
<th>Ended</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for attempt, collection in attempt_rows %}
|
||||
<tr>
|
||||
{% if group_by == 'user' %}
|
||||
<td>
|
||||
{% if collection %}{{ collection.name }}{% else %}<span class="text-muted">Unknown</span>{% endif %}
|
||||
</td>
|
||||
{% else %}
|
||||
<td>
|
||||
{% if attempt.user_user %}
|
||||
{{ attempt.user_user.get_full_name|default:attempt.user_user.username }}
|
||||
{% if attempt.user_user.email %}
|
||||
<br><span class="text-muted small">{{ attempt.user_user.email }}</span>
|
||||
{% endif %}
|
||||
{% elif attempt.cid_user %}
|
||||
CID {{ attempt.cid_user.cid }}
|
||||
{% if attempt.cid_user.name %}<br><span class="text-muted small">{{ attempt.cid_user.name }}</span>{% endif %}
|
||||
{% else %}
|
||||
<span class="text-muted">Unknown</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endif %}
|
||||
<td class="small text-nowrap">{{ attempt.start_time|default:"-" }}</td>
|
||||
<td class="small text-nowrap">{{ attempt.end_time|default:"-" }}</td>
|
||||
<td>
|
||||
{% if attempt.completed %}
|
||||
<span class="badge bg-success">Completed</span>
|
||||
{% else %}
|
||||
<span class="badge bg-warning text-dark">In progress</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if attempt.user_user_id and collection %}
|
||||
<a class="btn btn-sm btn-outline-primary"
|
||||
href="{% url 'atlas:collection_history_user' exam_id=collection.pk user_pk=attempt.user_user_id %}">
|
||||
View attempt
|
||||
</a>
|
||||
{% else %}
|
||||
<a class="btn btn-sm btn-outline-primary"
|
||||
href="{% url 'atlas:collection_shared_attempt_overview' attempt.pk %}">
|
||||
View attempt
|
||||
</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="alert alert-info">
|
||||
No collection attempts found. Try adjusting the filters.
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user