improve case user answer management (and fix small bug)

This commit is contained in:
Ross
2024-11-18 10:44:27 +00:00
parent 9c69792e87
commit 00323cc6bd
7 changed files with 125 additions and 30 deletions
@@ -0,0 +1,18 @@
# Generated by Django 5.0.2 on 2024-11-18 09:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('atlas', '0063_casecollection_results_supervisor_visible'),
]
operations = [
migrations.AddField(
model_name='casecollection',
name='exam_open_access',
field=models.BooleanField(default=False, help_text='Set to true if you want any registered user to be able to take the exam.'),
),
]
@@ -33,6 +33,7 @@
<p>View as a viva collection <a href='{% url "atlas:collection_viva" collection.pk %}'>here</a>
{% else %}
<p>This collection will be available to view/take <a href='{{collection.get_take_url}}'>here</a> (when active)
<p>Review collection <a href='{% url "atlas:collection_viva" collection.pk %}'>here</a>
{% endif %}
{% if can_edit %}
@@ -59,6 +60,13 @@
hx-swap="outerHTML"
hx-confirm="Are you sure you want to reset all answers? This action cannot be undone."
>Reset all answers</button>
<button title="This will specific user answers and attempts"
hx-post="{% url 'atlas:collection_reset_answers_user_list' collection.pk %}"
hx-swap="innerHTML"
hx-target="#user-list"
>Reset user answers</button>
<div id="user-list"></div>
</details>
{% endif %}
@@ -0,0 +1,10 @@
{% for cid_user_exam in cid_users %}
<button title="This will clear the user answers and attempts"
hx-post="{% url 'atlas:collection_reset_answers_user' collection.pk cid_user_exam.user_user.id %}"
hx-swap="outerHTML"
hx-confirm="Are you sure you want to reset answers for the user? This action cannot be undone."
>{{cid_user_exam.user_user}}</button>
{% endfor %}
+37 -27
View File
@@ -58,12 +58,14 @@
<div class="sticky-top">
<h3>Current Case</h3>
<div id="loading-case">Waiting for case to load in linked window.<br/> If you are seeing this message you probably need to open the viewer window and reload the case.</div>
<div id="current-case-title">None</div>
<div id="current-case-series"></div>
<div id="current-case-history"></div>
<div id="current-case-discussion"></div>
<div id="current-case-report"></div>
<div id="case-details">
<div id="loading-case">Waiting for case to load in linked window.<br/> If you are seeing this message you probably need to open the viewer window and reload the case.</div>
<div id="current-case-title">None</div>
<div id="current-case-series"></div>
<div id="current-case-history"></div>
<div id="current-case-discussion"></div>
<div id="current-case-report"></div>
</div>
</div>
<iframe id="viewer" style="width: 100%; height: 500px; border: none"></iframe>
@@ -106,16 +108,16 @@
$('#loading-case').show()
$("#open-viewer").addClass("flash-button");
$('#current-case-title').text("Case: "+c.data('title'));
$("#current-case-history").text("History: "+case_details['history']);
$("#current-case-discussion").text("Discussion: "+case_details['discussion']);
$("#current-case-report").text("Report: "+case_details['report']);
$('#current-case-title').html("<span class='title'>Case:</span> "+c.data('title'));
$("#current-case-history").html("<span class='title'>History:</span> "+case_details['history']);
$("#current-case-discussion").html("<span class='title'>Discussion:</span> "+case_details['discussion']);
$("#current-case-report").html("<span class='title'>Report:</span> "+case_details['report']);
console.log($(this).data('type'))
if ($(this).data('type') == 'case') {
$('#current-case-series').text("Series: All");
$('#current-case-series').html("<span class='title'>Series:</span> All");
} else {
$('#current-case-series').text("Series: " + $(this).data('series'));
$('#current-case-series').html("<span class='title'>Series:</span> " + $(this).data('series'));
}
bc.postMessage({"type": "open", "url" : url});
//if (win2 == false || win2.closed) {
@@ -153,25 +155,33 @@
{% endblock %}
{% block css %}
<style type="text/css">
#loading-case {
display: none;
color: red;
}
@keyframes glowing {
0% {
box-shadow: 0 0 20px #a600ff;
}
50% {
box-shadow: 0 0 40px #52057b;
}
100% {
box-shadow: 0 0 20px #a600ff;
}
}
.flash-button {
animation: glowing 1300ms infinite;
}
@keyframes glowing {
0% {
box-shadow: 0 0 20px #a600ff;
}
50% {
box-shadow: 0 0 40px #52057b;
}
100% {
box-shadow: 0 0 20px #a600ff;
}
}
.flash-button {
animation: glowing 1300ms infinite;
}
#case-details {
padding-bottom: 20px;
}
.title {
font-weight: bold;
}
</style>
{% endblock css %}
+10
View File
@@ -148,6 +148,16 @@ urlpatterns = [
views.collection_reset_answers,
name="collection_reset_answers",
),
path(
"collection/<int:exam_id>/reset_answers_user_list",
views.collection_reset_answers_user_list,
name="collection_reset_answers_user_list",
),
path(
"collection/<int:exam_id>/<int:user_id>/reset_answers",
views.collection_reset_answers_user,
name="collection_reset_answers_user",
),
#path(
# "question_schemas_preset",
# views.question_schemas_preset,
+38 -1
View File
@@ -1682,7 +1682,12 @@ def collection_take_start(request, pk):
"""
collection = get_object_or_404(CaseCollection, pk=pk)
valid_user = (collection.check_logged_in_user(request),)
valid_user = collection.check_logged_in_user(request)
# for now we only allow registered users....
if not valid_user:
raise PermissionDenied
cid_exam = None
if collection.collection_type == "REV" or valid_user:
@@ -2901,6 +2906,38 @@ def collection_question_schemas(request, exam_id: int):
},
)
def collection_reset_answers_user_list(request, exam_id: int):
if request.htmx:
collection = get_object_or_404(CaseCollection, pk=exam_id)
cid_users = collection.cid_users.all()
if cid_users:
return render(request, "atlas/collection_reset_answers_user_list.html", {"collection": collection, "cid_users": cid_users})
else:
return HttpResponse("No user answers.")
else:
raise Http404("Invalid request")
def collection_reset_answers_user(request, exam_id: int, user_id: int):
if request.htmx:
collection = get_object_or_404(CaseCollection, pk=exam_id)
# Select all case details (answers are linked to these)
case_details = collection.casedetail_set.all().prefetch_related()
# Delete all answers
for case in case_details:
user_answers = case.userreportanswer_set.filter(user_id=user_id)
user_answers.delete()
collection.cid_users.filter(user_user_id=user_id).delete()
collection.exam_user_status.filter(cid_user_exam__user_user_id=user_id).delete()
return HttpResponse("Success")
else:
raise Http404("Invalid request")
def collection_reset_answers(request, exam_id: int):
if request.htmx:
+4 -2
View File
@@ -613,6 +613,8 @@ class ExamOrCollectionGenericBase(models.Model, AuthorMixin):
default=False,
)
exam_open_access = models.BooleanField(default=False, help_text="Set to true if you want any registered user to be able to take the exam.")
class Meta:
abstract = True
@@ -718,6 +720,8 @@ class ExamOrCollectionGenericBase(models.Model, AuthorMixin):
return True
if cid is None and user_id is None:
if user.is_anonymous:
return False
if user is not None:
user_id = user.id
else:
@@ -869,8 +873,6 @@ class ExamBase(ExamOrCollectionGenericBase):
default=False,
)
exam_open_access = models.BooleanField(default=False, help_text="Set to true if you want any registered user to be able to take the exam.")
# randomise_question_order = models.BooleanField(
# help_text="If an exam should randomise the order of questions in RTS.",
# )