work on case priors
This commit is contained in:
@@ -24,6 +24,7 @@ from atlas.models import (
|
||||
Case,
|
||||
CaseCollection,
|
||||
CaseDetail,
|
||||
CasePrior,
|
||||
CidReportAnswer,
|
||||
Differential,
|
||||
Finding,
|
||||
@@ -858,10 +859,19 @@ class QuestionSchemaForm(ModelForm):
|
||||
"schema": SvelteJSONEditorWidgetOverride(),
|
||||
}
|
||||
|
||||
#class ModelPriorCaseForm(ModelForm):
|
||||
# class Meta:
|
||||
# model = CasePrior
|
||||
# fields = ["case_detail", "prior_case", "relation_text", "prior_visibility"]
|
||||
|
||||
class PriorCaseForm(Form):
|
||||
|
||||
relation = CharField(max_length=255, required=True)
|
||||
|
||||
prior_visibility = CharField(max_length=2, required=True)
|
||||
|
||||
|
||||
|
||||
#def __init__(self, *args, **kwargs):
|
||||
# self.case_detail = kwargs.pop(
|
||||
# "case_detail"
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.1.4 on 2025-04-28 15:04
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('atlas', '0068_alter_seriesfinding_description'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='caseprior',
|
||||
name='prior_visibility',
|
||||
field=models.CharField(choices=[('NO', 'None'), ('AL', 'Always'), ('RE', 'Review')], default='AL', help_text='Defines when the prior case is shown to the user', max_length=2),
|
||||
),
|
||||
]
|
||||
@@ -1118,6 +1118,19 @@ class CasePrior(models.Model):
|
||||
|
||||
relation_text = models.CharField(max_length=255, blank=True, help_text="Text to describe the relationship between the cases")
|
||||
|
||||
class PriorVisibility(models.TextChoices):
|
||||
NONE = "NO", _("None")
|
||||
ALWAYS = "AL", _("Always")
|
||||
REVIEW = "RE", _("Review")
|
||||
|
||||
|
||||
prior_visibility = models.CharField(
|
||||
max_length=2,
|
||||
choices=PriorVisibility.choices,
|
||||
default=PriorVisibility.ALWAYS,
|
||||
help_text="Defines when the prior case is shown to the user",
|
||||
)
|
||||
|
||||
class Meta:
|
||||
unique_together = ("case_detail", "prior_case")
|
||||
|
||||
|
||||
@@ -253,7 +253,7 @@
|
||||
<button
|
||||
hx-get="{% url 'atlas:case_collection_form' case.pk %}"
|
||||
hx-target="#collection-form">
|
||||
Add collection</button>
|
||||
Add to collection</button>
|
||||
{% endif %}
|
||||
<div id="collection-form"></div>
|
||||
<ul>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<h3>Available priors</h3>
|
||||
|
||||
<ul>
|
||||
{% for case, added, relation in available_priors %}
|
||||
{% for case, added, relation, visibility in available_priors %}
|
||||
|
||||
<li class='
|
||||
{% if added %}
|
||||
@@ -38,24 +38,63 @@
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
{% if not added %}
|
||||
<form hx-post="{% url 'atlas:collection_case_priors' collection.id case_detail.case.pk %}"
|
||||
hx-target="#htmx-response-{{case.id}}"
|
||||
_="on htmx:afterRequest log 'test' then remove me"
|
||||
>
|
||||
_="on htmx:afterRequest log 'test' then remove me">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="prior_case_id" value="{{case.id}}" />
|
||||
<input type="text" name="relation" value="{{relation}}" placeholder="relation to case" />
|
||||
<br />
|
||||
<label for="prior_visibility_{{case.id}}">Visibility:</label>
|
||||
<select name="prior_visibility" id="prior_visibility_{{case.id}}">
|
||||
<option value="AL"
|
||||
{% if visibility == 'AL' %}
|
||||
selected
|
||||
{% endif %}
|
||||
>Always</option>
|
||||
<option value="RE"
|
||||
{% if visibility == 'RE' %}
|
||||
selected
|
||||
{% endif %}
|
||||
|
||||
>Review</option>
|
||||
<option value="NO"
|
||||
{% if visibility == 'NO' %}
|
||||
selected
|
||||
{% endif %}
|
||||
>None</option>
|
||||
</select>
|
||||
<br />
|
||||
<button class="btn primary">Add to case</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<form hx-post="{% url 'atlas:collection_case_priors' collection.id case_detail.case.pk %}"
|
||||
hx-target="#htmx-response-{{case.id}}"
|
||||
_="on htmx:afterRequest log 'test' then remove me"
|
||||
>
|
||||
_="on htmx:afterRequest log 'test' then remove me">
|
||||
Case available: {{relation}}
|
||||
<input type="hidden" name="remove" value="{{case.id}}" />
|
||||
<br />
|
||||
<label for="prior_visibility_{{case.id}}">Visibility:</label>
|
||||
<select name="prior_visibility" id="prior_visibility_{{case.id}}" disabled>
|
||||
<option value="AL"
|
||||
{% if visibility == 'AL' %}
|
||||
selected
|
||||
{% endif %}
|
||||
>Always</option>
|
||||
<option value="RE"
|
||||
{% if visibility == 'RE' %}
|
||||
selected
|
||||
{% endif %}
|
||||
|
||||
>Review</option>
|
||||
<option value="NO"
|
||||
{% if visibility == 'NO' %}
|
||||
selected
|
||||
{% endif %}
|
||||
>None</option>
|
||||
</select>
|
||||
<br />
|
||||
<button class="btn primary">Remove from case</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
@@ -49,14 +49,24 @@
|
||||
|
||||
{% if collection.show_ohif_viewer %}
|
||||
<div>
|
||||
|
||||
{% if question_completed %}
|
||||
<iframe id="viewer" style="width: 100%; height: 100%; border: none; padding: 0px; min-height: 700px" src="/ohif/viewer/dicomjson?url=https://www.penracourses.org.uk{% url 'atlas:collection_case_dicom_json_review' collection.pk case.pk %}"></iframe>
|
||||
{% else %}
|
||||
<iframe id="viewer" style="width: 100%; height: 100%; border: none; padding: 0px; min-height: 700px" src="/ohif/viewer/dicomjson?url=https://www.penracourses.org.uk{% url 'atlas:collection_case_dicom_json' collection.pk case.pk %}"></iframe>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if collection.show_ohif_viewer_link %}
|
||||
<div>
|
||||
{% if question_completed %}
|
||||
<a target="_blank" href="/ohif/viewer/dicomjson?url=https://www.penracourses.org.uk{% url 'atlas:collection_case_dicom_json_review' collection.pk case.pk %}" title="Click to open the case in the advanced viewer. This will open in a new tab/window."><button class="viewer"><i class="bi bi-collection"></i> Launch advanced viewer.</button></a>
|
||||
{% else %}
|
||||
<a target="_blank" href="/ohif/viewer/dicomjson?url=https://www.penracourses.org.uk{% url 'atlas:collection_case_dicom_json' collection.pk case.pk %}" title="Click to open the case in the advanced viewer. This will open in a new tab/window."><button class="viewer"><i class="bi bi-collection"></i> Launch advanced viewer.</button></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -138,6 +138,11 @@ urlpatterns = [
|
||||
views.collection_case_dicom_json,
|
||||
name="collection_case_dicom_json",
|
||||
),
|
||||
path(
|
||||
"collection/<int:exam_id>/case/<int:case_id>/dicom_json/review",
|
||||
views.collection_case_dicom_json_review,
|
||||
name="collection_case_dicom_json_review",
|
||||
),
|
||||
path(
|
||||
"collection/<int:exam_id>/question_schemas",
|
||||
views.collection_question_schemas,
|
||||
|
||||
+33
-17
@@ -56,6 +56,7 @@ from .forms import (
|
||||
ExamGroupsForm,
|
||||
FindingForm,
|
||||
JsonAnswerForm,
|
||||
#ModelPriorCaseForm,
|
||||
PriorCaseForm,
|
||||
QuestionSchemaForm,
|
||||
ResourceForm,
|
||||
@@ -493,7 +494,7 @@ def add_case_to_collection(request, collection_id):
|
||||
return HttpResponse("Case already in collection")
|
||||
print(case)
|
||||
collection.add_case(case)
|
||||
return HttpResponse("Case added to collection (refresh to see)")
|
||||
return HttpResponse(f"Case added to collection {collection.name} (refresh to see)")
|
||||
|
||||
# if request.method == "POST":
|
||||
|
||||
@@ -1766,6 +1767,7 @@ def collection_case_priors(request, exam_id, case_id):
|
||||
return HttpResponse(
|
||||
"You need to enter text to describe the relationship between the cases"
|
||||
)
|
||||
p.prior_visibility = request.POST["prior_visibility"]
|
||||
|
||||
p.save()
|
||||
|
||||
@@ -1780,7 +1782,7 @@ def collection_case_priors(request, exam_id, case_id):
|
||||
|
||||
added_relation_map = {}
|
||||
for prior in added_priors:
|
||||
added_relation_map[prior.prior_case] = prior.relation_text
|
||||
added_relation_map[prior.prior_case] = (prior.relation_text, prior.prior_visibility)
|
||||
|
||||
case = case_detail.case
|
||||
|
||||
@@ -1789,9 +1791,9 @@ def collection_case_priors(request, exam_id, case_id):
|
||||
available_priors = []
|
||||
for case in available_cases:
|
||||
if case in added_relation_map:
|
||||
available_priors.append((case, True, added_relation_map[case]))
|
||||
available_priors.append((case, True, added_relation_map[case][0], added_relation_map[case][1]))
|
||||
else:
|
||||
available_priors.append((case, False, ""))
|
||||
available_priors.append((case, False, "", "AL"))
|
||||
|
||||
form = PriorCaseForm()
|
||||
|
||||
@@ -1808,6 +1810,7 @@ def collection_case_priors(request, exam_id, case_id):
|
||||
{
|
||||
"case_detail": case_detail,
|
||||
"form": form,
|
||||
#"model_form": model_form,
|
||||
# "example_form": example_form,
|
||||
"collection": collection,
|
||||
"case": case_detail.case,
|
||||
@@ -2302,17 +2305,6 @@ def collection_case_view_take(
|
||||
|
||||
series_list = case.series.all().prefetch_related("images", "examination", "plane")
|
||||
|
||||
prior_cases = case_detail.caseprior_set.all()
|
||||
|
||||
series_to_load = []
|
||||
|
||||
for series in series_list:
|
||||
series_to_load.append((series, False, ""))
|
||||
|
||||
for prior in prior_cases:
|
||||
for series in prior.prior_case.get_series():
|
||||
series_to_load.append((series, True, prior.relation_text))
|
||||
|
||||
previous = case_number > 0
|
||||
next = case_number < (case_count - 1)
|
||||
|
||||
@@ -2348,6 +2340,25 @@ def collection_case_view_take(
|
||||
|
||||
resources = case.caseresource_set.filter(pre_review=True)
|
||||
|
||||
prior_cases = case_detail.caseprior_set.all()
|
||||
|
||||
series_to_load = []
|
||||
|
||||
for series in series_list:
|
||||
series_to_load.append((series, False, ""))
|
||||
|
||||
for prior in prior_cases:
|
||||
match prior.prior_visibility:
|
||||
case "AL":
|
||||
for series in prior.prior_case.get_series():
|
||||
series_to_load.append((series, True, prior.relation_text))
|
||||
case "RE":
|
||||
if question_completed:
|
||||
for series in prior.prior_case.get_series():
|
||||
series_to_load.append((series, True, prior.relation_text))
|
||||
case _:
|
||||
continue
|
||||
|
||||
return render(
|
||||
request,
|
||||
"atlas/collection_case_view_take.html",
|
||||
@@ -2437,11 +2448,16 @@ def use_dates_as_descriptions(request, pk):
|
||||
|
||||
return HttpResponse("Done")
|
||||
|
||||
def collection_case_dicom_json_review(request, exam_id, case_id):
|
||||
return collection_case_dicom_json(request, exam_id, case_id, review=True)
|
||||
|
||||
def collection_case_dicom_json(request, exam_id, case_id):
|
||||
def collection_case_dicom_json(request, exam_id, case_id, review=False):
|
||||
case_detail = CaseDetail.objects.get(case=case_id, collection=exam_id)
|
||||
|
||||
priors = case_detail.caseprior_set.all()
|
||||
if review:
|
||||
priors = case_detail.caseprior_set.exclude(prior_visibility="NO")
|
||||
else:
|
||||
priors = case_detail.caseprior_set.exclude(prior_visibility__in=["NO", "RE"])
|
||||
|
||||
return JsonResponse(case_detail.case.get_case_dicom_json(priors=priors))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user