diff --git a/atlas/forms.py b/atlas/forms.py index abe7734e..61b9e03b 100755 --- a/atlas/forms.py +++ b/atlas/forms.py @@ -17,6 +17,7 @@ from django.forms import ( from django.forms import inlineformset_factory from django.shortcuts import get_object_or_404 from django_jsonforms.forms import JSONSchemaField +from django_svelte_jsoneditor.widgets import SvelteJSONEditorWidget from atlas.models import ( @@ -517,6 +518,21 @@ SeriesImageFormSet = inlineformset_factory( max_num=2000, ) + +class JsonAnswerForm(Form): + json_answer = JSONSchemaField( + schema = "schema/report.json", + #options = 'schema/options.json' + options = {} + ) + class Meta: + fields = ["json_answer"] + + def __init__(self, *args, case_detail, **kwargs): + super(JsonAnswerForm, self).__init__(*args, **kwargs) + if case_detail.question_schema is not None: + self.fields["json_answer"] = JSONSchemaField(schema=case_detail.question_schema, options={}) + class BaseReportAnswerForm(ModelForm): json_answer = JSONSchemaField( schema = "schema/report.json", @@ -721,6 +737,12 @@ class AnswerJSONForm(Form): ) class CaseDetailForm(ModelForm): + class Meta: model = CaseDetail - fields = ["sort_order", "question_schema"]#, "user"] \ No newline at end of file + fields = ["sort_order", "question_schema", "question_answers"]#, "user"] + + widgets = { + "question_schema": SvelteJSONEditorWidget(), + "question_answers": SvelteJSONEditorWidget(), + } \ No newline at end of file diff --git a/atlas/migrations/0053_casedetail_question_answers.py b/atlas/migrations/0053_casedetail_question_answers.py new file mode 100644 index 00000000..6ef25f86 --- /dev/null +++ b/atlas/migrations/0053_casedetail_question_answers.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.2 on 2024-05-20 09:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('atlas', '0052_alter_casecollection_end_date_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='casedetail', + name='question_answers', + field=models.JSONField(blank=True, null=True), + ), + ] diff --git a/atlas/models.py b/atlas/models.py index 53ad5ef1..aeaefee8 100644 --- a/atlas/models.py +++ b/atlas/models.py @@ -961,6 +961,7 @@ class CaseDetail(models.Model): collection = models.ForeignKey(CaseCollection, on_delete=models.CASCADE) question_schema = models.JSONField(null=True, blank=True) + question_answers = models.JSONField(null=True, blank=True) sort_order = models.IntegerField(default=1000) diff --git a/atlas/templates/atlas/collection_case_detail.html b/atlas/templates/atlas/collection_case_detail.html index 13bca990..941ea1ff 100644 --- a/atlas/templates/atlas/collection_case_detail.html +++ b/atlas/templates/atlas/collection_case_detail.html @@ -1,12 +1,36 @@ {% extends 'atlas/exams.html' %} + + {% block content %}

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

+

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

+
{% csrf_token %} {{ form.as_p }} - + +
+ +

Blank form

+
+ {{ blank_form}} +
+ +

Correct answers

+
+ {% csrf_token %} + {{example_form}} +
{% endblock %} + +{% block js %} + + {% comment %} {{ example_form.media }} {% endcomment %} + + + +{% endblock %} \ No newline at end of file diff --git a/atlas/templates/atlas/collection_case_view_take_answers.html b/atlas/templates/atlas/collection_case_view_take_answers.html new file mode 100644 index 00000000..debbfa75 --- /dev/null +++ b/atlas/templates/atlas/collection_case_view_take_answers.html @@ -0,0 +1,12 @@ + +{% extends 'atlas/base.html' %} + +{% block content %} + +

Case: {{ case.title }}

+{{ case_detail.question_schema }} + + +{{ case.question_answers }} + +{% endblock %} \ No newline at end of file diff --git a/atlas/templates/atlas/index.html b/atlas/templates/atlas/index.html index 957d1292..0826795c 100644 --- a/atlas/templates/atlas/index.html +++ b/atlas/templates/atlas/index.html @@ -3,8 +3,8 @@ {% block content %}

Atlas

-Available collections
+Colletion to view / take
View my cases.
-My uploads +Uploads awaiting import {% endblock %} \ No newline at end of file diff --git a/atlas/urls.py b/atlas/urls.py index eeccf0e8..e380db09 100755 --- a/atlas/urls.py +++ b/atlas/urls.py @@ -176,6 +176,11 @@ urlpatterns = [ views.collection_case_view_take_user, name="collection_case_view_take_user", ), + path( + "collection///take/answers", + views.collection_case_view_take_user_answers, + name="collection_case_view_take_user_answers", + ), path( "collection//json_edit", views.GenericExamViews.exam_json_edit, diff --git a/atlas/views.py b/atlas/views.py index e88c0035..3ae0662a 100755 --- a/atlas/views.py +++ b/atlas/views.py @@ -47,6 +47,7 @@ from .forms import ( ConditionAutocompleteForm, ConditionForm, FindingForm, + JsonAnswerForm, ResourceForm, SelfReviewForm, SeriesAuthorForm, @@ -1566,18 +1567,51 @@ def collection_take_start(request, pk): def collection_case_details(request, exam_id, case_id): case_detail = CaseDetail.objects.get(case=case_id, collection=exam_id) - if request.method == 'POST': + + 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) + + 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) + 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) - + + blank_form = JsonAnswerForm(case_detail=case_detail) + return render( request, "atlas/collection_case_detail.html", {"case_detail": case_detail, - "form": form} + "form": form, "example_form": example_form, + "blank_form": blank_form} ) @user_is_collection_author_or_atlas_editor @@ -1790,6 +1824,35 @@ def collection_take_overview( }, ) +def collection_case_view_take_user_answers(request, pk: int, case_number: int): + return collection_case_view_take_answers(request, pk, case_number) + +def collection_case_view_take_answers( + request, pk: int, case_number: int, cid=None, passcode=None +): + """ + """ + collection = get_object_or_404(CaseCollection, pk=pk) + + collection.check_user_can_take(cid, passcode, request.user) + + case, case_count = collection.get_case_by_index(case_number, case_count=True) + + cid_user_exam = collection.get_or_create_cid_user_exam( + cid=cid, user_user=request.user + ) + + case_detail = CaseDetail.objects.get(case=case, collection=collection) + + return render( + request, + "atlas/collection_case_view_take_answers.html", + { + "collection": collection, + "case": case, + "case_detail": case_detail, + }, + ) def collection_case_view_take_user(request, pk: int, case_number: int): return collection_case_view_take(request, pk, case_number) diff --git a/rad/settings.py b/rad/settings.py index 6248a00f..cab48e2f 100644 --- a/rad/settings.py +++ b/rad/settings.py @@ -80,7 +80,7 @@ INSTALLED_APPS = [ "autocomplete", 'markdownify.apps.MarkdownifyConfig', 'django_jsonforms', - + 'django_svelte_jsoneditor' ] MIDDLEWARE = [ diff --git a/requirements.txt b/requirements.txt index 92d29f93..ae468d78 100644 --- a/requirements.txt +++ b/requirements.txt @@ -47,4 +47,5 @@ django-sortedm2m # remove once migrations squashed loguru pylibjpeg pylibjpeg-libjpeg -django-jsonforms \ No newline at end of file +django-jsonforms +django_svelte_jsoneditor \ No newline at end of file