From d5b3d00b3c573645e657a352f6c67ea1c4bc8b74 Mon Sep 17 00:00:00 2001 From: Ross Date: Sun, 16 May 2021 13:30:27 +0100 Subject: [PATCH] . --- anatomy/static/css/anatomy.css | 4 ++ generic/models.py | 5 +- rad/urls.py | 1 + rad/views.py | 51 ++++++++++++++----- .../rapids/question_display_block.html | 12 +++-- rapids/views.py | 6 ++- templates/view_feedback.html | 3 +- 7 files changed, 62 insertions(+), 20 deletions(-) diff --git a/anatomy/static/css/anatomy.css b/anatomy/static/css/anatomy.css index 1e96d449..3d9314cf 100644 --- a/anatomy/static/css/anatomy.css +++ b/anatomy/static/css/anatomy.css @@ -481,4 +481,8 @@ td.user-answer-score-2::after { .proposed-answer { color: darkblue + } + + .notes .complete { + color: darkslategray; } \ No newline at end of file diff --git a/generic/models.py b/generic/models.py index 4c8175d0..d662be79 100644 --- a/generic/models.py +++ b/generic/models.py @@ -126,4 +126,7 @@ class QuestionNote(models.Model): return "{} [{}] {} / {}".format(self.author, self.created_on, self.note_type, self.note) def get_absolute_url(self): - return "/" \ No newline at end of file + return "/" + + def get_object_url(self): + return self.question.get_absolute_url() \ No newline at end of file diff --git a/rad/urls.py b/rad/urls.py index 2474c9c9..0ef32119 100644 --- a/rad/urls.py +++ b/rad/urls.py @@ -57,6 +57,7 @@ urlpatterns = [ path("exam/submit", views.exam_submit, name="global_exam_answers_submit"), #path('', include('generic.urls')), path("feedback//", views.AddQuestionNote.as_view(), name="feedback_create"), + path("feedback/note//complete", views.feedback_mark_complete, name="feedback_mark_complete"), #path("feedback/", views.AddQuestionNote.as_view(), name="feedback"), path("feedback/answer", views.answer_suggestion_submit, name="answer_suggestion_submit"), path("feedback/answer/confirm", views.answer_suggestion_confirm, name="answer_suggestion_confirm"), diff --git a/rad/views.py b/rad/views.py index 1d1687f7..6936bdc9 100644 --- a/rad/views.py +++ b/rad/views.py @@ -1,3 +1,4 @@ +from django.core.exceptions import PermissionDenied from django.shortcuts import render, get_object_or_404, redirect from django.views.decorators.csrf import csrf_exempt from django import forms @@ -23,7 +24,7 @@ from django.http import Http404, JsonResponse from django.http import HttpResponseRedirect, HttpResponse -from physics.models import CidUserAnswer as PhysicsCidUserAnswer +from physics.models import CidUserAnswer as PhysicsCidUserAnswer, Question from physics.models import Exam as PhysicsExam from anatomy.models import CidUserAnswer as AnatomyCidUserAnswer @@ -48,6 +49,9 @@ from generic.models import QuestionNote import json +def feedback_checker(user): + return user.groups.filter(name="feedback_checker").exists() + @login_required def profile(request): @@ -162,6 +166,22 @@ def feedback_create(request, question_type, pk): return JsonResponse({"success": False, "error": "Invalid exam type"}) +def get_question_and_content_type(pk, question_type): + if question_type == "rapid": + question = Rapid + content_type = ContentType.objects.get(model="rapid") + elif question_type == "anatomy": + question = AnatomyQuestion + content_type = ContentType.objects.get(model="anatomyquestion") + elif question_type == "long": + question = Long + content_type = ContentType.objects.get(model="long") + else: + raise PermissionError() + + return question, content_type + + class AddQuestionNote(CreateView): model = QuestionNote form_class = QuestionNoteForm @@ -178,22 +198,24 @@ class AddQuestionNote(CreateView): def get_initial(self): pk = self.kwargs["pk"] question_type = self.kwargs["question_type"] - if question_type == "rapid": - question = Rapid - content_type = ContentType.objects.get(model="rapid") - elif question_type == "anatomy": - question = AnatomyQuestion - content_type = ContentType.objects.get(model="anatomyquestion") - elif question_type == "long": - question = Long - content_type = ContentType.objects.get(model="long") - else: - raise PermissionError() + + question, content_type = get_question_and_content_type(pk, question_type) get_object_or_404(question, pk=pk) return { "content_type" : content_type, "object_id" : pk } +@login_required +def feedback_mark_complete(request, pk): + q = get_object_or_404(QuestionNote, pk=pk) + + if request.user not in q.question.author.all() and not request.user.groups.filter(name="feedback_checker").exists(): + raise PermissionDenied() + + q.complete = True + q.save() + return redirect(q.get_object_url()) + @csrf_exempt def answer_suggestion_submit(request): if request.is_ajax and request.method == "POST": @@ -249,10 +271,11 @@ def answer_suggestion_confirm(request): return JsonResponse({"success": True, "error": "Answer changed"}) @login_required -def view_feedback(request, pk): +@user_passes_test(feedback_checker) +def view_feedback(request): # exam = get_object_or_404(Exam, pk=pk) - feedback_notes = QuestionNote.objects.all() + feedback_notes = QuestionNote.objects.filter(complete=False) return render( request, diff --git a/rapids/templates/rapids/question_display_block.html b/rapids/templates/rapids/question_display_block.html index f0d7ad93..fc84ef9d 100755 --- a/rapids/templates/rapids/question_display_block.html +++ b/rapids/templates/rapids/question_display_block.html @@ -37,6 +37,8 @@

+ + {% if view_feedback %} Notes:
    {% for note in question.rapid_notes.all %} @@ -46,13 +48,17 @@ {% endfor %}
Anon Notes: -
    +
      {% for note in question.anon_notes.all %} -
    • - {{ note.created_on }} by {{ note.author }}: {{ note.note }} +
    • + {{ note.created_on }} by {{ note.author }}: {{note.note_type}} / {{ note.note }} + {% if not note.complete %} + (Mark complete) + {% endif %}
    • {% endfor %}
    + {% endif %}
diff --git a/rapids/views.py b/rapids/views.py index 7b97dabe..9b87b875 100755 --- a/rapids/views.py +++ b/rapids/views.py @@ -101,9 +101,13 @@ def question_detail(request, pk): # if request.user not in rapid.author.all(): # raise PermissionDenied + view_feedback = False + if request.user.groups.filter(name="rapid_checker").exists() or request.user.groups.filter(name="feedback_checker").exists() or request.user in rapid.author.all(): + view_feedback = True + # logging.debug(rapid.rapid_notes.first()) # logging.debug(rapid.subspecialty.first().name.all()) - return render(request, "rapids/question_detail.html", {"question": rapid}) + return render(request, "rapids/question_detail.html", {"question": rapid, "view_feedback" : view_feedback}) @login_required diff --git a/templates/view_feedback.html b/templates/view_feedback.html index 63f8435b..c58740cf 100644 --- a/templates/view_feedback.html +++ b/templates/view_feedback.html @@ -3,9 +3,10 @@ {% block content %}

Feedback

+ Displays a list of feedback reports yet to be acted upon
    {% for note in notes %} -
  • {{note.content_type }}: {{note.note_type}} / {{note.note}} [{{note.complete}}]
  • +
  • {{note.content_type }}: {{note.note_type}} / {{note.note}}
  • {% endfor %}