This commit is contained in:
Ross
2025-11-11 11:12:36 +00:00
parent 9ebcd24938
commit 9a9ce11ccb
4 changed files with 618 additions and 620 deletions
+217 -218
View File
@@ -5,14 +5,14 @@
{% block js %}
<!--<script type="text/javascript" src="/admin/jsi18n/"></script>-->
<script type="text/javascript">
let csrf_token = "{{csrf_token}}";
let hash_url = "{% url 'rapids:rapid_question_by_hash' %}";
<script type="text/javascript">
let csrf_token = "{{csrf_token}}";
let hash_url = "{% url 'rapids:rapid_question_by_hash' %}";
//let monitor_directory_handler = false;
//let monitor_interval_id = false;
// set to hold the files that are still being processed
let load_viewer = false;
let load_viewer = false;
// async function listAllFilesAndDirs(dirHandle, files_only) {
// const files = [];
@@ -41,80 +41,80 @@
// }
document.addEventListener('drop', function (e) {
e.preventDefault();
}, false);
document.addEventListener('drop', function (e) {
e.preventDefault();
}, false);
function add_answers_input_form() {
var form_idx = $('#id_answers-TOTAL_FORMS').val();
$('#answer_form_set').append($('#answer_empty_form').html().replace(/__prefix__/g, form_idx));
$(`#id_answers-${form_idx}-status`).val(2);
$('#id_answers-TOTAL_FORMS').val(parseInt(form_idx) + 1);
}
function add_answers_input_form() {
var form_idx = $('#id_answers-TOTAL_FORMS').val();
$('#answer_form_set').append($('#answer_empty_form').html().replace(/__prefix__/g, form_idx));
$(`#id_answers-${form_idx}-status`).val(2);
$('#id_answers-TOTAL_FORMS').val(parseInt(form_idx) + 1);
}
$(document).ready(function () {
$("#add_abnormality").appendTo($("#abnormality-label"));
$("#add_examination").appendTo($("#examination-label"));
$("#add_region").appendTo($("#region-label"));
$(document).ready(function () {
$("#add_abnormality").appendTo($("#abnormality-label"));
$("#add_examination").appendTo($("#examination-label"));
$("#add_region").appendTo($("#region-label"));
dropContainer = document.getElementById("drop-container");
dropContainer = document.getElementById("drop-container");
dropContainer.ondragover = function (evt) {
evt.preventDefault();
evt.stopPropagation();
};
dropContainer.ondragover = function (evt) {
evt.preventDefault();
evt.stopPropagation();
};
dropContainer.ondragenter = function (evt) {
console.log("ENTER")
console.log(evt)
$(evt.target).addClass("drop-target-active")
evt.preventDefault();
evt.stopPropagation();
};
dropContainer.ondragenter = function (evt) {
console.log("ENTER")
console.log(evt)
$(evt.target).addClass("drop-target-active")
evt.preventDefault();
evt.stopPropagation();
};
dropContainer.ondragleave = function (evt) {
console.log("ENTER")
console.log(evt)
$(evt.target).removeClass("drop-target-active")
evt.preventDefault();
evt.stopPropagation();
};
dropContainer.ondragleave = function (evt) {
console.log("ENTER")
console.log(evt)
$(evt.target).removeClass("drop-target-active")
evt.preventDefault();
evt.stopPropagation();
};
dropContainer.ondrop = function (evt) {
$(evt.target).removeClass("drop-target-active");
dropContainer.ondrop = function (evt) {
$(evt.target).removeClass("drop-target-active");
file_drop_number = evt.dataTransfer.files.length;
file_drop_number = evt.dataTransfer.files.length;
if (file_drop_number < 1) {
toastr.warning(`Drop failed (no files), try again.`);
} else {
toastr.info(`Loading ${file_drop_number} dropped image(s).`);
}
if (file_drop_number < 1) {
toastr.warning(`Drop failed (no files), try again.`);
} else {
toastr.info(`Loading ${file_drop_number} dropped image(s).`);
}
// Get all input elements
inputs = extendInputs("rapid-form", file_drop_number);
inputs = extendInputs("rapid-form", file_drop_number);
console.log("drop inputs", inputs, evt);
console.log("drop inputs", inputs, evt);
// Loop through each dropped file and try to assign to an
// input element
[...evt.dataTransfer.files].forEach((f) => {
feedback = false;
if (evt.target.id == "feedback-drop-target") {
feedback = true;
}
addFile(f, feedback)
})
[...evt.dataTransfer.files].forEach((f) => {
feedback = false;
if (evt.target.id == "feedback-drop-target") {
feedback = true;
}
addFile(f, feedback)
})
evt.preventDefault();
evt.stopPropagation();
};
evt.preventDefault();
evt.stopPropagation();
};
// $('#directory-picker-button').click(() => {
@@ -170,71 +170,71 @@
$('#add_more_images').click(() => {
add_input_form()
});
$('#add_more_answers').click(() => {
add_answers_input_form()
});
$('#add_more_images').click(() => {
add_input_form()
});
$('#add_more_answers').click(() => {
add_answers_input_form()
});
$("input[type=file]").on('change', input_change);
$("input[type=file]").on('change', input_change);
$("#rapid-form").on("submit", (evt) => {
submit = true;
if (!$normal) {
if ($('#id_answers-TOTAL_FORMS').val() == "0") {
$("#rapid-form").on("submit", (evt) => {
submit = true;
if (!$normal) {
if ($('#id_answers-TOTAL_FORMS').val() == "0") {
submit = false;
add_answers_input_form();
toastr.error(`Question that are not normal require an answer`);
evt.preventDefault();
}
}
if (!$("#id_examination_to option").length) {
submit = false;
add_answers_input_form();
toastr.error(`Question that are not normal require an answer`);
toastr.error("Please add examination type")
evt.preventDefault();
}
}
if (submit) {
toastr.info(`Submiting question... please wait`, '', {
"closeButton": false,
"debug": false,
"newestOnTop": false,
"progressBar": true,
"positionClass": "toast-top-full-width",
"preventDuplicates": false,
"onclick": null,
"showDuration": "300",
"hideDuration": "1000",
"timeOut": "5000",
"extendedTimeOut": "1000",
"showEasing": "swing",
"hideEasing": "linear",
"showMethod": "fadeIn",
"hideMethod": "fadeOut"
});
}
})
});
function extractDicomDetails(byteArray) {
if (!$("#id_examination_to option").length) {
submit = false;
toastr.error("Please add examination type")
evt.preventDefault();
}
if (submit) {
toastr.info(`Submiting question... please wait`, '', {
"closeButton": false,
"debug": false,
"newestOnTop": false,
"progressBar": true,
"positionClass": "toast-top-full-width",
"preventDuplicates": false,
"onclick": null,
"showDuration": "300",
"hideDuration": "1000",
"timeOut": "5000",
"extendedTimeOut": "1000",
"showEasing": "swing",
"hideEasing": "linear",
"showMethod": "fadeIn",
"hideMethod": "fadeOut"
});
}
})
});
function extractDicomDetails(byteArray) {
if (!$("#id_examination_to option").length) {
// 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 {
try {
// parse byteArray into a DataSet object using the parseDicom library
var dataSet = dicomParser.parseDicom(byteArray);
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
@@ -244,157 +244,156 @@
// 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);
var study_description = dataSet.string('x00081030').toLowerCase();
console.log("STUDY", study_description);
// 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 ($(`#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)`);
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);
}
}
} catch (err) {
console.log(err);
}
}
}
</script>
<script type="text/hyperscript">
init
set global $normal to false
if (#id_normal_0.checked )
Fade(.abnormal-fields) then
set global $normal to true then
</script>
<script type="text/hyperscript">
init
set global $normal to false
if (#id_normal_0.checked )
Fade(.abnormal-fields) then
set global $normal to true then
remove @required from <#answer_form_set textarea/> then
remove @required from <#answer_empty_form textarea.required/>
end
end
remove @required from <#answer_empty_form textarea.required/>
end
end
def Fade(elt)
def Fade(elt)
if elt's style's opacity != "0"
transition element elt opacity to 0 over 350ms
transition element elt transform to "translateY(0.25rem)" over 350ms
hide elt
transition element elt opacity to 0 over 350ms
transition element elt transform to "translateY(0.25rem)" over 350ms
hide elt
else
show elt
transition element elt opacity to 1 over 350ms
transition element elt transform to "translateY(0rem)" over 350ms
transition element elt opacity to 1 over 350ms
transition element elt transform to "translateY(0rem)" over 350ms
end
end
on change from #id_normal_0
if (#id_normal_0.checked )
Fade(.abnormal-fields) then
set global $normal to true then
end
on change from #id_normal_0
if (#id_normal_0.checked )
Fade(.abnormal-fields) then
set global $normal to true then
remove @required from <#answer_form_set textarea/> then
remove @required from <#answer_empty_form textarea.required/>
end
on change from #id_normal_1
if (#id_normal_1.checked )
Fade(.abnormal-fields) then
set global $normal to false then
remove @required from <#answer_empty_form textarea.required/>
end
on change from #id_normal_1
if (#id_normal_1.checked )
Fade(.abnormal-fields) then
set global $normal to false then
add @required to <#answer_form_set textarea/> then
add @required to <#answer_empty_form textarea.required/>
end
add @required to <#answer_empty_form textarea.required/>
end
</script>
</script>
{{ form.media }}
{{ form.media }}
{% endblock %}
{% block content %}
{% if object %}
{% include "rapids/question_link_header.html" %}
{% endif %}
<h2>Submit Rapid</h2>
<p>
<h3>Instructions</h3>
Abnormality, Region and Laterality are used to categorise within the system (they are not used for marking). String
answers that match those added below will be used for automatic marking. Multiple images can be added to a question.
If
the feedback image box is checked they will not be displayed when taking the question.
</p>
{% if object %}
{% include "rapids/question_link_header.html" %}
{% endif %}
<h2>Submit Rapid</h2>
<p>
<h3>Instructions</h3>
Abnormality, Region and Laterality are used to categorise within the system (they are not used for marking). String
answers that match those added below will be used for automatic marking. Multiple images can be added to a question.
If
the feedback image box is checked they will not be displayed when taking the question.
</p>
<!-- <div>
To monitor a directory select it here.<br />
<button id="directory-picker-button">Pick a directory</button>
<span id="directory-picker-display">No directory monitored</span>
</div> -->
<form action="" method="post" enctype="multipart/form-data" id="rapid-form">
<form action="" method="post" enctype="multipart/form-data" id="rapid-form">
{% comment %} {% csrf_token %} {% endcomment %}
<a href="/rapids/abnormality/create" id="add_abnormality" class="add-popup"
onclick="return showAddPopup(this);"><img src="{% static 'img/icon-addlink.svg' %}"></a>
<a href="/rapids/examination/create" id="add_examination" class="add-popup"
onclick="return showAddPopup(this);"><img src="{% static 'img/icon-addlink.svg' %}"></a>
<a href="/rapids/region/create" id="add_region" class="add-popup" onclick="return showAddPopup(this);"><img
<a href="/rapids/abnormality/create" id="add_abnormality" class="add-popup"
onclick="return showAddPopup(this);"><img src="{% static 'img/icon-addlink.svg' %}"></a>
<a href="/rapids/examination/create" id="add_examination" class="add-popup"
onclick="return showAddPopup(this);"><img src="{% static 'img/icon-addlink.svg' %}"></a>
<a href="/rapids/region/create" id="add_region" class="add-popup" onclick="return showAddPopup(this);"><img
src="{% static 'img/icon-addlink.svg' %}"></a>
{% crispy form form.helper %}
{% crispy form form.helper %}
<div class="abnormal-fields">
<h3>Answers:</h3>
<input type="button" value="Add More Answers" id="add_more_answers">
<div id="answer_form_set">
{% for form in answer_formset %}
<ul class="no-error answer-formset">
{{form.non_field_errors}}
{{form.errors}}
{{ form.as_ul }}
</ul>
{% endfor %}
</div>
{{ answer_formset.management_form }}
</div>
<h3>Images:</h3>
<div id="drop-container" class="drop-target">Drop images here (or use the buttons below)<div
<div class="abnormal-fields">
<h3>Answers:</h3>
<input type="button" value="Add More Answers" id="add_more_answers">
<div id="answer_form_set">
{% for form in answer_formset %}
<ul class="no-error answer-formset">
{{form.non_field_errors}}
{{form.errors}}
{{ form.as_ul }}
</ul>
{% endfor %}
</div>
{{ answer_formset.management_form }}
</div>
<h3>Images:</h3>
<div id="drop-container" class="drop-target">Drop images here (or use the buttons below)<div
id="feedback-drop-target">Feedback image?<br />drop those here</div>
<div id="drop-filenames"></div>
<div id="drop-filenames"></div>
</div>
<input type="button" value="Add More Images" id="add_more_images">
<div id="image_form_set">
{% for form in image_formset %}
<ul class="no-error image-formset">
{{form.non_field_errors}}
{{form.errors}}
{{ 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>
</div>
<input type="button" value="Add More Images" id="add_more_images">
<div id="image_form_set">
{% for form in image_formset %}
<ul class="no-error image-formset">
{{form.non_field_errors}}
{{form.errors}}
{{ form.as_ul }}
<div id="answer_empty_form" style="display:none">
<ul class='no_error answer-formset'>
{{ answer_formset.empty_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>
</div>
<div id="answer_empty_form" style="display:none">
<ul class='no_error answer-formset'>
{{ answer_formset.empty_form.as_ul }}
</ul>
</div>
<div id="single-dicom-viewer" class="rapid-dicom-viewer" data-images="" data-annotations='' style="display:none"></div>
<div id="single-dicom-viewer" class="rapid-dicom-viewer" data-images="" data-annotations='' style="display:none"></div>
{% endblock %}
{% block css %}
<style>
.add-popup {
float: left;
}
</style>
<style>
.add-popup {
float: left;
}
</style>
{% endblock css %}