diff --git a/atlas/forms.py b/atlas/forms.py index 61b9e03b..dc8dbfd5 100755 --- a/atlas/forms.py +++ b/atlas/forms.py @@ -736,13 +736,17 @@ class AnswerJSONForm(Form): options = {} ) + +class SvelteJSONEditorWidgetOverride(SvelteJSONEditorWidget): + template_name = "atlas/svelte_jsoneditor_widget_override.html" + class CaseDetailForm(ModelForm): class Meta: model = CaseDetail - fields = ["sort_order", "question_schema", "question_answers"]#, "user"] + fields = ["question_schema", "question_answers"]#, "user"] widgets = { - "question_schema": SvelteJSONEditorWidget(), - "question_answers": SvelteJSONEditorWidget(), + "question_schema": SvelteJSONEditorWidgetOverride(), + "question_answers": SvelteJSONEditorWidgetOverride(), } \ No newline at end of file diff --git a/atlas/models.py b/atlas/models.py index aeaefee8..44a3dad7 100644 --- a/atlas/models.py +++ b/atlas/models.py @@ -968,6 +968,9 @@ class CaseDetail(models.Model): class Meta: ordering = ("sort_order",) + def get_question_schema(self): + return json.dumps(self.question_schema) + class BaseReportAnswer(models.Model): question = models.ForeignKey(CaseDetail, on_delete=models.CASCADE) diff --git a/atlas/templates/atlas/collection_case_detail.html b/atlas/templates/atlas/collection_case_detail.html index 941ea1ff..320eee0d 100644 --- a/atlas/templates/atlas/collection_case_detail.html +++ b/atlas/templates/atlas/collection_case_detail.html @@ -5,7 +5,33 @@ {% block content %}

{{case_detail.collection.name}} / {{case_detail.case.pk}}

-

See https://django-jsonform.readthedocs.io/en/latest/guide/inputs.html for formatting

+

Collection: {{case_detail.collection.name}}, Case: {{case_detail.case.title}}

+ +

This form allows you to add questions to a case. A example of how the quesiton will be displayed is shown below.

+

If answers are supplied the question will be automarked

+ +

See https://django-jsonform.readthedocs.io/en/latest/guide/inputs.html for formatting

+ + Import schema from: + + + +
+
+
Question schemas
+ +
+
+ ... +
+
{% csrf_token %} @@ -13,12 +39,14 @@
-

Blank form

+{% comment %}

Blank form

{{ blank_form}} -
+ {% endcomment %} + +

Question display

+ This shows the form as it will be displayed (with the correct answers). If you wish to edit a correct answer you can change it below. -

Correct answers

{% csrf_token %} {{example_form}} @@ -31,6 +59,21 @@ {% comment %} {{ example_form.media }} {% endcomment %} - + + {% endblock %} \ No newline at end of file diff --git a/atlas/templates/atlas/collection_question_schemas.html b/atlas/templates/atlas/collection_question_schemas.html new file mode 100644 index 00000000..10fd3c2d --- /dev/null +++ b/atlas/templates/atlas/collection_question_schemas.html @@ -0,0 +1,50 @@ + +{% load static %} +{% comment %} + {% endcomment %} +
    + {% for case_detail in case_details %} + +
  1. +

    Case: {{ case_detail.case.title }}

    + + {% if case_detail.question_schema %} + +
    Schema: +
    {{ case_detail.question_schema }}
    +
    +
    + {% else %} +

    No question(s)

    + {% endif %} + +
  2. + + {% endfor %} +
+ + + + \ No newline at end of file diff --git a/atlas/templates/atlas/question_schemas_preset.html b/atlas/templates/atlas/question_schemas_preset.html new file mode 100644 index 00000000..d4d94576 --- /dev/null +++ b/atlas/templates/atlas/question_schemas_preset.html @@ -0,0 +1,44 @@ + +{% load static %} +{% comment %} + {% endcomment %} +
    + {% for schema in schemas %} + +
  1. + +
    Schema: +
    {{schema}}
    +
    +
    + +
  2. + + {% endfor %} +
+ + + + \ No newline at end of file diff --git a/atlas/templates/atlas/svelte_jsoneditor_widget_override.html b/atlas/templates/atlas/svelte_jsoneditor_widget_override.html new file mode 100644 index 00000000..54660926 --- /dev/null +++ b/atlas/templates/atlas/svelte_jsoneditor_widget_override.html @@ -0,0 +1,26 @@ +{% load static %} + +
+ + + + + \ No newline at end of file diff --git a/atlas/urls.py b/atlas/urls.py index e380db09..efafb417 100755 --- a/atlas/urls.py +++ b/atlas/urls.py @@ -116,6 +116,16 @@ urlpatterns = [ views.collection_case_details, name="collection_case_details", ), + path( + "collection//question_schemas", + views.collection_question_schemas, + name="collection_question_schemas", + ), + path( + "question_schemas_preset", + views.question_schemas_preset, + name="question_schemas_preset", + ), path( "collection//cids//delete_answers", views.delete_collection_cid_answers, diff --git a/atlas/views.py b/atlas/views.py index 3ae0662a..6f0f5225 100755 --- a/atlas/views.py +++ b/atlas/views.py @@ -1568,50 +1568,87 @@ def collection_case_details(request, exam_id, case_id): case_detail = CaseDetail.objects.get(case=case_id, collection=exam_id) - if request.method == 'POST' and request.POST.get('submit') == 'answer': - #answers = request.POST - case_detail.question_answers = json.loads(request.POST.get("json_answer")) - case_detail.save() - example_form = JsonAnswerForm(request.POST, case_detail=case_detail) + if request.method == 'POST': + + # Called if the user saves the correct answer form + if request.POST.get('submit') == 'answer': + #answers = request.POST + case_detail.question_answers = json.loads(request.POST.get("json_answer")) + case_detail.save() + example_form = JsonAnswerForm(request.POST, case_detail=case_detail) + form = CaseDetailForm(instance=case_detail) + # Called if the user saves the main form + elif request.POST.get('submit') == 'save': + form = CaseDetailForm(request.POST, instance=case_detail) + if form.is_valid(): + form.save() + # Add any additional logic or redirection here + #example_form = JsonAnswerForm(request.POST, case_detail=case_detail) + if case_detail.question_schema is not None and case_detail.question_answers is not None: + question_keys = set(case_detail.question_schema["properties"].keys()) + answer_keys = set(case_detail.question_answers.keys()) + + answers = {} + for key, value in case_detail.question_answers.items(): + if key in question_keys: + answers[key] = value + + diff = question_keys - answer_keys + + for key in diff: + answers[key] = "" + + + post_data = request.POST.copy() + post_data["json_answer"]= json.dumps(answers) + case_detail.question_answers = answers + case_detail.save() + example_form = JsonAnswerForm(post_data, case_detail=case_detail) + + form = CaseDetailForm(instance=case_detail) + # This shouldn't happen + else: + assert False + form = CaseDetailForm(request.POST, instance=case_detail) else: - post_data = None - - if case_detail.question_schema is not None and case_detail.question_answers is not None: - question_keys = set(case_detail.question_schema["properties"].keys()) - answer_keys = set(case_detail.question_answers.keys()) - - answers = {} - for key, value in case_detail.question_answers.items(): - if key in question_keys: - answers[key] = value - - diff = question_keys - answer_keys - - for key in diff: - answers[key] = "" - - - post_data = request.POST.copy() - post_data["json_answer"]= json.dumps(answers) + post_data = request.POST.copy() + post_data["json_answer"]= json.dumps(case_detail.question_answers) example_form = JsonAnswerForm(post_data, case_detail=case_detail) - if request.method == 'POST' and request.POST.get('submit') == 'save': - form = CaseDetailForm(request.POST, instance=case_detail) - if form.is_valid(): - form.save() - # Add any additional logic or redirection here - else: - form = CaseDetailForm(instance=case_detail) + pass + #post_data = None - blank_form = JsonAnswerForm(case_detail=case_detail) + #if case_detail.question_schema is not None and case_detail.question_answers is not None: + # question_keys = set(case_detail.question_schema["properties"].keys()) + # answer_keys = set(case_detail.question_answers.keys()) + + # answers = {} + # for key, value in case_detail.question_answers.items(): + # if key in question_keys: + # answers[key] = value + + # diff = question_keys - answer_keys + + # for key in diff: + # answers[key] = "" + + + # post_data = request.POST.copy() + # post_data["json_answer"]= json.dumps(answers) + # case_detail.question_answers = answers + #example_form = JsonAnswerForm(post_data, case_detail=case_detail) + + #form = CaseDetailForm(instance=case_detail) + + #blank_form = JsonAnswerForm(case_detail=case_detail) return render( request, "atlas/collection_case_detail.html", {"case_detail": case_detail, "form": form, "example_form": example_form, - "blank_form": blank_form} + } ) @user_is_collection_author_or_atlas_editor @@ -2497,3 +2534,34 @@ class SeriesAuthorUpdate(RevisionMixin, AuthorRequiredMixin, UpdateView): context = super(SeriesAuthorUpdate, self).get_context_data(**kwargs) context["collection"] = context["object"] return context + +def question_schemas_preset(request): + schemas = [ + json.dumps({'type': 'object', 'title': 'Questions', 'required': ['laterality', 'diagnosis'], 'properties': {'test': {'type': 'string', 'title': 'test string', 'description': 'What side is the lesion on?'}, 'diagnosis': {'enum': ['Meningioma', 'Schwannoma', 'Neurofibroma', 'Ependymoma'], 'type': 'string', 'title': 'Diagnosis', 'description': 'What is the diagnosis?'}, 'laterality': {'enum': ['left', 'right'], 'type': 'string', 'title': 'Laterality', 'widget': 'radio', 'description': 'What side is the lesion on?'}, 'laterality (copy 2)': {'enum': ['left', 'right'], 'type': 'string', 'title': 'Lateralityaoue', 'widget': 'radio', 'description': 'What side is the lesion on?'}}}), + ] + + return render( + request, + "atlas/question_schemas_preset.html", + { + "schemas": schemas, + }, + ) + +def collection_question_schemas(request, exam_id: int): + collection = get_object_or_404(CaseCollection, pk=exam_id) + + questions = collection.cases.all().prefetch_related() + + case_details = CaseDetail.objects.filter( + case__in=questions, collection=collection + ).prefetch_related("case").order_by("sort_order") + + return render( + request, + "atlas/collection_question_schemas.html", + { + "collection": collection, + "case_details": case_details, + }, + ) \ No newline at end of file