improve finrding
This commit is contained in:
@@ -210,7 +210,6 @@ function loadDicomViewer(images_to_load, annotations_to_load) {
|
|||||||
images = JSON.parse(images);
|
images = JSON.parse(images);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(images);
|
|
||||||
|
|
||||||
let annotations = single_dicom.dataset.annotations;
|
let annotations = single_dicom.dataset.annotations;
|
||||||
if (annotations_to_load != undefined) {
|
if (annotations_to_load != undefined) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{% partialdef case-series %}
|
{% partialdef case-series %}
|
||||||
{% for series in case.series.all %}
|
{% for series in case.series.all %}
|
||||||
<span class="series-block">
|
<span class="series-block" id="series-block-{{ series.pk }}">
|
||||||
<span>
|
<span>
|
||||||
<span class="series-block-series-number">Series {{ forloop.counter }}:</span><br>
|
<span class="series-block-series-number">Series {{ forloop.counter }}:</span><br>
|
||||||
<a href="{% url 'atlas:series_detail' pk=series.pk %}">
|
<a href="{% url 'atlas:series_detail' pk=series.pk %}">
|
||||||
@@ -197,9 +197,14 @@
|
|||||||
{% if case.series.all %}
|
{% if case.series.all %}
|
||||||
{% 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" id="finding-box-{{ finding.pk }}" data-series="{{ series.pk }}"
|
||||||
|
_="on mouseenter
|
||||||
|
toggle .highlight-series
|
||||||
|
on #series-block-{{ series.pk }}
|
||||||
|
until mouseleave"
|
||||||
|
>
|
||||||
<span>
|
<span>
|
||||||
<a href="{{series.get_absolute_url}}">Series {{series.pk}}</a>: {{series.get_examination_full}} |
|
<a href="{{series.get_absolute_url}}?show_finding={{finding.pk}}"><button class="btn btn-primary btn-sm">View</button></a>
|
||||||
</span>
|
</span>
|
||||||
{% if finding.findings.all %}
|
{% if finding.findings.all %}
|
||||||
<span>
|
<span>
|
||||||
@@ -331,4 +336,12 @@
|
|||||||
// Listen for toggle events on the <details> element
|
// Listen for toggle events on the <details> element
|
||||||
detailsElement.addEventListener("toggle", toggleCheckboxes);
|
detailsElement.addEventListener("toggle", toggleCheckboxes);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Highlight style for the series-block */
|
||||||
|
.highlight-series {
|
||||||
|
background-color: blue;
|
||||||
|
transition: background-color 0.3s ease, border 0.3s ease;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -3,14 +3,41 @@
|
|||||||
<div>{{ series.modality}}, {{ series.examination }}, {{ series.plane }}, {{ series.contrast }}</div>
|
<div>{{ series.modality}}, {{ series.examination }}, {{ series.plane }}, {{ series.contrast }}</div>
|
||||||
<div>Description: {{series.description}}</div>
|
<div>Description: {{series.description}}</div>
|
||||||
|
|
||||||
{% if series.case %}
|
Associated case:
|
||||||
Associated case:
|
|
||||||
{% for case in series.case.all %}
|
{% for case in series.case.all %}
|
||||||
|
<span id="case-link-{{ case.pk }}" class="case-item">
|
||||||
<a href="{% url 'atlas:case_detail' pk=case.pk %}">{{case}}</a>
|
<a href="{% url 'atlas:case_detail' pk=case.pk %}">{{case}}</a>
|
||||||
{% endfor %}
|
{% if can_edit %}
|
||||||
{% else %}
|
<button hx-post="{% url 'atlas:remove_series_from_case' series.pk case.pk %}"
|
||||||
|
hx-target="#case-link-{{ case.pk }}"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-confirm="Are you sure you want to remove this series from the case?"
|
||||||
|
class="btn btn-link btn-sm button-unset remove-button">
|
||||||
|
Remove
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
{% empty %}
|
||||||
This series is not associated with any cases.
|
This series is not associated with any cases.
|
||||||
{% endif %}
|
{% if can_edit %}
|
||||||
|
<details>
|
||||||
|
<summary>Add Series to Case</summary>
|
||||||
|
<form hx-post="{% url 'atlas:add_series_to_case' series.pk %}"
|
||||||
|
hx-target="#add-series-to-case-result"
|
||||||
|
hx-swap="innerHTML">
|
||||||
|
{% csrf_token %}
|
||||||
|
<label for="case-select">Select Case:</label>
|
||||||
|
<select name="case_id" id="case-select" required>
|
||||||
|
{% for case in available_cases %}
|
||||||
|
<option value="{{ case.pk }}">{{ case.title }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<button type="submit" class="btn btn-primary">Add to Case</button>
|
||||||
|
</form>
|
||||||
|
<div id="add-series-to-case-result"></div>
|
||||||
|
</details>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
{% with image_url_array_and_count=series.get_image_url_array_and_count %}
|
{% with image_url_array_and_count=series.get_image_url_array_and_count %}
|
||||||
<div id="single-dicom-viewer" class="dicom-viewer" data-images="{{ image_url_array_and_count.0 }}" data-annotations=''>
|
<div id="single-dicom-viewer" class="dicom-viewer" data-images="{{ image_url_array_and_count.0 }}" data-annotations=''>
|
||||||
@@ -44,7 +71,7 @@
|
|||||||
|
|
||||||
{% 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 id="finding-{{finding.pk}}" class="view-finding-button" data-annotationjson={{finding.annotation_json}}
|
||||||
data-viewportjson={{finding.viewport_json}} data-findingid={{finding.id}} data-currentimageid={{finding.current_image_id_index}}>Click to view</button>
|
data-viewportjson={{finding.viewport_json}} data-findingid={{finding.id}} data-currentimageid={{finding.current_image_id_index}}>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 />
|
||||||
@@ -155,6 +182,7 @@
|
|||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$("#set-lower-truncation-bound-button").click(() => {
|
$("#set-lower-truncation-bound-button").click(() => {
|
||||||
@@ -248,6 +276,7 @@
|
|||||||
current_image_id_index = e.currentTarget.dataset.currentimageid;
|
current_image_id_index = e.currentTarget.dataset.currentimageid;
|
||||||
console.log(e.currentTarget, current_image_id_index)
|
console.log(e.currentTarget, current_image_id_index)
|
||||||
loadAnnotationAndViewportOnElement(annotationjson, viewport, dicom_element, current_image_id_index);
|
loadAnnotationAndViewportOnElement(annotationjson, viewport, dicom_element, current_image_id_index);
|
||||||
|
$(el).addClass("active");
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -269,6 +298,15 @@
|
|||||||
}, 1000)
|
}, 1000)
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{% if request.GET.show_finding %}
|
||||||
|
function show_finding() {
|
||||||
|
console.log("show finding")
|
||||||
|
$("#finding-{{ request.GET.show_finding }}").trigger("click");
|
||||||
|
}
|
||||||
|
setTimeout(show_finding, 500);
|
||||||
|
{% endif %}
|
||||||
});
|
});
|
||||||
|
|
||||||
function loadAnnotationAndViewportOnElement(annotation, viewport, dicom_element, current_image_id_index) {
|
function loadAnnotationAndViewportOnElement(annotation, viewport, dicom_element, current_image_id_index) {
|
||||||
@@ -351,3 +389,24 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.case-item {
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.case-item:hover {
|
||||||
|
background-color: darkgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.remove-button:hover {
|
||||||
|
color: #dc3545; /* Optional: Make the remove button text red on hover */
|
||||||
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
font-weight: bold; /* Optional: Make the active button text bold */
|
||||||
|
border-style: dashed;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -264,6 +264,8 @@ urlpatterns = [
|
|||||||
views.series_dicom_json,
|
views.series_dicom_json,
|
||||||
name="series_dicom_json",
|
name="series_dicom_json",
|
||||||
),
|
),
|
||||||
|
path('series/<int:series_pk>/add-to-case/', views.add_series_to_case, name='add_series_to_case'),
|
||||||
|
path('series/<int:series_pk>/<int:case_pk>/remove-from-case/', views.remove_series_from_case, name='remove_series_from_case'),
|
||||||
path("uncategorised_dicoms/", views.uncategorised_dicoms, name="uncategorised_dicoms_view"),
|
path("uncategorised_dicoms/", views.uncategorised_dicoms, name="uncategorised_dicoms_view"),
|
||||||
path("question_schema/", views.QuestionSchemaView.as_view(), name="question_schema_overview"),
|
path("question_schema/", views.QuestionSchemaView.as_view(), name="question_schema_overview"),
|
||||||
path("question_schema/<int:pk>", views.question_schema_detail, name="question_schema_detail"),
|
path("question_schema/<int:pk>", views.question_schema_detail, name="question_schema_detail"),
|
||||||
|
|||||||
+43
-7
@@ -247,16 +247,21 @@ def series_detail(request, pk, finding_pk=None):
|
|||||||
else:
|
else:
|
||||||
series_finding_form = SeriesFindingForm(series_id=series.id)
|
series_finding_form = SeriesFindingForm(series_id=series.id)
|
||||||
|
|
||||||
# logging.debug(atlas.subspecialty.first().name.all())
|
context = {
|
||||||
return render(
|
|
||||||
request,
|
|
||||||
"atlas/series.html",
|
|
||||||
{
|
|
||||||
"series": series,
|
"series": series,
|
||||||
"series_finding_form": series_finding_form,
|
"series_finding_form": series_finding_form,
|
||||||
"editing_finding": editing_finding,
|
"editing_finding": editing_finding,
|
||||||
"can_edit": can_edit,
|
"can_edit": can_edit,
|
||||||
},
|
}
|
||||||
|
|
||||||
|
if can_edit:
|
||||||
|
context["available_cases"] = Case.objects.all() # Adjust the queryset as needed
|
||||||
|
|
||||||
|
# logging.debug(atlas.subspecialty.first().name.all())
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"atlas/series.html",
|
||||||
|
context,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -3098,4 +3103,35 @@ def linked_cases_overview(request, case_id):
|
|||||||
"previous_cases": previous_cases,
|
"previous_cases": previous_cases,
|
||||||
"next_cases": next_cases,
|
"next_cases": next_cases,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def add_series_to_case(request, series_pk):
|
||||||
|
if request.method == "POST":
|
||||||
|
case_id = request.POST.get("case_id")
|
||||||
|
case = get_object_or_404(Case, pk=case_id)
|
||||||
|
if not case.check_user_can_edit(request.user):
|
||||||
|
raise PermissionDenied("You do not have permission to edit this case.")
|
||||||
|
|
||||||
|
series = get_object_or_404(Series, pk=series_pk)
|
||||||
|
|
||||||
|
# Associate the series with the case
|
||||||
|
series.case.add(case)
|
||||||
|
|
||||||
|
return HttpResponse(f"Series {series_pk} added to case {case.title} ({case_id}).")
|
||||||
|
return HttpResponse("Invalid request.")
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def remove_series_from_case(request, series_pk, case_pk):
|
||||||
|
if request.method == "POST":
|
||||||
|
case = get_object_or_404(Case, pk=case_pk)
|
||||||
|
if not case.check_user_can_edit(request.user):
|
||||||
|
raise PermissionDenied("You do not have permission to edit this case.")
|
||||||
|
|
||||||
|
series = get_object_or_404(Series, pk=series_pk)
|
||||||
|
|
||||||
|
# Associate the series with the case
|
||||||
|
series.case.remove(case)
|
||||||
|
|
||||||
|
return HttpResponse(f"Removed")
|
||||||
|
return HttpResponse("Invalid request.")
|
||||||
|
|||||||
@@ -138,6 +138,17 @@ button a {
|
|||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button-unset {
|
||||||
|
background-color: unset;
|
||||||
|
color: unset;
|
||||||
|
border: unset;
|
||||||
|
}
|
||||||
|
.button-unset:hover {
|
||||||
|
background-color: unset;
|
||||||
|
color: unset;
|
||||||
|
border: unset;
|
||||||
|
}
|
||||||
|
|
||||||
.marking-list pre {
|
.marking-list pre {
|
||||||
display: inline;
|
display: inline;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
|
|||||||
Reference in New Issue
Block a user