This commit is contained in:
Ross
2022-04-04 22:06:11 +01:00
parent 4adef5c2c3
commit 0eeb0e832e
26 changed files with 1123 additions and 1099 deletions
+4 -4
View File
@@ -2,7 +2,7 @@
{% block content %} {% block content %}
{% for author in authors %} {% for author in authors %}
<p>Author: <a href="{% url 'atlas:author_detail' pk=author.pk %}">{{author.username}}</a>, </p> <p>Author: <a href="{% url 'atlas:author_detail' pk=author.pk %}">{{author.username}}</a>, </p>
{% endfor %} {% endfor %}
{% endblock %} {% endblock %}
+12 -12
View File
@@ -1,7 +1,7 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block title %} {% block title %}
Atlas Atlas
{% endblock %} {% endblock %}
{% block css %} {% block css %}
@@ -15,16 +15,16 @@ Atlas
{% block content %} {% block content %}
{% endblock %} {% endblock %}
{% block navigation %} {% block navigation %}
Atlas: Atlas:
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<a href="{% url 'atlas:case_view' %}">Cases</a> / <a href="{% url 'atlas:case_view' %}">Cases</a> /
<a href="{% url 'atlas:series_view' %}">Series</a> / <a href="{% url 'atlas:series_view' %}">Series</a> /
<a href="{% url 'atlas:collection_view' %}">Collections</a> / <a href="{% url 'atlas:collection_view' %}">Collections</a> /
<a href="{% url 'atlas:categories_list' %}">Categories</a> / <a href="{% url 'atlas:categories_list' %}">Categories</a> /
<a href="{% url 'atlas:case_create' %}" title="Create a new atlas case">Create Case</a> / <a href="{% url 'atlas:case_create' %}" title="Create a new atlas case">Create Case</a> /
<a href="{% url 'atlas:series_create' %}" title="Create a new image series">Create Series</a> <a href="{% url 'atlas:series_create' %}" title="Create a new image series">Create Series</a>
{% endif %} {% endif %}
{% comment %} </br> {% comment %} </br>
Questions by: Questions by:
<span id="authors-link"><a href="{% url 'atlas:author_list' %}">author</a></span> {% endcomment %} <span id="authors-link"><a href="{% url 'atlas:author_list' %}">author</a></span> {% endcomment %}
{% endblock %} {% endblock %}
+15 -15
View File
@@ -4,21 +4,21 @@
<div class="floating-header"> <div class="floating-header">
<a href="{% url 'atlas:case_update' pk=case.pk %}" title="Edit the Case">Edit</a> <a href="{% url 'atlas:case_update' pk=case.pk %}" title="Edit the Case">Edit</a>
<a href="{% url 'atlas:case_clone' pk=case.pk %}" <a href="{% url 'atlas:case_clone' pk=case.pk %}"
title="Clone the Case (duplicate everything but the images)">Clone</a> title="Clone the Case (duplicate everything but the images)">Clone</a>
<a href="{% url 'atlas:case_delete' pk=case.pk %}" title="Delete the Case">Delete</a> <a href="{% url 'atlas:case_delete' pk=case.pk %}" title="Delete the Case">Delete</a>
<a href="#" <a href="#"
onclick="return window.create_popup_window('{% url 'feedback_create' question_type='atlas' pk=case.pk %}')"> Add onclick="return window.create_popup_window('{% url 'feedback_create' question_type='atlas' pk=case.pk %}')"> Add
Note</a> Note</a>
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
<a href="{% url 'admin:atlas_case_change' case.id %}" title="Edit the Case using the admin interface">Admin Edit</a> <a href="{% url 'admin:atlas_case_change' case.id %}" title="Edit the Case using the admin interface">Admin Edit</a>
{% endif %} {% endif %}
</div> </div>
{% include 'atlas/case_display_block.html' %} {% include 'atlas/case_display_block.html' %}
{% endblock %} {% endblock %}
{% block js %} {% block js %}
{% endblock %} {% endblock %}
+125 -125
View File
@@ -1,125 +1,125 @@
<div class="atlas {% if case.scrapped %}atlas-scrapped{% endif %}"> <div class="atlas {% if case.scrapped %}atlas-scrapped{% endif %}">
<div class="date"> <div class="date">
{{ case.created_date|date:"d/m/Y" }} {{ case.created_date|date:"d/m/Y" }}
</div> </div>
<div class="id"> <div class="id">
ID: {{ case.id }} ID: {{ case.id }}
</div> </div>
<p class="pre-whitespace"><b>Title:</b> {{ case.title }}</p> <p class="pre-whitespace"><b>Title:</b> {{ case.title }}</p>
<p class="pre-whitespace"><b>Description:</b> {{ case.description }}</p> <p class="pre-whitespace"><b>Description:</b> {{ case.description }}</p>
<p> <p>
<b>Presentation:</b> <b>Presentation:</b>
<ul> <ul>
{% for presentation in case.presentation.all %} {% for presentation in case.presentation.all %}
<li>{{presentation.get_link}}</li> <li>{{presentation.get_link}}</li>
{% endfor %} {% endfor %}
</ul> </ul>
</p> </p>
<p class="pre-whitespace"><b>History:</b> {{ case.history }}</p> <p class="pre-whitespace"><b>History:</b> {{ case.history }}</p>
<p class="pre-whitespace"><b>Discussion:</b> {{ case.discussion }}</p> <p class="pre-whitespace"><b>Discussion:</b> {{ case.discussion }}</p>
<p class="pre-whitespace"><b>Report:</b> {{ case.report }}</p> <p class="pre-whitespace"><b>Report:</b> {{ case.report }}</p>
<div class="pre-whitespace multi-image-block"><b>Series:</b> <div class="pre-whitespace multi-image-block"><b>Series:</b>
{% for series in case.series.all %} {% for series in case.series.all %}
<span class="series-block"> <span class="series-block">
<span> <span>
Series {{ forloop.counter }}: Series {{ forloop.counter }}:
<a href="{% url 'atlas:series_detail' pk=series.pk %}"> <a href="{% url 'atlas:series_detail' pk=series.pk %}">
{{series.get_block}} {{series.get_block}}
</a> </a>
<a href="#" <a href="#"
onclick="return window.create_popup_window('/atlas/series/{{series.pk}}', 'Series')">Popup</a> onclick="return window.create_popup_window('/atlas/series/{{series.pk}}', 'Series')">Popup</a>
</span> </span>
</span> </span>
{% endfor %} {% endfor %}
<a href="{% url 'atlas:series_id_create' pk=case.pk %}">Add new series</a><br /> <a href="{% url 'atlas:series_id_create' pk=case.pk %}">Add new series</a><br />
</div> </div>
{% comment %} <p><b>Scrapped:</b> {{ case.scrapped }} <a {% comment %} <p><b>Scrapped:</b> {{ case.scrapped }} <a
href="{% url 'atlas:case_scrap' pk=case.pk %}">(toggle)</a> {% endcomment %} href="{% url 'atlas:case_scrap' pk=case.pk %}">(toggle)</a> {% endcomment %}
<div class="atlas-answer"> <div class="atlas-answer">
<p class="pre-whitespace"> <p class="pre-whitespace">
Condition: Condition:
<ul> <ul>
{% for con in case.condition.all %} {% for con in case.condition.all %}
<li>{{con.get_link}}</li> <li>{{con.get_link}}</li>
{% endfor %} {% endfor %}
</ul> </ul>
<details> <details>
<summary><b>Findings</b></summary> <summary><b>Findings</b></summary>
{% if case.series.all %} {% if case.series.all %}
See individual series for more details.<br/> See individual series for more details.<br/>
{% for series in case.series.all %} {% for series in case.series.all %}
{% for finding in series.findings.all %} {% for finding in series.findings.all %}
<div class="finding-box"> <div class="finding-box">
<span> <span>
<a href="{{series.get_absolute_url}}">Series {{series.pk}}</a>: {{series.get_examination_full}} |&nbsp; <a href="{{series.get_absolute_url}}">Series {{series.pk}}</a>: {{series.get_examination_full}} |&nbsp;
</span> </span>
{% if finding.findings.all %} {% if finding.findings.all %}
<span> <span>
Findings: {% for f in finding.findings.all %} Findings: {% for f in finding.findings.all %}
{{f.get_link}},&nbsp; {{f.get_link}},&nbsp;
{% endfor %} {% endfor %}
</span> </span>
{% endif %} {% endif %}
{% if finding.structures.all %} {% if finding.structures.all %}
<span> <span>
Structure: {% for s in finding.structures.all %} Structure: {% for s in finding.structures.all %}
{{s.get_link}},&nbsp; {{s.get_link}},&nbsp;
{% endfor %} {% endfor %}
</span> </span>
{% endif %} {% endif %}
{% if finding.description %} {% if finding.description %}
<span> <span>
Description: {{finding.description}} Description: {{finding.description}}
</span> </span>
{% endif %} {% endif %}
</div> </div>
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}
{% else %} {% else %}
No findings associated with case. No findings associated with case.
{% endif %} {% endif %}
</details> </details>
<details open> <details open>
<summary><b>Differentials</b></summary> <summary><b>Differentials</b></summary>
<ul> <ul>
{% for diff in case.differentialcase.all %} {% for diff in case.differentialcase.all %}
<li>{{diff.condition.get_link}} - {{diff.text}}</li> <li>{{diff.condition.get_link}} - {{diff.text}}</li>
{% endfor %} {% endfor %}
</ul> </ul>
</details> </details>
</p> </p>
</div> </div>
Subspecialty: Subspecialty:
<ul> <ul>
{% for sub in case.subspecialty.all %} {% for sub in case.subspecialty.all %}
<li>{{sub.get_link}}</li> <li>{{sub.get_link}}</li>
{% endfor %} {% endfor %}
</ul> </ul>
<b>Pathological Process:</b> <b>Pathological Process:</b>
<ul> <ul>
{% for p in case.pathological_process.all %} {% for p in case.pathological_process.all %}
<li>{{p.get_link}}</li> <li>{{p.get_link}}</li>
{% endfor %} {% endfor %}
</ul> </ul>
</p> </p>
<p class="pre-whitespace"><b>Previous case:</b> {{ case.previous_case }}</p> <p class="pre-whitespace"><b>Previous case:</b> {{ case.previous_case }}</p>
<p class="pre-whitespace"><b>Next case:</b> {{ case.next_case }}</p> <p class="pre-whitespace"><b>Next case:</b> {{ case.next_case }}</p>
<div> <div>
{% include 'question_notes.html' %} {% include 'question_notes.html' %}
</div> </div>
<p><b>Checked by:</b> {% for verified in case.verified.all %} <a <p><b>Checked by:</b> {% for verified in case.verified.all %} <a
href="{% url 'atlas:verified_detail' pk=verified.pk %}">{{verified}}</a>, {% endfor %}</p> href="{% url 'atlas:verified_detail' pk=verified.pk %}">{{verified}}</a>, {% endfor %}</p>
<p><b>Author(s):</b> {% for author in case.author.all %} <a <p><b>Author(s):</b> {% for author in case.author.all %} <a
href="{% url 'atlas:author_detail' pk=author.pk %}">{{author}}</a>, {% endfor %}</p> href="{% url 'atlas:author_detail' pk=author.pk %}">{{author}}</a>, {% endfor %}</p>
+78 -78
View File
@@ -4,95 +4,95 @@
{% block css %} {% block css %}
{% endblock %} {% endblock %}
{% block js %} {% block js %}
<!--<script type="text/javascript" src="/admin/jsi18n/"></script>--> <!--<script type="text/javascript" src="/admin/jsi18n/"></script>-->
{{form.media}} {{form.media}}
<script type="text/javascript"> <script type="text/javascript">
function showEditPopup(url) { function showEditPopup(url) {
var win = window.open(url, "Edit", var win = window.open(url, "Edit",
'height=500,width=800,resizable=yes,scrollbars=yes'); 'height=500,width=800,resizable=yes,scrollbars=yes');
return false; return false;
} }
function showAddPopup(triggeringLink) { function showAddPopup(triggeringLink) {
var name = triggeringLink.id.replace(/^add_/, ''); var name = triggeringLink.id.replace(/^add_/, '');
href = triggeringLink.href; href = triggeringLink.href;
var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
win.focus(); win.focus();
return false; return false;
} }
function closePopup(win, newID, newRepr, id) { function closePopup(win, newID, newRepr, id) {
console.log(id) console.log(id)
$(id + "_to").append('<option value=' + newID + ' title=' + newRepr + ' >' + newRepr + '</option>') $(id + "_to").append('<option value=' + newID + ' title=' + newRepr + ' >' + newRepr + '</option>')
win.close(); win.close();
} }
function add_series_input_form() { function add_series_input_form() {
var form_idx = $('#id_Case_series-TOTAL_FORMS').val(); var form_idx = $('#id_Case_series-TOTAL_FORMS').val();
$('#series_formset').append($('#empty_series_form').html().replace(/__prefix__/g, form_idx)); $('#series_formset').append($('#empty_series_form').html().replace(/__prefix__/g, form_idx));
$('#id_Case_series-TOTAL_FORMS').val(parseInt(form_idx) + 1); $('#id_Case_series-TOTAL_FORMS').val(parseInt(form_idx) + 1);
} }
function add_differential_input_form() { function add_differential_input_form() {
var form_idx = $('#id_differentialcase-TOTAL_FORMS').val(); var form_idx = $('#id_differentialcase-TOTAL_FORMS').val();
$('#casedifferential_formset').append($('#empty_casedifferential_form').html().replace(/__prefix__/g, form_idx)); $('#casedifferential_formset').append($('#empty_casedifferential_form').html().replace(/__prefix__/g, form_idx));
$('#id_differentialcase-TOTAL_FORMS').val(parseInt(form_idx) + 1); $('#id_differentialcase-TOTAL_FORMS').val(parseInt(form_idx) + 1);
} }
$(document).ready(function () { $(document).ready(function () {
$('#add_more_series').click(() => { add_series_input_form() }); $('#add_more_series').click(() => { add_series_input_form() });
$('#add_more_differential').click(() => { add_differential_input_form() }); $('#add_more_differential').click(() => { add_differential_input_form() });
}) })
</script> </script>
<!-- {{ form.media }} --> <!-- {{ form.media }} -->
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h2>Submit Case</h2> <h2>Submit Case</h2>
Use this form to create a atlas case. Existing associated image sets can be added using this form. Use this form to create a atlas case. Existing associated image sets can be added using this form.
<form action="" method="post" enctype="multipart/form-data" id="atlas-form"> <form action="" method="post" enctype="multipart/form-data" id="atlas-form">
{% csrf_token %} {% csrf_token %}
<table> <table>
{{ form.as_table }} {{ form.as_table }}
</table> </table>
<h3>Series:</h3> <h3>Series:</h3>
Add image sets here. These can only be added once created (they can also be added to cases on creation). Add image sets here. These can only be added once created (they can also be added to cases on creation).
<input type="button" value="Add More Series" id="add_more_series"> <input type="button" value="Add More Series" id="add_more_series">
<div id="series_formset"> <div id="series_formset">
{% for form in series_formset %} {% for form in series_formset %}
<ul class="no-error series-formset"> <ul class="no-error series-formset">
{{form.non_field_errors}} {{form.non_field_errors}}
{{form.errors}} {{form.errors}}
{{ form.as_ul }} {{ form.as_ul }}
</ul>
{% endfor %}
</div>
{{ series_formset.management_form }}
<h3>Differential:</h3>
Add differential here.
<input type="button" value="Add Another Differential" id="add_more_differential">
<div id="casedifferential_formset">
{% for form in casedifferential_formset %}
<ul class="no-error casedifferential_formset">
{{form.non_field_errors}}
{{form.errors}}
{{ form.as_ul }}
</ul>
{% endfor %}
</div>
{{ casedifferential_formset.management_form }}
<input type="submit" class="submit-button" value="Submit" name="submit">
</form>
<div id="empty_series_form" style="display:none">
<ul class='no_error series-formset'>
{{ series_formset.empty_form.as_ul }}
</ul> </ul>
{% endfor %}
</div> </div>
{{ series_formset.management_form }} <div id="empty_casedifferential_form" style="display:none">
<h3>Differential:</h3> <ul class='no_error casedifferential_formset'>
Add differential here. {{ casedifferential_formset.empty_form.as_ul }}
<input type="button" value="Add Another Differential" id="add_more_differential">
<div id="casedifferential_formset">
{% for form in casedifferential_formset %}
<ul class="no-error casedifferential_formset">
{{form.non_field_errors}}
{{form.errors}}
{{ form.as_ul }}
</ul> </ul>
{% endfor %}
</div> </div>
{{ casedifferential_formset.management_form }} {% endblock %}
<input type="submit" class="submit-button" value="Submit" name="submit">
</form>
<div id="empty_series_form" style="display:none">
<ul class='no_error series-formset'>
{{ series_formset.empty_form.as_ul }}
</ul>
</div>
<div id="empty_casedifferential_form" style="display:none">
<ul class='no_error casedifferential_formset'>
{{ casedifferential_formset.empty_form.as_ul }}
</ul>
</div>
{% endblock %}
+9 -9
View File
@@ -6,16 +6,16 @@
{% block content %} {% block content %}
<div id="view-filter-options"> <div id="view-filter-options">
<h3>Filter Long </h3> <h3>Filter Long </h3>
<form action="" method="get"> <form action="" method="get">
{{ filter.form }} {{ filter.form }}
<input class="btn btn-primary btn-sm mt-1 mb-1" type="submit" /> <input class="btn btn-primary btn-sm mt-1 mb-1" type="submit" />
</form> </form>
</div> </div>
{% render_table table %} {% render_table table %}
{% endblock %} {% endblock %}
{% block js %} {% block js %}
{% endblock %} {% endblock %}
+39 -39
View File
@@ -4,51 +4,51 @@
{% block css %} {% block css %}
{% endblock %} {% endblock %}
{% block js %} {% block js %}
<!--<script type="text/javascript" src="/admin/jsi18n/"></script>--> <!--<script type="text/javascript" src="/admin/jsi18n/"></script>-->
{{form.media}} {{form.media}}
<script type="text/javascript"> <script type="text/javascript">
function add_case_input_form() { function add_case_input_form() {
var form_idx = $('#id_casedetail_set-TOTAL_FORMS').val(); var form_idx = $('#id_casedetail_set-TOTAL_FORMS').val();
$('#case_formset').append($('#empty_case_form').html().replace(/__prefix__/g, form_idx)); $('#case_formset').append($('#empty_case_form').html().replace(/__prefix__/g, form_idx));
$('#id_casedetail_set-TOTAL_FORMS').val(parseInt(form_idx) + 1); $('#id_casedetail_set-TOTAL_FORMS').val(parseInt(form_idx) + 1);
} }
$(document).ready(function () { $(document).ready(function () {
$('#add_more_case').click(() => { add_case_input_form() }); $('#add_more_case').click(() => { add_case_input_form() });
}) })
</script> </script>
<!-- {{ form.media }} --> <!-- {{ form.media }} -->
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h2>Create Collection</h2> <h2>Create Collection</h2>
Use this form to create a collection of cases Use this form to create a collection of cases
<form action="" method="post" enctype="multipart/form-data" id="atlas-form"> <form action="" method="post" enctype="multipart/form-data" id="atlas-form">
{% csrf_token %} {% csrf_token %}
<table> <table>
{{ form.as_table }} {{ form.as_table }}
</table> </table>
<h3>Cases:</h3> <h3>Cases:</h3>
Add cases here. These can only be added once created (they can also be added to cases on creation). Add cases here. These can only be added once created (they can also be added to cases on creation).
<input type="button" value="Add More Cases" id="add_more_case"> <input type="button" value="Add More Cases" id="add_more_case">
<div id="case_formset"> <div id="case_formset">
{% for form in case_formset %} {% for form in case_formset %}
<ul class="no-error case-formset"> <ul class="no-error case-formset">
{{form.non_field_errors}} {{form.non_field_errors}}
{{form.errors}} {{form.errors}}
{{ form.as_ul }} {{ form.as_ul }}
</ul>
{% endfor %}
</div>
{{ case_formset.management_form }}
<input type="submit" class="submit-button" value="Submit" name="submit">
</form>
<div id="empty_case_form" style="display:none">
<ul class='no_error case-formset'>
{{ case_formset.empty_form.as_ul }}
</ul> </ul>
{% endfor %}
</div> </div>
{{ case_formset.management_form }} {% endblock %}
<input type="submit" class="submit-button" value="Submit" name="submit">
</form>
<div id="empty_case_form" style="display:none">
<ul class='no_error case-formset'>
{{ case_formset.empty_form.as_ul }}
</ul>
</div>
{% endblock %}
+9 -9
View File
@@ -1,12 +1,12 @@
{% extends 'atlas/base.html' %} {% extends 'atlas/base.html' %}
{% block content %} {% block content %}
<ul> <ul>
<li><a href="{% url 'atlas:condition_view' %}">Conditions</a></li> <li><a href="{% url 'atlas:condition_view' %}">Conditions</a></li>
<li><a href="{% url 'atlas:finding_view' %}">Findings</a></li> <li><a href="{% url 'atlas:finding_view' %}">Findings</a></li>
<li><a href="{% url 'atlas:structure_view' %}">Structures</li></a> <li><a href="{% url 'atlas:structure_view' %}">Structures</li></a>
<li><a href="{% url 'atlas:subspecialty_view' %}">Subspecialties</li></a> <li><a href="{% url 'atlas:subspecialty_view' %}">Subspecialties</li></a>
<li><a href="{% url 'atlas:presentation_view' %}">Presentations</li></a> <li><a href="{% url 'atlas:presentation_view' %}">Presentations</li></a>
<li><a href="{% url 'atlas:pathological_process_view' %}">Pathological Process</li></a> <li><a href="{% url 'atlas:pathological_process_view' %}">Pathological Process</li></a>
</ul> </ul>
{% endblock %} {% endblock %}
+8 -8
View File
@@ -1,13 +1,13 @@
{% extends 'atlas/base.html' %} {% extends 'atlas/base.html' %}
{% block content %} {% block content %}
{{category}}: {{category}}:
<ul> <ul>
{% for atlas in atlas %} {% for atlas in atlas %}
<li><a href="{% url 'atlas:case_detail' pk=atlas.pk %}">{{atlas}} <li><a href="{% url 'atlas:case_detail' pk=atlas.pk %}">{{atlas}}
[{{atlas.get_authors}}]</a></li> [{{atlas.get_authors}}]</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
{% endblock %} {% endblock %}
@@ -1,8 +1,8 @@
{% extends 'atlas/base.html' %} {% extends 'atlas/base.html' %}
{% block content %} {% block content %}
{% include 'atlas/collection_headers.html' %} {% include 'atlas/collection_headers.html' %}
{% include "generic/exam_cids.html" %} {% include "generic/exam_cids.html" %}
{% endblock %} {% endblock %}
+118 -118
View File
@@ -1,118 +1,118 @@
{% extends 'atlas/base.html' %} {% extends 'atlas/base.html' %}
{% block content %} {% block content %}
<h2>Case {{case_number|add:1}} <h2>Case {{case_number|add:1}}
{% if collection.show_title %} {% if collection.show_title %}
: {{case.title}} : {{case.title}}
{% endif %} {% endif %}
</h2> </h2>
{% if collection.show_description and case.description%} {% if collection.show_description and case.description%}
<div> <div>
Description: {{case.description}} Description: {{case.description}}
</div> </div>
{% endif %} {% endif %}
{% if collection.show_history and case.history%} {% if collection.show_history and case.history%}
<div> <div>
Description: {{case.history}} Description: {{case.history}}
</div> </div>
{% endif %} {% endif %}
<div class="pre-whitespace multi-image-block"> <div class="pre-whitespace multi-image-block">
{% for series in series_list %} {% for series in series_list %}
<span class="series-block"> <span class="series-block">
<span> <span>
Series {{ forloop.counter }}: Series {{ forloop.counter }}:
<a href="#" onclick='window.loadDicomViewer(window.images[{{forloop.counter0}}])'> <a href="#" onclick='window.loadDicomViewer(window.images[{{forloop.counter0}}])'>
{{series.get_block}} {{series.get_block}}
</a> </a>
</span> </span>
</span> </span>
{% endfor %} {% endfor %}
</div> </div>
<div> <div>
<div id="single-dicom-viewer" class="dicom-viewer" data-images="" data-annotations=''> <div id="single-dicom-viewer" class="dicom-viewer" data-images="" data-annotations=''>
</div> </div>
</div> </div>
{% if collection.show_discussion and case.discussion%} {% if collection.show_discussion and case.discussion%}
<details> <details>
<summary> <summary>
Discussion: Discussion:
</summary> </summary>
<div> <div>
{{case.discussion}} {{case.discussion}}
</div> </div>
</details> </details>
{% endif %} {% endif %}
{% if collection.show_report and case.report%} {% if collection.show_report and case.report%}
<details> <details>
<summary> <summary>
Report: Report:
</summary> </summary>
<div> <div>
{{case.report}} {{case.report}}
</div> </div>
</details> </details>
{% endif %} {% endif %}
{% if take %} {% if take %}
<form method="POST" class="post-form">{% csrf_token %} <form method="POST" class="post-form">{% csrf_token %}
<div class="form-contents"> <div class="form-contents">
{% if collection.publish_results %}<fieldset disabled="disabled">{% endif %} {% if collection.publish_results %}<fieldset disabled="disabled">{% endif %}
{{form}} {{form}}
{% if collection.publish_results %}</fieldset>{% endif %} {% if collection.publish_results %}</fieldset>{% endif %}
</div> </div>
{% if previous > -1 %} {% if previous > -1 %}
<button type="submit" name="previous" class="save btn btn-default">Previous</button> <button type="submit" name="previous" class="save btn btn-default">Previous</button>
{% endif %} {% endif %}
{% if next %} {% if next %}
<button type="submit" name="next" class="save btn btn-default">Next</button> <button type="submit" name="next" class="save btn btn-default">Next</button>
{% else %} {% else %}
{% if not exam.publish_results %} {% if not exam.publish_results %}
<button type="submit" name="save" class="save btn btn-default">Save</button> <button type="submit" name="save" class="save btn btn-default">Save</button>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if collection.publish_results %} {% if collection.publish_results %}
Answer score: {{answer.score}}<br /> Answer score: {{answer.score}}<br />
Answer feedback: {{answer.feedback|safe}} Answer feedback: {{answer.feedback|safe}}
{% endif %} {% endif %}
<br /> <br />
<button type="submit" name="finish" class="save btn btn-default">Overview</button> <button type="submit" name="finish" class="save btn btn-default">Overview</button>
<button type="submit" id="goto-button" value="test" name="goto" class="hide">goto</button> <button type="submit" id="goto-button" value="test" name="goto" class="hide">goto</button>
</form> </form>
{% else %} {% else %}
<div> <div>
{% if previous %} {% if previous %}
<a href="{% url 'atlas:collection_case_view' pk=collection.pk case_number=case_number|add:-1 %}">Previous</a> <a href="{% url 'atlas:collection_case_view' pk=collection.pk case_number=case_number|add:-1 %}">Previous</a>
{% endif %} {% endif %}
{% if next %} {% if next %}
<a href="{% url 'atlas:collection_case_view' pk=collection.pk case_number=case_number|add:1 %}">Next</a> <a href="{% url 'atlas:collection_case_view' pk=collection.pk case_number=case_number|add:1 %}">Next</a>
{% endif %} {% endif %}
</div> </div>
<br /> <br />
Return to <a href='{{collection.get_absolute_url}}'>collection</a> Return to <a href='{{collection.get_absolute_url}}'>collection</a>
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block js %} {% block js %}
<script type="text/javascript"> <script type="text/javascript">
window.images = { window.images = {
{% for series in series_list %} {% for series in series_list %}
{{ forloop.counter0 }}: ["{{ series.get_image_url_array_not_json }}"], {{ forloop.counter0 }}: ["{{ series.get_image_url_array_not_json }}"],
{% endfor %} {% endfor %}
} }
$(document).ready(function () { $(document).ready(function () {
setTimeout(() => { setTimeout(() => {
window.loadDicomViewer(window.images[0]) window.loadDicomViewer(window.images[0])
}, 500); }, 500);
}) })
</script> </script>
{% endblock js %} {% endblock js %}
+10 -10
View File
@@ -1,14 +1,14 @@
{% extends 'atlas/base.html' %} {% extends 'atlas/base.html' %}
{% block content %} {% block content %}
{% include 'atlas/collection_headers.html' %} {% include 'atlas/collection_headers.html' %}
<ul> <ul>
{% for case in collection.cases.all %} {% for case in collection.cases.all %}
<li><a href="{% url 'atlas:collection_case_view' pk=collection.pk case_number=forloop.counter0 %}">Case {{forloop.counter}}</a> <li><a href="{% url 'atlas:collection_case_view' pk=collection.pk case_number=forloop.counter0 %}">Case {{forloop.counter}}</a>
: {{case.title}} : {{case.title}}
</li> </li>
{% endfor %}
</ul>
{% endblock %} {% endfor %}
</ul>
{% endblock %}
+13 -13
View File
@@ -1,20 +1,20 @@
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
Collection: {{collection.name}}-> <a href="{% url 'atlas:collection_detail' pk=collection.pk %}">Overview</a> / Collection: {{collection.name}}-> <a href="{% url 'atlas:collection_detail' pk=collection.pk %}">Overview</a> /
<a href="{% url 'atlas:collection_mark_overview' collection.pk %}">Mark</a> / <a href="{% url 'atlas:collection_mark_overview' collection.pk %}">Mark</a> /
<a href="{% url 'atlas:collection_scores_cid' collection.pk %}">Scores</a> / <a href="{% url 'atlas:collection_scores_cid' collection.pk %}">Scores</a> /
<a href="{% url 'atlas:collection_candidates' collection.pk %}">Candidates</a> <a href="{% url 'atlas:collection_candidates' collection.pk %}">Candidates</a>
<div class="floating-header"> <div class="floating-header">
<a href="{% url 'atlas:collection_update' collection.id %}" title="Edit the Collection">Edit</a> <a href="{% url 'atlas:collection_update' collection.id %}" title="Edit the Collection">Edit</a>
\ <a href="{% url 'atlas:collection_delete' collection.id %}" title="Delete the Collection">Delete</a> \ <a href="{% url 'atlas:collection_delete' collection.id %}" title="Delete the Collection">Delete</a>
{% comment %} \ <a href="{% url 'atlas:collection_clone' collection.id %}" title="Clone the Collection">Clone</a> {% endcomment %} {% comment %} \ <a href="{% url 'atlas:collection_clone' collection.id %}" title="Clone the Collection">Clone</a> {% endcomment %}
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
\ <a href="{% url 'admin:atlas_casecollection_change' collection.id %}" title="Edit the Collection using the admin interface">Admin Edit</a> \ <a href="{% url 'admin:atlas_casecollection_change' collection.id %}" title="Edit the Collection using the admin interface">Admin Edit</a>
{% endif %} {% endif %}
</div> </div>
{% endif %} {% endif %}
<h2>{{collection.name}}</h2> <h2>{{collection.name}}</h2>
{% include 'exam_notes.html' %} {% include 'exam_notes.html' %}
@@ -1,10 +1,10 @@
{% extends 'atlas/base.html' %} {% extends 'atlas/base.html' %}
{% block content %} {% block content %}
<a href="{% url 'atlas:collection_create' %}">Create collection</a> <a href="{% url 'atlas:collection_create' %}">Create collection</a>
<ul> <ul>
{% for collection in collections %} {% for collection in collections %}
<li><a href='{{collection.get_absolute_url}}'>{{collection.name}}</a></li> <li><a href='{{collection.get_absolute_url}}'>{{collection.name}}</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
{% endblock %} {% endblock %}
@@ -1,30 +1,30 @@
{% extends 'atlas/base.html' %} {% extends 'atlas/base.html' %}
{% block content %} {% block content %}
{% include 'atlas/collection_headers.html' %} {% include 'atlas/collection_headers.html' %}
<div class="vstack gap-3"> <div class="vstack gap-3">
{% for case_detail, answers in case_map.items %} {% for case_detail, answers in case_map.items %}
<div class="border border-dark"> <div class="border border-dark">
<h4>Case: {{case_detail.case.title}}</h4> <h4>Case: {{case_detail.case.title}}</h4>
Answers Answers
<ul> <ul>
{% for answer in answers %} {% for answer in answers %}
<li {% if not answer.score %}class="flagged"{% endif %}>{{answer.answer}} <li {% if not answer.score %}class="flagged"{% endif %}>{{answer.answer}}
{% if not answer.score %} {% if not answer.score %}
<span class="badge rounded-pill bg-danger">Unmarked</span> <span class="badge rounded-pill bg-danger">Unmarked</span>
{% else %}
<span class="badge rounded-pill bg-info">Score: {{answer.score}}</span>
{% endif %}
</li>
{% endfor %}
</ul>
<a href="{% url 'atlas:collection_mark_question' collection.pk forloop.counter0 %}">Mark</a>
</div>
{% endfor %}
</div>
{% endblock %} {% else %}
<span class="badge rounded-pill bg-info">Score: {{answer.score}}</span>
{% endif %}
</li>
{% endfor %}
</ul>
<a href="{% url 'atlas:collection_mark_question' collection.pk forloop.counter0 %}">Mark</a>
</div>
{% endfor %}
</div>
{% endblock %}
@@ -3,11 +3,12 @@
{% block content %} {% block content %}
{% include 'atlas/collection_headers.html' %} {% include 'atlas/collection_headers.html' %}
<h3>Marking case: {{case.title}}</h3> <h3>Marking case: {{case.title}}</h3>
<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasTop" aria-controls="offcanvasTop">View Case</button>
<form method="POST" class="post-form">{% csrf_token %} <form method="POST" class="post-form">{% csrf_token %}
<div class="vstack gap-3"> <div class="vstack gap-3">
{% for answer, form in answer_forms %} {% for answer, form in answer_forms %}
<div class="border border-dark"> <div class="border border-dark">
CID: {{answer.cid}}<br /> CID: {{answer.cid}}<br />
Answer: {{answer.answer}} <br /> Answer: {{answer.answer}} <br />
Score: {{answer.score}}<br /> Score: {{answer.score}}<br />
@@ -31,4 +32,24 @@
</form> </form>
<div class="offcanvas offcanvas-top" tabindex="-1" id="offcanvasTop" aria-labelledby="offcanvasTopLabel">
<div class="offcanvas-header">
<h5 id="offcanvasTopLabel">Offcanvas top</h5>
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
{% for series in series_list %}
<span class="series-block">
<span>
Series {{ forloop.counter }}:
<a href="#" onclick='window.loadDicomViewer(window.images[{{forloop.counter0}}])'>
{{series.get_block}}
</a>
</span>
</span>
{% endfor %}
</div>
</div>
{% endblock %} {% endblock %}
@@ -1,172 +1,172 @@
<div>{{ series.modality}}, {{ series.examination }}, {{ series.plane }}, {{ series.contrast }}</div> <div>{{ series.modality}}, {{ series.examination }}, {{ series.plane }}, {{ series.contrast }}</div>
<div id="single-dicom-viewer" class="dicom-viewer" data-images="{{ series.get_image_url_array }}" data-annotations=''> <div id="single-dicom-viewer" class="dicom-viewer" data-images="{{ series.get_image_url_array }}" data-annotations=''>
</div> </div>
{% if editing_finding < 1 %} {% if editing_finding < 1 %}
<button id="add-finding-button">Add finding</button> <button id="add-finding-button">Add finding</button>
{% endif %} {% endif %}
<button id="reset-viewport-button">Reset viewport</button> <button id="reset-viewport-button">Reset viewport</button>
<div id="finding-form"> <div id="finding-form">
<div class="hide" id="hidden-form"> <div class="hide" id="hidden-form">
<form method="post" id="series_finding_form"> <form method="post" id="series_finding_form">
{% csrf_token %} {% csrf_token %}
{{series_finding_form.management_form}} {{series_finding_form.management_form}}
<div> <div>
<div>Description: {{ series_finding_form.description }}</div> <div>Description: {{ series_finding_form.description }}</div>
<div>Findings: {{ series_finding_form.findings }}</div> <div>Findings: {{ series_finding_form.findings }}</div>
<div>Structures: {{ series_finding_form.structures }}</div> <div>Structures: {{ series_finding_form.structures }}</div>
</div> </div>
<input type="submit" value="Submit"> <input type="submit" value="Submit">
<button id="cancel-add-finding-button">Cancel</button> <button id="cancel-add-finding-button">Cancel</button>
</form> </form>
</div> </div>
</div> </div>
<details open> <details open>
<summary>Findings</summary> <summary>Findings</summary>
{% for finding in series.findings.all %} {% for finding in series.findings.all %}
<div class="finding-box"> <div class="finding-box">
<button class="view-finding-button" data-annotationjson={{finding.annotation_json}} <button class="view-finding-button" data-annotationjson={{finding.annotation_json}}
data-viewportjson={{finding.viewport_json}} data-findingid={{finding.id}}>Click to view</button> data-viewportjson={{finding.viewport_json}} data-findingid={{finding.id}}>Click to view</button>
<span class="view-finding-details"> <span class="view-finding-details">
Finding(s): {% for f in finding.findings.all %}{{f.get_link}}{% endfor %}<br /> Finding(s): {% for f in finding.findings.all %}{{f.get_link}}{% endfor %}<br />
Structure(s): {% for s in finding.structures.all %}{{s.get_link}}{% endfor %}<br /> Structure(s): {% for s in finding.structures.all %}{{s.get_link}}{% endfor %}<br />
Description: {{finding.description}}<br /> Description: {{finding.description}}<br />
</span> </span>
<a href="{% url 'atlas:series_edit_finding' pk=series.pk finding_pk=finding.pk %}" class="edit-finding-link">Edit</a> <a href="{% url 'atlas:series_edit_finding' pk=series.pk finding_pk=finding.pk %}" class="edit-finding-link">Edit</a>
<a href="{% url 'atlas:delete_finding' pk=finding.pk %}" class="delete-finding-link">Delete</a> <a href="{% url 'atlas:delete_finding' pk=finding.pk %}" class="delete-finding-link">Delete</a>
</div> </div>
{% endfor %} {% endfor %}
</details> </details>
<div>Author: {{ series.get_author_display }}</div> <div>Author: {{ series.get_author_display }}</div>
<details> <details>
<summary>Image info</summary> <summary>Image info</summary>
<div> <div>
<a href="{% url 'atlas:series_order_dicom' pk=series.pk %}" title="orders dicom by slice location">Order dicoms <a href="{% url 'atlas:series_order_dicom' pk=series.pk %}" title="orders dicom by slice location">Order dicoms
by slice location</a> by slice location</a>
<a href="{% url 'atlas:series_order_dicom_instance' pk=series.pk %}" <a href="{% url 'atlas:series_order_dicom_instance' pk=series.pk %}"
title="orders dicom by instance number">Order dicoms by instance number</a> title="orders dicom by instance number">Order dicoms by instance number</a>
<a href="{% url 'atlas:series_order_dicom_SeriesInstanceUID' pk=series.pk %}" <a href="{% url 'atlas:series_order_dicom_SeriesInstanceUID' pk=series.pk %}"
title="orders dicom by instance number">Order dicoms by SeriesInstanceUID</a> title="orders dicom by instance number">Order dicoms by SeriesInstanceUID</a>
<a href="{% url 'atlas:series_order_upload_filename' pk=series.pk %}" <a href="{% url 'atlas:series_order_upload_filename' pk=series.pk %}"
title="orders dicom by uploaded filename">Order by uploaded filename</a> title="orders dicom by uploaded filename">Order by uploaded filename</a>
</div> </div>
{% for image in series.images.all %} {% for image in series.images.all %}
{{image.image.url}}, pos: {{image.position}}, {{image.upload_filename}} [{{image.image.size|filesizeformat}}]<br /> {{image.image.url}}, pos: {{image.position}}, {{image.upload_filename}} [{{image.image.size|filesizeformat}}]<br />
{% comment %} {{image.get_dicom_info|safe}}<br /> {% endcomment %} {% comment %} {{image.get_dicom_info|safe}}<br /> {% endcomment %}
{% endfor %} {% endfor %}
<p>Total image size: {{series.get_total_image_size|filesizeformat}}</p> <p>Total image size: {{series.get_total_image_size|filesizeformat}}</p>
<p><a href="{% url 'atlas:series_download' pk=series.pk %}">Download images</a></p> <p><a href="{% url 'atlas:series_download' pk=series.pk %}">Download images</a></p>
</details> </details>
<script> <script>
$(document).ready(function () { $(document).ready(function () {
$("#add-finding-button").click(() => { $("#add-finding-button").click(() => {
dicom_element = $(".cornerstone-element").get(0); dicom_element = $(".cornerstone-element").get(0);
cornerstoneTools.globalImageIdSpecificToolStateManager.clear(dicom_element); cornerstoneTools.globalImageIdSpecificToolStateManager.clear(dicom_element);
cornerstone.reset(dicom_element); cornerstone.reset(dicom_element);
cornerstone.resize(dicom_element, true); cornerstone.resize(dicom_element, true);
//$("#finding-form").empty().append( //$("#finding-form").empty().append(
// $("#hidden-form form").clone() // $("#hidden-form form").clone()
//); //);
$("#hidden-form").show() $("#hidden-form").show()
}); });
$("#cancel-add-finding-button").click((e) => { $("#cancel-add-finding-button").click((e) => {
$("#hidden-form").hide() $("#hidden-form").hide()
e.preventDefault(); e.preventDefault();
}); });
$("#reset-viewport-button").click(() => { $("#reset-viewport-button").click(() => {
dicom_element = $(".cornerstone-element").get(0); dicom_element = $(".cornerstone-element").get(0);
//annotationjson = JSON.parse(e.currentTarget.dataset.annotationjson); //annotationjson = JSON.parse(e.currentTarget.dataset.annotationjson);
cornerstoneTools.globalImageIdSpecificToolStateManager.clear(dicom_element); cornerstoneTools.globalImageIdSpecificToolStateManager.clear(dicom_element);
cornerstone.reset(dicom_element); cornerstone.reset(dicom_element);
cornerstone.resize(dicom_element, true); cornerstone.resize(dicom_element, true);
}); });
$(".view-finding-button").each((n, el) => { $(".view-finding-button").each((n, el) => {
$(el).click((e) => { $(el).click((e) => {
dicom_element = $(".cornerstone-element").get(0); dicom_element = $(".cornerstone-element").get(0);
annotationjson = JSON.parse(e.currentTarget.dataset.annotationjson); annotationjson = JSON.parse(e.currentTarget.dataset.annotationjson);
viewport = JSON.parse(e.currentTarget.dataset.viewportjson); viewport = JSON.parse(e.currentTarget.dataset.viewportjson);
loadAnnotationAndViewportOnElement(annotationjson, viewport, dicom_element); loadAnnotationAndViewportOnElement(annotationjson, viewport, dicom_element);
}); });
}); });
{% if editing_finding > 0 %} {% if editing_finding > 0 %}
$("#hidden-form").show() $("#hidden-form").show()
setTimeout(function() { setTimeout(function() {
$(".view-finding-button[data-findingid={{editing_finding}}]").trigger("click"); $(".view-finding-button[data-findingid={{editing_finding}}]").trigger("click");
}, 1000) }, 1000)
{% endif %} {% endif %}
}); });
function loadAnnotationAndViewportOnElement(annotation, viewport, dicom_element) { function loadAnnotationAndViewportOnElement(annotation, viewport, dicom_element) {
cornerstoneTools.globalImageIdSpecificToolStateManager.clear(dicom_element); cornerstoneTools.globalImageIdSpecificToolStateManager.clear(dicom_element);
cornerstone.getEnabledElement(dicom_element).viewport = viewport cornerstone.getEnabledElement(dicom_element).viewport = viewport
cornerstoneTools.globalImageIdSpecificToolStateManager.restoreToolState( cornerstoneTools.globalImageIdSpecificToolStateManager.restoreToolState(
annotation); annotation);
console.log(annotation) console.log(annotation)
//cornerstone.getEnabledElement(dicom_element).toolStateManager.restoreToolState(annotationjson) //cornerstone.getEnabledElement(dicom_element).toolStateManager.restoreToolState(annotationjson)
cornerstone.resize(dicom_element); cornerstone.resize(dicom_element);
dicomViewer.getNextAnnotationImage(dicom_element); dicomViewer.getNextAnnotationImage(dicom_element);
} }
$(document).on('submit', '#series_finding_form', function (e) { $(document).on('submit', '#series_finding_form', function (e) {
dicom_element = $(".cornerstone-element").get(0); dicom_element = $(".cornerstone-element").get(0);
c = cornerstone.getEnabledElement(dicom_element); c = cornerstone.getEnabledElement(dicom_element);
e.preventDefault(); e.preventDefault();
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
url: '{% url "atlas:add_finding" %}', url: '{% url "atlas:add_finding" %}',
data: { data: {
series_finding_id: {{ editing_finding }}, series_finding_id: {{ editing_finding }},
description: $('#id_description').val(), description: $('#id_description').val(),
series: {{ series.pk }}, series: {{ series.pk }},
//annotation_json: JSON.stringify(c.toolStateManager.saveToolState()), //annotation_json: JSON.stringify(c.toolStateManager.saveToolState()),
annotation_json: JSON.stringify(cornerstoneTools.globalImageIdSpecificToolStateManager annotation_json: JSON.stringify(cornerstoneTools.globalImageIdSpecificToolStateManager
.saveToolState()), .saveToolState()),
viewport_json: JSON.stringify(c.viewport), viewport_json: JSON.stringify(c.viewport),
findings: JSON.stringify($('#finding-form select[name="findings"]').find(":selected") findings: JSON.stringify($('#finding-form select[name="findings"]').find(":selected")
.map((i, el) => { .map((i, el) => {
return $(el).val() return $(el).val()
}).toArray()), }).toArray()),
structures: JSON.stringify($('#finding-form select[name="structures"]').find( structures: JSON.stringify($('#finding-form select[name="structures"]').find(
":selected") ":selected")
.map((i, el) => { .map((i, el) => {
return $(el).val() return $(el).val()
}).toArray()), }).toArray()),
csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(), csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
action: 'post' action: 'post'
}, },
success: function (json) { success: function (json) {
$("#finding-form").empty(); $("#finding-form").empty();
toastr.info('Finding added.'); toastr.info('Finding added.');
location.href='{{series.get_absolute_url}}'; location.href='{{series.get_absolute_url}}';
}, },
error: function (xhr, errmsg, err) { error: function (xhr, errmsg, err) {
console.log(xhr.status + ": " + xhr console.log(xhr.status + ": " + xhr
.responseText); // provide a bit more info about the error to the console .responseText); // provide a bit more info about the error to the console
} }
}); });
}); });
</script> </script>
+44 -44
View File
@@ -1,53 +1,53 @@
{% extends 'atlas/base.html' %} {% extends 'atlas/base.html' %}
{% block content %} {% block content %}
<h2>{{collection.name}} <h2>{{collection.name}}
<ul> <ul>
</ul> </ul>
{% if collection.collection_type == "REP" %} {% if collection.collection_type == "REP" %}
<h2>Start: {{exam.name}}</h2> <h2>Start: {{exam.name}}</h2>
Enter your CID and passcode in the below boxes.<br /> Enter your CID and passcode in the below boxes.<br />
<p><input id="cid-box" type="text" value="Candidate ID"></p> <p><input id="cid-box" type="text" value="Candidate ID"></p>
<p><input id="passcode-box" type="text" value="Passcode"></p> <p><input id="passcode-box" type="text" value="Passcode"></p>
<button>Start</button> <button>Start</button>
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function () { $(document).ready(function () {
window.location.search.substr(1).split("&").forEach((item) => window.location.search.substr(1).split("&").forEach((item) =>
{ {
s = item.split("="); s = item.split("=");
if (s[0] == "cid") { if (s[0] == "cid") {
$("#cid-box").val(s[1]); $("#cid-box").val(s[1]);
} }
if (s[0] == "passcode") { if (s[0] == "passcode") {
$("#passcode-box").val(s[1]); $("#passcode-box").val(s[1]);
} }
});
$("#cid-box, #passcode-box").keypress(function(e) {
// Enter pressed?
console.log(e)
if(e.which == 10 || e.which == 13) {
$("button").click();
}
});
$("button").click(() => {
let cid = $("#cid-box").val();
let passcode = $("#passcode-box").val();
if (Number.isInteger(parseInt(cid))) {
window.location.replace("{% url 'atlas:collection_case_view_take' pk=collection.pk case_number=0 cid='0000000' passcode='ZZZZZZ' %}".replace("0000000", cid).replace("ZZZZZZ", passcode));
} else {
alert("Please enter a valid Candidate ID (CID).")
}
});
}); });
</script>
{% endif %}
{% endblock %}
$("#cid-box, #passcode-box").keypress(function(e) {
// Enter pressed?
console.log(e)
if(e.which == 10 || e.which == 13) {
$("button").click();
}
});
$("button").click(() => {
let cid = $("#cid-box").val();
let passcode = $("#passcode-box").val();
if (Number.isInteger(parseInt(cid))) {
window.location.replace("{% url 'atlas:collection_case_view_take' pk=collection.pk case_number=0 cid='0000000' passcode='ZZZZZZ' %}".replace("0000000", cid).replace("ZZZZZZ", passcode));
} else {
alert("Please enter a valid Candidate ID (CID).")
}
});
});
</script>
{% endif %}
{% endblock %}
+15 -15
View File
@@ -4,23 +4,23 @@
{% block css %} {% block css %}
{% endblock %} {% endblock %}
{% block js %} {% block js %}
<!--<script type="text/javascript" src="/admin/jsi18n/"></script>--> <!--<script type="text/javascript" src="/admin/jsi18n/"></script>-->
{{form.media}} {{form.media}}
<script type="text/javascript"> <script type="text/javascript">
</script> </script>
<!-- {{ form.media }} --> <!-- {{ form.media }} -->
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h2>Add/Edit Condition</h2> <h2>Add/Edit Condition</h2>
Use this form to create or edit a condition. Use this form to create or edit a condition.
<form action="" method="post" enctype="multipart/form-data" id="condition-form"> <form action="" method="post" enctype="multipart/form-data" id="condition-form">
{% csrf_token %} {% csrf_token %}
<table> <table>
{{ form.as_table }} {{ form.as_table }}
</table> </table>
<input type="submit" class="submit-button" value="Submit" name="submit"> <input type="submit" class="submit-button" value="Submit" name="submit">
</form> </form>
{% endblock %} {% endblock %}
+15 -15
View File
@@ -4,23 +4,23 @@
{% block css %} {% block css %}
{% endblock %} {% endblock %}
{% block js %} {% block js %}
<!--<script type="text/javascript" src="/admin/jsi18n/"></script>--> <!--<script type="text/javascript" src="/admin/jsi18n/"></script>-->
{{form.media}} {{form.media}}
<script type="text/javascript"> <script type="text/javascript">
</script> </script>
<!-- {{ form.media }} --> <!-- {{ form.media }} -->
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h2>Add/Edit Finding</h2> <h2>Add/Edit Finding</h2>
Use this form to create or edit a finding. Use this form to create or edit a finding.
<form action="" method="post" enctype="multipart/form-data" id="finding-form"> <form action="" method="post" enctype="multipart/form-data" id="finding-form">
{% csrf_token %} {% csrf_token %}
<table> <table>
{{ form.as_table }} {{ form.as_table }}
</table> </table>
<input type="submit" class="submit-button" value="Submit" name="submit"> <input type="submit" class="submit-button" value="Submit" name="submit">
</form> </form>
{% endblock %} {% endblock %}
@@ -5,7 +5,7 @@
<div class="floating-header"> <div class="floating-header">
{% comment %} <a href="{% url 'atlas:pathological_process_update' pk=pathological_process.pk %}" title="Edit the Condition">Edit</a> {% comment %} <a href="{% url 'atlas:pathological_process_update' pk=pathological_process.pk %}" title="Edit the Condition">Edit</a>
<a href="{% url 'atlas:pathological_process_delete' pk=pathological_process.pk %}" title="Delete the Condition">Delete</a> {% endcomment %} <a href="{% url 'atlas:pathological_process_delete' pk=pathological_process.pk %}" title="Delete the Condition">Delete</a> {% endcomment %}
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
<a href="{% url 'admin:atlas_pathologicalprocess_change' pathological_process.id %}" <a href="{% url 'admin:atlas_pathologicalprocess_change' pathological_process.id %}"
@@ -5,7 +5,7 @@
<div class="floating-header"> <div class="floating-header">
{% comment %} <a href="{% url 'atlas:presentation_update' pk=presentation.pk %}" title="Edit the Condition">Edit</a> {% comment %} <a href="{% url 'atlas:presentation_update' pk=presentation.pk %}" title="Edit the Condition">Edit</a>
<a href="{% url 'atlas:presentation_delete' pk=presentation.pk %}" title="Delete the Condition">Delete</a> {% endcomment %} <a href="{% url 'atlas:presentation_delete' pk=presentation.pk %}" title="Delete the Condition">Delete</a> {% endcomment %}
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
<a href="{% url 'admin:atlas_presentation_change' presentation.id %}" <a href="{% url 'admin:atlas_presentation_change' presentation.id %}"
+327 -327
View File
@@ -3,118 +3,118 @@
{% load static %} {% load static %}
{% block js %} {% block js %}
<!--<script type="text/javascript" src="/admin/jsi18n/"></script>--> <!--<script type="text/javascript" src="/admin/jsi18n/"></script>-->
<script type="text/javascript"> <script type="text/javascript">
document.addEventListener('drop', function (e) { e.preventDefault(); }, false); document.addEventListener('drop', function (e) { e.preventDefault(); }, false);
function add_input_form() { function add_input_form() {
var form_idx = $('#id_images-TOTAL_FORMS').val(); var form_idx = $('#id_images-TOTAL_FORMS').val();
$('#image_form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx)); $('#image_form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
$('#id_images-TOTAL_FORMS').val(parseInt(form_idx) + 1); $('#id_images-TOTAL_FORMS').val(parseInt(form_idx) + 1);
} }
$(document).ready(function () { $(document).ready(function () {
$("#add_examination").appendTo($("label[for='id_examination']")); $("#add_examination").appendTo($("label[for='id_examination']"));
dropContainer = document.getElementById("drop-container"); dropContainer = document.getElementById("drop-container");
dropContainer.ondragover = function (evt) { dropContainer.ondragover = function (evt) {
evt.preventDefault(); evt.preventDefault();
evt.stopPropagation(); evt.stopPropagation();
}; };
dropContainer.ondragenter = function (evt) { dropContainer.ondragenter = function (evt) {
console.log("ENTER") console.log("ENTER")
console.log(evt) console.log(evt)
$(evt.target).addClass("drop-target-active") $(evt.target).addClass("drop-target-active")
evt.preventDefault(); evt.preventDefault();
evt.stopPropagation(); evt.stopPropagation();
}; };
dropContainer.ondragleave = function (evt) { dropContainer.ondragleave = function (evt) {
console.log("ENTER") console.log("ENTER")
console.log(evt) console.log(evt)
$(evt.target).removeClass("drop-target-active") $(evt.target).removeClass("drop-target-active")
evt.preventDefault(); evt.preventDefault();
evt.stopPropagation(); evt.stopPropagation();
}; };
dropContainer.ondrop = function (evt) { dropContainer.ondrop = function (evt) {
$(evt.target).removeClass("drop-target-active"); $(evt.target).removeClass("drop-target-active");
if (evt.dataTransfer.files.length < 1) { if (evt.dataTransfer.files.length < 1) {
toastr.warning(`Drop failed :( try again?`); toastr.warning(`Drop failed :( try again?`);
} else { } else {
toastr.info(`Adding ${evt.dataTransfer.files.length} files.`); toastr.info(`Adding ${evt.dataTransfer.files.length} files.`);
}
// Get all input elements
inputs = $("#atlas-form input[type=file][id^=id_images-]");
//fileInput = document.getElementById("id_images-0-image");
// Make sure we have enough input targets
input_diff = (evt.dataTransfer.files.length - inputs.length)
if (input_diff > 0) {
for (let j = 0; j < input_diff; j++) {
add_input_form()
} }
// Need to make sure we include the new ones... // Get all input elements
inputs = $("#atlas-form input[type=file][id^=id_images-]"); inputs = $("#atlas-form input[type=file][id^=id_images-]");
} //fileInput = document.getElementById("id_images-0-image");
// Loop through each dropped file and try to assign to an // Make sure we have enough input targets
// input element input_diff = (evt.dataTransfer.files.length - inputs.length)
[...evt.dataTransfer.files].forEach((f) => {
let dT = new DataTransfer();
dT.clearData();
dT.items.add(f);
for (let i = 0; i < inputs.length; i++) {
el = inputs.get(i)
if (el.files.length == 0) { if (input_diff > 0) {
el.files = dT.files; for (let j = 0; j < input_diff; j++) {
//ocr(el) add_input_form()
return false
} }
// Need to make sure we include the new ones...
inputs = $("#atlas-form input[type=file][id^=id_images-]");
} }
})
// // If you want to use some of the dropped files // Loop through each dropped file and try to assign to an
// const dT = new DataTransfer(); // input element
// dT.items.add(evt.dataTransfer.files[0]); [...evt.dataTransfer.files].forEach((f) => {
// dT.items.add(evt.dataTransfer.files[3]); let dT = new DataTransfer();
// fileInput.files = dT.files; dT.clearData();
dT.items.add(f);
for (let i = 0; i < inputs.length; i++) {
el = inputs.get(i)
loadDicomViewerAndFileImages(); if (el.files.length == 0) {
el.files = dT.files;
//ocr(el)
evt.preventDefault(); return false
evt.stopPropagation(); }
}; }
})
// // If you want to use some of the dropped files
// const dT = new DataTransfer();
// dT.items.add(evt.dataTransfer.files[0]);
// dT.items.add(evt.dataTransfer.files[3]);
// fileInput.files = dT.files;
loadDicomViewerAndFileImages();
evt.preventDefault();
evt.stopPropagation();
};
$('#add_more_images').click(() => { add_input_form() }); $('#add_more_images').click(() => { add_input_form() });
$("input[type=file]").on('change', function () { $("input[type=file]").on('change', function () {
$(this).removeClass("image-ident-warning"); $(this).removeClass("image-ident-warning");
$(this).removeClass("image-ident-ok"); $(this).removeClass("image-ident-ok");
console.log("input change1"); console.log("input change1");
console.log("input change", this); console.log("input change", this);
//ocr(this); //ocr(this);
//LoadDicomViewer(); //LoadDicomViewer();
}); });
sortable('.sortable'); sortable('.sortable');
sortable('.sortable')[0].addEventListener('sortupdate', function (e) { sortable('.sortable')[0].addEventListener('sortupdate', function (e) {
/* /*
This event is triggered when the user stops sorting and the DOM position has not yet changed. This event is triggered when the user stops sorting and the DOM position has not yet changed.
@@ -125,262 +125,262 @@
e.detail.origin.elementIndex - {Integer} Index of the element in all elements in the Sortable Container e.detail.origin.elementIndex - {Integer} Index of the element in all elements in the Sortable Container
e.detail.origin.container - {HTMLElement} Sortable Container that element was moved out of (or copied from) e.detail.origin.container - {HTMLElement} Sortable Container that element was moved out of (or copied from)
*/ */
//updateImagePositions(); //updateImagePositions();
$(".temp-thumb").remove() $(".temp-thumb").remove()
loadDicomViewer(); loadDicomViewer();
});
});
function ocr(input) {
// Tesseract.recognize(f, "eng",{ logger: m => console.log(m) }
// ).then(({ data: { text } }) => {
// console.log(text);
// l = text.toLowerCase();
// if (l.includes("accesion") || l.includes("number") || l.search(/(REF|RK9|RH8|RA9)\d+/g)) {
// console.log("SHIT", this);
// }
// })
console.log('{% static "worker.min.js" %}');
console.log('{{ STATIC_URL }}/tesseract-core.wasm.js %}');
const worker = Tesseract.createWorker({
workerPath: '{% static "worker.min.js" %}',
langPath: '{% static "" %}',
//langPath: '{{ STATIC_URL }}',
corePath: '{% static "tesseract-core.wasm.js" %}',
});
const url = URL.createObjectURL(input.files[0]);
let img = new Image;
img.src = url;
img.onload = function () {
width = img.width;
// const rectangle = { left: 0, top: 0, width: width, height: 10 }
(async () => {
await worker.load();
await worker.loadLanguage('eng');
await worker.initialize('eng');
// const { data: { text } } = await worker.recognize(input.files[0], { rectangle });
const { data: { text } } = await worker.recognize(input.files[0]);
//console.log(text);
l = text.toLowerCase();
$(`img[data-input-id='${input.id}'`).removeClass("image-ident-loading");
console.log(l);
if (l.includes("accesion") || l.includes("number") || l.search(/(ref|rk9|rh8|ra9|rbz)\d+/g) > -1) {
$(input).addClass("image-ident-warning");
$(`img[data-input-id='${input.id}'`).addClass("image-ident-warning");
} else {
$(input).addClass("image-ident-ok");
}
await worker.terminate();
})();
}
}
async function loadDicomViewerAndFileImages(callback) {
$("#single-dicom-viewer").empty()
//images = []
//Function that returns a promise to read the file
const reader = (file) => {
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = () => resolve(fileReader);
fileReader.readAsDataURL(file);
}); });
}
const readFile = (file, el) => {
reader(file).then(reader => {
console.log("hello", file, el, image)
if ($("#id_examination").find(":selected")[0].dataset.select2Id == "2") {
var byteArray = new Uint8Array(reader.result);
console.log("etrxact")
extractDicomStudyDescription(byteArray);
}
var image = new Image();
image.height = 100;
image.title = file.name;
image.src = reader.result;
image.className = "temp-thumb";
console.log("read", el);
$(el).parent().parent().prepend(image);
//images.push(reader.result);
loadViewer(images);
});
}
file_set = $("#image_form_set input[type=file]");
file_set.each(async (n, el) => {
console.log(el);
if (el.files.length > 0) {
filename = el.files[0].name;
await readFile(el.files[0], el);
}
})
console.log("images from files", images);
}
function loadViewer(images) {
//dicomViewer.loadCornerstone($("#single-dicom-viewer"), null, images, annotations);
file_set = $("#image_form_set input[type=file]");
n = 0;
for (let i = 0; i < file_set.length; i++) {
el = file_set.get(i)
if (el.files.length > 0) {
n++;
}
}
image_set = $("#image_form_set img");
if (n == image_set.length) {
const event = new CustomEvent('loadDicomViewer', { "detail": image_set });
window.dispatchEvent(event);
sortable('.sortable');
//sortable('.sortable')[0].addEventListener('sortstop', function(e) {
updateImagePositions();
}
}
function updateImagePositions() {
console.log("UP pos");
file_set = $("#image_form_set ul");
n = 0;
for (let i = 0; i < file_set.length; i++) {
ul = file_set.get(i);
console.log(ul)
file_element = $(ul).find("input[type=file]").get(0);
// If a (new) file is being uploaded we save it's name prior to it being hashed
if (file_element.files.length > 0) {
file_name = file_element.files[0].name
$(ul).find("input[type=text]").val(file_name);
}
if (file_element.files.length > 0 || $(ul).find(":contains('Currently:')")) {
n++;
$(ul).find("input[type=number]").val(n);
}
}
}
function extractDicomStudyDescription(byteArray) {
// We need to setup a try/catch block because parseDicom will throw an exception
// if you attempt to parse a non dicom part 10 file (or one that is corrupted)
try {
// parse byteArray into a DataSet object using the parseDicom library
var dataSet = dicomParser.parseDicom(byteArray);
// dataSet contains the parsed elements. Each element is available via a property
// in the dataSet.elements object. The property name is based on the elements group
// and element in the following format: xggggeeee where gggg is the group number
// and eeee is the element number with lowercase hex characters.
// To access the data for an element, we need to know its type and its tag.
// We will get the sopInstanceUid from the file which is a string and
// has the tag (0020,000D)
var study_description = dataSet.string('x00081030').toLowerCase();
console.log("STUDY", study_description);
$.ajax({
url: `{% url 'generic:examination-autocomplete' %}/${encodeURI(study_description)}`,
//context: document.body,
success: function(data){
console.log(data)
}
}); });
// try to match with a study description (if not already selected)
if ($(`#id_examination_to option`).length < 1) {
option = $(`#id_examination_from option[title*='${study_description}' i]`);
if (option.length) {
option.appendTo($("#id_examination_to"));
toastr.success(`Examination set to ${option.attr('title')} from dicom data`);
} else {
toastr.warning(
`Unable to set examination ${study_description} from dicom data (it needs creating)`);
function ocr(input) {
// Tesseract.recognize(f, "eng",{ logger: m => console.log(m) }
// ).then(({ data: { text } }) => {
// console.log(text);
// l = text.toLowerCase();
// if (l.includes("accesion") || l.includes("number") || l.search(/(REF|RK9|RH8|RA9)\d+/g)) {
// console.log("SHIT", this);
// }
// })
console.log('{% static "worker.min.js" %}');
console.log('{{ STATIC_URL }}/tesseract-core.wasm.js %}');
const worker = Tesseract.createWorker({
workerPath: '{% static "worker.min.js" %}',
langPath: '{% static "" %}',
//langPath: '{{ STATIC_URL }}',
corePath: '{% static "tesseract-core.wasm.js" %}',
});
const url = URL.createObjectURL(input.files[0]);
let img = new Image;
img.src = url;
img.onload = function () {
width = img.width;
// const rectangle = { left: 0, top: 0, width: width, height: 10 }
(async () => {
await worker.load();
await worker.loadLanguage('eng');
await worker.initialize('eng');
// const { data: { text } } = await worker.recognize(input.files[0], { rectangle });
const { data: { text } } = await worker.recognize(input.files[0]);
//console.log(text);
l = text.toLowerCase();
$(`img[data-input-id='${input.id}'`).removeClass("image-ident-loading");
console.log(l);
if (l.includes("accesion") || l.includes("number") || l.search(/(ref|rk9|rh8|ra9|rbz)\d+/g) > -1) {
$(input).addClass("image-ident-warning");
$(`img[data-input-id='${input.id}'`).addClass("image-ident-warning");
} else {
$(input).addClass("image-ident-ok");
}
await worker.terminate();
})();
}
}
async function loadDicomViewerAndFileImages(callback) {
$("#single-dicom-viewer").empty()
//images = []
//Function that returns a promise to read the file
const reader = (file) => {
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = () => resolve(fileReader);
fileReader.readAsDataURL(file);
});
}
const readFile = (file, el) => {
reader(file).then(reader => {
console.log("hello", file, el, image)
if ($("#id_examination").find(":selected")[0].dataset.select2Id == "2") {
var byteArray = new Uint8Array(reader.result);
console.log("etrxact")
extractDicomStudyDescription(byteArray);
}
var image = new Image();
image.height = 100;
image.title = file.name;
image.src = reader.result;
image.className = "temp-thumb";
console.log("read", el);
$(el).parent().parent().prepend(image);
//images.push(reader.result);
loadViewer(images);
});
}
file_set = $("#image_form_set input[type=file]");
file_set.each(async (n, el) => {
console.log(el);
if (el.files.length > 0) {
filename = el.files[0].name;
await readFile(el.files[0], el);
}
})
console.log("images from files", images);
}
function loadViewer(images) {
//dicomViewer.loadCornerstone($("#single-dicom-viewer"), null, images, annotations);
file_set = $("#image_form_set input[type=file]");
n = 0;
for (let i = 0; i < file_set.length; i++) {
el = file_set.get(i)
if (el.files.length > 0) {
n++;
} }
} }
} catch (err) { image_set = $("#image_form_set img");
console.log(err); if (n == image_set.length) {
} const event = new CustomEvent('loadDicomViewer', { "detail": image_set });
}
</script>
{{ form.media }} window.dispatchEvent(event);
sortable('.sortable');
//sortable('.sortable')[0].addEventListener('sortstop', function(e) {
updateImagePositions();
}
}
function updateImagePositions() {
console.log("UP pos");
file_set = $("#image_form_set ul");
n = 0;
for (let i = 0; i < file_set.length; i++) {
ul = file_set.get(i);
console.log(ul)
file_element = $(ul).find("input[type=file]").get(0);
// If a (new) file is being uploaded we save it's name prior to it being hashed
if (file_element.files.length > 0) {
file_name = file_element.files[0].name
$(ul).find("input[type=text]").val(file_name);
}
if (file_element.files.length > 0 || $(ul).find(":contains('Currently:')")) {
n++;
$(ul).find("input[type=number]").val(n);
}
}
}
function extractDicomStudyDescription(byteArray) {
// We need to setup a try/catch block because parseDicom will throw an exception
// if you attempt to parse a non dicom part 10 file (or one that is corrupted)
try {
// parse byteArray into a DataSet object using the parseDicom library
var dataSet = dicomParser.parseDicom(byteArray);
// dataSet contains the parsed elements. Each element is available via a property
// in the dataSet.elements object. The property name is based on the elements group
// and element in the following format: xggggeeee where gggg is the group number
// and eeee is the element number with lowercase hex characters.
// To access the data for an element, we need to know its type and its tag.
// We will get the sopInstanceUid from the file which is a string and
// has the tag (0020,000D)
var study_description = dataSet.string('x00081030').toLowerCase();
console.log("STUDY", study_description);
$.ajax({
url: `{% url 'generic:examination-autocomplete' %}/${encodeURI(study_description)}`,
//context: document.body,
success: function(data){
console.log(data)
}
});
// try to match with a study description (if not already selected)
if ($(`#id_examination_to option`).length < 1) {
option = $(`#id_examination_from option[title*='${study_description}' i]`);
if (option.length) {
option.appendTo($("#id_examination_to"));
toastr.success(`Examination set to ${option.attr('title')} from dicom data`);
} else {
toastr.warning(
`Unable to set examination ${study_description} from dicom data (it needs creating)`);
}
}
} catch (err) {
console.log(err);
}
}
</script>
{{ form.media }}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h2>Add Series</h2> <h2>Add Series</h2>
This form will create a image set that can be associated with a atlas question. If the question has already been created This form will create a image set that can be associated with a atlas question. If the question has already been created
it can be linked below. it can be linked below.
<form action="" method="post" enctype="multipart/form-data" id="atlas-form"> <form action="" method="post" enctype="multipart/form-data" id="atlas-form">
{% csrf_token %} {% csrf_token %}
<a href="/generic/examination/create" id="add_examination" class="add-popup" <a href="/generic/examination/create" id="add_examination" class="add-popup"
onclick="return showAddPopup(this);"><img src="{% static '/img/icon-addlink.svg' %}"></a> onclick="return showAddPopup(this);"><img src="{% static '/img/icon-addlink.svg' %}"></a>
<table> <table>
{{ form.as_table }} {{ form.as_table }}
</table> </table>
<h3>Images:</h3> <h3>Images:</h3>
<input type="button" value="Add More Images" id="add_more_images"> <input type="button" value="Add More Images" id="add_more_images">
<div id="drop-container" class="">Drop images here (or use the buttons below). Dropping images here will overwrite <div id="drop-container" class="">Drop images here (or use the buttons below). Dropping images here will overwrite
existing images in the series. When drag and dropping make sure to drag the first image or the order will not be existing images in the series. When drag and dropping make sure to drag the first image or the order will not be
maintained. Note: dicom images are often not exported in order (although their order can be automatically maintained. Note: dicom images are often not exported in order (although their order can be automatically
detected once uploaded) detected once uploaded)
<div id="single-dicom-viewer" class="dicom-viewer" data-images="" data-annotations=''></div> <div id="single-dicom-viewer" class="dicom-viewer" data-images="" data-annotations=''></div>
<div id="drop-filenames"></div> <div id="drop-filenames"></div>
</div> </div>
<div id="image_form_set" class="sortable"> <div id="image_form_set" class="sortable">
{% for form in image_formset %} {% for form in image_formset %}
<ul class="no-error image-formset"> <ul class="no-error image-formset">
{{form.non_field_errors}} {{form.non_field_errors}}
{{form.errors}} {{form.errors}}
{{ form.as_ul }} {{ form.as_ul }}
</ul>
{% endfor %}
</div>
{{ image_formset.management_form }}
<input type="submit" class="submit-button" value="Submit" name="submit">
</form>
<div id="empty_form" style="display:none">
<ul class='no_error image-formset'>
{{ image_formset.empty_form.as_ul }}
</ul> </ul>
{% endfor %}
</div> </div>
{{ image_formset.management_form }} <div id="images">
<input type="submit" class="submit-button" value="Submit" name="submit">
</form>
<div id="empty_form" style="display:none">
<ul class='no_error image-formset'>
{{ image_formset.empty_form.as_ul }}
</ul>
</div>
<div id="images">
</div> </div>
{% endblock %} {% endblock %}
+30 -30
View File
@@ -2,19 +2,19 @@
<div>Description: {{series.description}}</div> <div>Description: {{series.description}}</div>
{% if series.case %} {% if series.case %}
Associated case: Associated case:
{% for case in series.case.all %} {% for case in series.case.all %}
<a href="{% url 'atlas:case_detail' pk=case.pk %}">{{case}}</a> <a href="{% url 'atlas:case_detail' pk=case.pk %}">{{case}}</a>
{% endfor %} {% endfor %}
{% else %} {% else %}
This series is not associated with any cases. This series is not associated with any cases.
{% endif %} {% endif %}
<div id="single-dicom-viewer" class="dicom-viewer" data-images="{{ series.get_image_url_array }}" data-annotations=''> <div id="single-dicom-viewer" class="dicom-viewer" data-images="{{ series.get_image_url_array }}" data-annotations=''>
</div> </div>
{% if editing_finding < 1 %} {% if editing_finding < 1 %}
<button id="add-finding-button">Add finding</button> <button id="add-finding-button">Add finding</button>
{% endif %} {% endif %}
<button id="reset-viewport-button">Reset viewport</button> <button id="reset-viewport-button">Reset viewport</button>
<div id="finding-form"> <div id="finding-form">
@@ -37,17 +37,17 @@ This series is not associated with any cases.
<summary>Findings</summary> <summary>Findings</summary>
{% for finding in series.findings.all %} {% for finding in series.findings.all %}
<div class="finding-box"> <div class="finding-box">
<button class="view-finding-button" data-annotationjson={{finding.annotation_json}} <button class="view-finding-button" data-annotationjson={{finding.annotation_json}}
data-viewportjson={{finding.viewport_json}} data-findingid={{finding.id}}>Click to view</button> data-viewportjson={{finding.viewport_json}} data-findingid={{finding.id}}>Click to view</button>
<span class="view-finding-details"> <span class="view-finding-details">
Finding(s): {% for f in finding.findings.all %}{{f.get_link}}{% endfor %}<br /> Finding(s): {% for f in finding.findings.all %}{{f.get_link}}{% endfor %}<br />
Structure(s): {% for s in finding.structures.all %}{{s.get_link}}{% endfor %}<br /> Structure(s): {% for s in finding.structures.all %}{{s.get_link}}{% endfor %}<br />
Description: {{finding.description}}<br /> Description: {{finding.description}}<br />
</span> </span>
<a href="{% url 'atlas:series_edit_finding' pk=series.pk finding_pk=finding.pk %}" class="edit-finding-link">Edit</a> <a href="{% url 'atlas:series_edit_finding' pk=series.pk finding_pk=finding.pk %}" class="edit-finding-link">Edit</a>
<a href="{% url 'atlas:delete_finding' pk=finding.pk %}" class="delete-finding-link">Delete</a> <a href="{% url 'atlas:delete_finding' pk=finding.pk %}" class="delete-finding-link">Delete</a>
</div> </div>
{% endfor %} {% endfor %}
</details> </details>
@@ -67,8 +67,8 @@ This series is not associated with any cases.
title="orders dicom by uploaded filename">Order by uploaded filename</a> title="orders dicom by uploaded filename">Order by uploaded filename</a>
</div> </div>
{% for image in series.images.all %} {% for image in series.images.all %}
{{image.image.url}}, pos: {{image.position}}, {{image.upload_filename}} [{{image.image.size|filesizeformat}}]<br /> {{image.image.url}}, pos: {{image.position}}, {{image.upload_filename}} [{{image.image.size|filesizeformat}}]<br />
{% comment %} {{image.get_dicom_info|safe}}<br /> {% endcomment %} {% comment %} {{image.get_dicom_info|safe}}<br /> {% endcomment %}
{% endfor %} {% endfor %}
@@ -118,11 +118,11 @@ This series is not associated with any cases.
}); });
{% if editing_finding > 0 %} {% if editing_finding > 0 %}
$("#hidden-form").show() $("#hidden-form").show()
setTimeout(function() { setTimeout(function() {
$(".view-finding-button[data-findingid={{editing_finding}}]").trigger("click"); $(".view-finding-button[data-findingid={{editing_finding}}]").trigger("click");
}, 1000) }, 1000)
{% endif %} {% endif %}
}); });
@@ -153,15 +153,15 @@ This series is not associated with any cases.
series: {{ series.pk }}, series: {{ series.pk }},
//annotation_json: JSON.stringify(c.toolStateManager.saveToolState()), //annotation_json: JSON.stringify(c.toolStateManager.saveToolState()),
annotation_json: JSON.stringify(cornerstoneTools.globalImageIdSpecificToolStateManager annotation_json: JSON.stringify(cornerstoneTools.globalImageIdSpecificToolStateManager
.saveToolState()), .saveToolState()),
viewport_json: JSON.stringify(c.viewport), viewport_json: JSON.stringify(c.viewport),
findings: JSON.stringify($('#finding-form select[name="findings"]').find(":selected") findings: JSON.stringify($('#finding-form select[name="findings"]').find(":selected")
.map((i, el) => { .map((i, el) => {
return $(el).val() return $(el).val()
}).toArray()), }).toArray()),
structures: JSON.stringify($('#finding-form select[name="structures"]').find( structures: JSON.stringify($('#finding-form select[name="structures"]').find(
":selected") ":selected")
.map((i, el) => { .map((i, el) => {
return $(el).val() return $(el).val()
}).toArray()), }).toArray()),
csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(), csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
@@ -174,8 +174,8 @@ This series is not associated with any cases.
}, },
error: function (xhr, errmsg, err) { error: function (xhr, errmsg, err) {
console.log(xhr.status + ": " + xhr console.log(xhr.status + ": " + xhr
.responseText); // provide a bit more info about the error to the console .responseText); // provide a bit more info about the error to the console
} }
}); });
}); });
</script> </script>
+15 -15
View File
@@ -4,23 +4,23 @@
{% block css %} {% block css %}
{% endblock %} {% endblock %}
{% block js %} {% block js %}
<!--<script type="text/javascript" src="/admin/jsi18n/"></script>--> <!--<script type="text/javascript" src="/admin/jsi18n/"></script>-->
{{form.media}} {{form.media}}
<script type="text/javascript"> <script type="text/javascript">
</script> </script>
<!-- {{ form.media }} --> <!-- {{ form.media }} -->
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h2>Add/Edit Structure</h2> <h2>Add/Edit Structure</h2>
Use this form to create or edit a structure. Use this form to create or edit a structure.
<form action="" method="post" enctype="multipart/form-data" id="structure-form"> <form action="" method="post" enctype="multipart/form-data" id="structure-form">
{% csrf_token %} {% csrf_token %}
<table> <table>
{{ form.as_table }} {{ form.as_table }}
</table> </table>
<input type="submit" class="submit-button" value="Submit" name="submit"> <input type="submit" class="submit-button" value="Submit" name="submit">
</form> </form>
{% endblock %} {% endblock %}
+3
View File
@@ -1170,11 +1170,14 @@ def collection_mark_question(request, pk, case_number):
form = CidReportAnswerMarkForm(instance=answer, prefix=answer.pk) form = CidReportAnswerMarkForm(instance=answer, prefix=answer.pk)
answer_forms.append((answer, form)) answer_forms.append((answer, form))
series_list = case.series.all().prefetch_related("images", "examination", "plane")
return render( return render(
request, request,
"atlas/collection_mark_question.html", "atlas/collection_mark_question.html",
{ {
"collection": collection, "collection": collection,
"series_list": series_list,
"answers": answers, "answers": answers,
"case_detail": case_detail, "case_detail": case_detail,
"case": case, "case": case,