diff --git a/atlas/templates/atlas/collection_take_overview.html b/atlas/templates/atlas/collection_take_overview.html index 3ddd3e9b..893ceba3 100644 --- a/atlas/templates/atlas/collection_take_overview.html +++ b/atlas/templates/atlas/collection_take_overview.html @@ -1,78 +1,139 @@ {% extends 'base.html' %} {% block content %} - {% if cid is not None %} - CID: {{cid}} - {% endif %} - -

Collection: {{collection.name}} - - {% if collection.in_review_mode or cid_user_exam.completed %} - REVIEW - {% endif %} -

- - - {% if not collection.review_only %} - {{answer_count}} out of {{collection_length}} cases answered. Click to go to case. - {% endif %} -
- +
+
+

+ {{ collection.name }} + {% if collection.in_review_mode or cid_user_exam.completed %} + Review + {% endif %} +

+
+ {% if cid is not None %} + CID: {{ cid }} + {% else %} + Your collection overview + {% endif %} +
+
+
+
+
Progress
+ {% if not collection.review_only %} +
{{ answer_count }} / {{ collection_length }} answered
+
+
+
+ {% else %} +
Review-only collection
+ {% endif %} +
Started: {{ cid_user_exam.start_time }}
+
+
+
+ {% for question, answer, self_review in question_answer_tuples %} +
+
+
+
+ Case {{ forloop.counter }}{% if collection.show_title_post %}: {{ question.case.title|default:question.case.pk|truncatechars:70 }}{% endif %} + {% if answer and answer.completed or cid_user_exam.completed %} + Completed + {% elif answer %} + Saved + {% else %} + Not answered + {% endif %} + {% if self_review %} + Self review added + {% endif %} +
+ {% if collection.show_title_post %} +
+ {{ question.case }} +
+ {% endif %} +
+ +
- Start time: {{cid_user_exam.start_time}} + {% if self_review %} +
+
Your self reviews
+
+ {% for review in self_review %} + + View review {{ forloop.counter }} + + + Edit review {{ forloop.counter }} + + {% endfor %} +
+
+ {% endif %} + {% if not collection.review_only %} + {% if answer %} +
+ Preview saved answer/report +
+ {% if answer.answer %} + {{ answer.answer|linebreaksbr }} + {% else %} + {{ answer.json_answer }} + {% endif %} +
+
+ {% endif %} + {% endif %} +
+ {% endfor %} +
{% if not collection.review_only and not cid_user_exam.completed %} -

Completed: {{cid_user_exam.completed}}

-
- -
+
+
+
+
Ready to submit this session?
+
Completed: {{ cid_user_exam.completed }}
+
+
+ +
+
+
{% endif %} diff --git a/atlas/templates/atlas/partials/_collection_case_jump.html b/atlas/templates/atlas/partials/_collection_case_jump.html index 5ffb707c..52201bc1 100644 --- a/atlas/templates/atlas/partials/_collection_case_jump.html +++ b/atlas/templates/atlas/partials/_collection_case_jump.html @@ -1,11 +1,31 @@ -{% for cd in casedetails %} - {% with idx=forloop.counter0 %} - {% if cid %} - - {% else %} - - {% endif %} - Case {{ forloop.counter }}: {{ cd.case.title|default:cd.case.pk|truncatechars:60 }} - - {% endwith %} +{% for item in jump_items %} + +{% empty %} + {% endfor %} diff --git a/atlas/templates/atlas/partials/_self_review_block.html b/atlas/templates/atlas/partials/_self_review_block.html index 94e50b62..4c875879 100644 --- a/atlas/templates/atlas/partials/_self_review_block.html +++ b/atlas/templates/atlas/partials/_self_review_block.html @@ -24,20 +24,30 @@
Updated: {{ review.review_update_date|date:"Y-m-d H:i" }}
-
- + + View + + + + Edit - -
diff --git a/atlas/templates/atlas/partials/_selfreview_detail_embed.html b/atlas/templates/atlas/partials/_selfreview_detail_embed.html new file mode 100644 index 00000000..70a63dc1 --- /dev/null +++ b/atlas/templates/atlas/partials/_selfreview_detail_embed.html @@ -0,0 +1,52 @@ +
+
+
+

Self Review

+ {{ user_exam.exam }} +
+
+
Case: {{ case }}
+ +
+
+
+
Findings
+
{{ review.findings|default:"-" }}/5
+
+
+
+
+
Interpretation
+
{{ review.interpretation|default:"-" }}/5
+
+
+
+ +
+
Comments
+
+ {% if review.comments %} + {{ review.comments|linebreaksbr }} + {% else %} + No comments added. + {% endif %} +
+
+ +
+ Updated: {{ review.review_update_date }} +
+ + +
+
+
diff --git a/atlas/templates/atlas/selfreview_detail.html b/atlas/templates/atlas/selfreview_detail.html new file mode 100644 index 00000000..22175ebe --- /dev/null +++ b/atlas/templates/atlas/selfreview_detail.html @@ -0,0 +1,52 @@ +{% extends "base.html" %} + +{% block content %} +
+
+
+

Self Review

+ {{ user_exam.exam }} +
+
+
Case: {{ case }}
+
+
+
+
Findings
+
{{ review.findings|default:"-" }}/5
+
+
+
+
+
Interpretation
+
{{ review.interpretation|default:"-" }}/5
+
+
+
+
+
Comments
+
+ {% if review.comments %} + {{ review.comments|linebreaksbr }} + {% else %} + No comments added. + {% endif %} +
+
+
+ Created: {{ review.review_date }}
+ Updated: {{ review.review_update_date }} +
+ +
+
+
+{% endblock %} diff --git a/atlas/urls.py b/atlas/urls.py index d7b96b01..099bb9a2 100755 --- a/atlas/urls.py +++ b/atlas/urls.py @@ -25,6 +25,11 @@ urlpatterns = [ views.SelfReviewUpdate.as_view(), name="self_review_update", ), + path( + "self_review///view/", + views.SelfReviewDetail.as_view(), + name="self_review_detail", + ), path( "self_review///delete/", views.SelfReviewDelete.as_view(), diff --git a/atlas/views.py b/atlas/views.py index 45a8f7be..93be9c9a 100755 --- a/atlas/views.py +++ b/atlas/views.py @@ -1884,11 +1884,94 @@ def collection_case_jump_partial(request, pk: int): cid = request.GET.get('cid') passcode = request.GET.get('passcode') + try: + cid_value = int(cid) if cid is not None else None + except Exception: + cid_value = None + + cid_user_exam = collection.get_or_create_cid_user_exam( + cid=cid_value, + user_user=request.user, + ) + + if cid_value is not None: + answers = CidReportAnswer.objects.filter(cid=cid_value, question__in=casedetails) + else: + answers = UserReportAnswer.objects.filter(user=request.user, question__in=casedetails) + + answer_case_ids = { + ans.question.case_id + for ans in answers + if (ans.answer or ans.json_answer) + } + + latest_reviews = ( + cid_user_exam.selfreview_set.filter(case__in=[cd.case for cd in casedetails]) + .select_related("case") + .order_by("case_id", "-review_update_date") + ) + + latest_review_by_case = {} + for review in latest_reviews: + if review.case_id not in latest_review_by_case: + latest_review_by_case[review.case_id] = review + + jump_items = [] + for idx, cd in enumerate(casedetails): + if cid is not None: + case_url = reverse( + "atlas:collection_case_view_take", + kwargs={"pk": collection.pk, "case_number": idx, "cid": cid, "passcode": passcode}, + ) + answer_url = case_url + else: + case_url = reverse( + "atlas:collection_case_view_take_user", + kwargs={"pk": collection.pk, "case_number": idx}, + ) + answer_url = reverse( + "atlas:collection_case_view_take_user_answers", + kwargs={"pk": collection.pk, "case_number": idx}, + ) + + add_url = reverse( + "atlas:add_self_review", + kwargs={"user_exam_id": cid_user_exam.id, "case_id": cd.case_id}, + ) + + review = latest_review_by_case.get(cd.case_id) + review_view_url = None + review_edit_url = None + if review is not None: + review_view_url = reverse( + "atlas:self_review_detail", + kwargs={"user_exam_id": cid_user_exam.id, "case_id": cd.case_id, "pk": review.id}, + ) + review_edit_url = reverse( + "atlas:self_review_update", + kwargs={"user_exam_id": cid_user_exam.id, "case_id": cd.case_id, "pk": review.id}, + ) + + jump_items.append( + { + "idx": idx, + "cd": cd, + "case_url": case_url, + "answer_url": answer_url, + "self_review_add_url": add_url, + "self_review_view_url": review_view_url, + "self_review_edit_url": review_edit_url, + "has_answer": cd.case_id in answer_case_ids, + "has_self_review": review is not None, + } + ) + html = render_to_string( 'atlas/partials/_collection_case_jump.html', { 'collection': collection, 'casedetails': casedetails, + 'jump_items': jump_items, 'current': current, 'cid': cid, 'passcode': passcode, @@ -5644,6 +5727,37 @@ class SelfReviewDelete(DeleteView): return self.user_exam.exam.get_case_take_url(self.case) +class SelfReviewDetail(DetailView): + """Read-only self-review view for a specific user exam and case. + + This is the default viewing mode for self reviews. Add ``?embed=1`` to + render the compact sidebar-friendly template. + """ + + model = SelfReview + + def get_template_names(self): + if self.request.GET.get("embed") == "1": + return ["atlas/partials/_selfreview_detail_embed.html"] + return ["atlas/selfreview_detail.html"] + + def get_object(self, queryset=None): + return get_object_or_404( + SelfReview, + pk=self.kwargs["pk"], + user_exam_id=self.kwargs["user_exam_id"], + case_id=self.kwargs["case_id"], + ) + + def get_context_data(self, **kwargs): + context = super(SelfReviewDetail, self).get_context_data(**kwargs) + context["review"] = self.object + context["user_exam"] = self.object.user_exam + context["case"] = self.object.case + context["embed"] = self.request.GET.get("embed") == "1" + return context + + class SelfReviewUpdate(UpdateView): """Edit an existing self-review entry for a case attempt.