Refactor code structure for improved readability and maintainability
This commit is contained in:
@@ -17,11 +17,11 @@
|
|||||||
data-series-id="{{series.pk}}"
|
data-series-id="{{series.pk}}"
|
||||||
aria-label="Open series actions for Series {{ forloop.counter }}">
|
aria-label="Open series actions for Series {{ forloop.counter }}">
|
||||||
<div class="series-card-thumb-wrap">
|
<div class="series-card-thumb-wrap">
|
||||||
{% with preview_image=series.images.first %}
|
{% with series_thumbnail=series.get_thumbnail %}
|
||||||
{% if preview_image and preview_image.image %}
|
{% if series_thumbnail.1 %}
|
||||||
<img src="{{ preview_image.image.url }}"
|
<div class="series-card-thumb-generated" aria-label="Series {{ forloop.counter }} thumbnail">
|
||||||
alt="Series {{ forloop.counter }} thumbnail"
|
{{ series_thumbnail.0|safe }}
|
||||||
class="series-card-thumb">
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="series-card-thumb series-card-thumb-placeholder">
|
<div class="series-card-thumb series-card-thumb-placeholder">
|
||||||
<i class="bi bi-image"></i>
|
<i class="bi bi-image"></i>
|
||||||
@@ -565,15 +565,21 @@
|
|||||||
Remove selected series from case
|
Remove selected series from case
|
||||||
</button>
|
</button>
|
||||||
<button hx-post="{% url 'atlas:series_bulk_delete' %}"
|
<button hx-post="{% url 'atlas:series_bulk_delete' %}"
|
||||||
|
id="series-delete-selected-btn"
|
||||||
title="delete selected series"
|
title="delete selected series"
|
||||||
hx-include="[name='series-ids']:checked"
|
hx-include="[name='series-ids']:checked"
|
||||||
hx-target="#series-action-results"
|
hx-target="#series-action-results"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
|
hx-indicator="#series-delete-indicator"
|
||||||
hx-confirm="Delete the selected series from the database? This cannot be undone."
|
hx-confirm="Delete the selected series from the database? This cannot be undone."
|
||||||
class="btn btn-sm btn-danger text-start"
|
class="btn btn-sm btn-danger text-start"
|
||||||
type="button">
|
type="button">
|
||||||
Delete selected series
|
Delete selected series
|
||||||
</button>
|
</button>
|
||||||
|
<span id="series-delete-indicator" class="htmx-indicator small text-danger">
|
||||||
|
<span class="spinner-border spinner-border-sm me-1" role="status" aria-hidden="true"></span>
|
||||||
|
Deleting...
|
||||||
|
</span>
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn btn-sm btn-secondary text-start"
|
class="btn btn-sm btn-secondary text-start"
|
||||||
data-bs-toggle="modal"
|
data-bs-toggle="modal"
|
||||||
@@ -836,12 +842,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<section class="case-detail-section card mb-3">
|
||||||
<h5>Resources</h5>
|
<div class="card-header d-flex justify-content-between align-items-center flex-wrap gap-2">
|
||||||
|
<h5 class="mb-0">Resources</h5>
|
||||||
{% if can_edit%}
|
{% if can_edit %}
|
||||||
<div class="mb-2">
|
<div id="resource-search-panel-placeholder" class="d-inline-flex">
|
||||||
<div id="resource-search-panel-placeholder">
|
|
||||||
<button class="btn btn-sm btn-outline-primary"
|
<button class="btn btn-sm btn-outline-primary"
|
||||||
hx-get="{% url 'atlas:resource_search_panel' %}?case_id={{ case.pk }}"
|
hx-get="{% url 'atlas:resource_search_panel' %}?case_id={{ case.pk }}"
|
||||||
hx-target="#resource-search-panel-placeholder"
|
hx-target="#resource-search-panel-placeholder"
|
||||||
@@ -849,29 +854,35 @@
|
|||||||
Add Resource
|
Add Resource
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
<div>
|
<div class="card-body">
|
||||||
{% include 'atlas/partials/case_resources_list.html' with case=case %}
|
{% include 'atlas/partials/case_resources_list.html' with case=case %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
|
|
||||||
{% 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">
|
<section class="case-detail-section card mb-3 atlas-answer">
|
||||||
<div class="pre-whitespace">
|
<div class="card-header">
|
||||||
Condition:
|
<h5 class="mb-0">Clinical Summary</h5>
|
||||||
<ul>
|
</div>
|
||||||
|
<div class="card-body pre-whitespace">
|
||||||
|
<div class="mb-3">
|
||||||
|
<strong>Condition:</strong>
|
||||||
|
<ul class="mb-2">
|
||||||
{% for con in case.condition.all %}
|
{% for con in case.condition.all %}
|
||||||
<li>{{con.get_link}}</li>
|
<li>{{con.get_link}}</li>
|
||||||
|
{% empty %}
|
||||||
|
<li class="text-muted">None</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
<div>
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
<strong>Procedure(s):</strong>
|
<strong>Procedure(s):</strong>
|
||||||
{% if case.procedures.all %}
|
{% if case.procedures.all %}
|
||||||
<ul>
|
<ul class="mb-2">
|
||||||
{% for proc in case.procedures.all %}
|
{% for proc in case.procedures.all %}
|
||||||
<li>{{ proc.get_link }}</li>
|
<li>{{ proc.get_link }}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -880,28 +891,30 @@
|
|||||||
<span class="text-muted">None</span>
|
<span class="text-muted">None</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="mb-3">
|
||||||
|
|
||||||
{% include 'atlas/partials/_series_findings.html' %}
|
{% include 'atlas/partials/_series_findings.html' %}
|
||||||
|
|
||||||
{% include 'atlas/partials/_case_displaysets.html' %}
|
{% include 'atlas/partials/_case_displaysets.html' %}
|
||||||
</div>
|
</div>
|
||||||
{% include 'atlas/partials/_case_differentials.html' %}
|
{% include 'atlas/partials/_case_differentials.html' %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
|
|
||||||
<b>Collections:</b>
|
|
||||||
|
|
||||||
|
<section class="case-detail-section card mb-3">
|
||||||
|
<div class="card-header d-flex justify-content-between align-items-center flex-wrap gap-2">
|
||||||
|
<h5 class="mb-0">Collections</h5>
|
||||||
{% if can_edit %}
|
{% if can_edit %}
|
||||||
<button class="btn btn-sm btn-primary"
|
<button class="btn btn-sm btn-primary"
|
||||||
hx-get="{% url 'atlas:case_collection_form' case.pk %}"
|
hx-get="{% url 'atlas:case_collection_form' case.pk %}"
|
||||||
hx-target="#collection-form">
|
hx-target="#collection-form">
|
||||||
Add to collection</button>
|
Add to collection
|
||||||
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div id="collection-form"></div>
|
</div>
|
||||||
<ul id="case-{{ case.pk }}-collections">
|
<div class="card-body">
|
||||||
|
<div id="collection-form" class="mb-2"></div>
|
||||||
|
<ul id="case-{{ case.pk }}-collections" class="list-group list-group-flush">
|
||||||
{% for collection in case.casecollection_set.all %}
|
{% for collection in case.casecollection_set.all %}
|
||||||
<li id="collection-{{ collection.pk }}">
|
<li id="collection-{{ collection.pk }}" class="list-group-item d-flex justify-content-between align-items-center flex-wrap gap-2">
|
||||||
<a href="{% url 'atlas:collection_detail' pk=collection.pk %}">{{ collection.name }}</a>
|
<a href="{% url 'atlas:collection_detail' pk=collection.pk %}">{{ collection.name }}</a>
|
||||||
{% if can_edit %}
|
{% if can_edit %}
|
||||||
<button
|
<button
|
||||||
@@ -914,9 +927,12 @@
|
|||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</li>
|
</li>
|
||||||
|
{% empty %}
|
||||||
|
<li class="list-group-item text-muted">No collections linked.</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</p>
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
{% if casedetail %}
|
{% if casedetail %}
|
||||||
@@ -924,30 +940,45 @@
|
|||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
<section class="case-detail-section card mb-3">
|
||||||
|
<div class="card-header">
|
||||||
|
<h5 class="mb-0">Linked Cases</h5>
|
||||||
<p class="pre-whitespace"><b>Previous case:</b> {{ case.previous_case.get_link }}</p>
|
</div>
|
||||||
<p class="pre-whitespace"><b>Next case:</b>
|
<div class="card-body">
|
||||||
|
<p class="mb-2"><strong>Previous case:</strong> {{ case.previous_case.get_link }}</p>
|
||||||
|
<p class="mb-0"><strong>Next case:</strong>
|
||||||
{% if case.next_case %}
|
{% if case.next_case %}
|
||||||
{{ case.next_case.get_link }}
|
{{ case.next_case.get_link }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{% url 'atlas:case_clone_next' case.pk %}">Clone and add next case</a>
|
<a href="{% url 'atlas:case_clone_next' case.pk %}">Clone and add next case</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
<div>
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="case-detail-section card mb-3">
|
||||||
|
<div class="card-header">
|
||||||
|
<h5 class="mb-0">Notes</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
{% include 'question_notes.html' %}
|
{% include 'question_notes.html' %}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
</div>
|
<section class="case-detail-section card mb-3">
|
||||||
|
<div class="card-header">
|
||||||
|
<h5 class="mb-0">Case Metadata</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="mb-2"><strong>Checked by:</strong> {% for verified in case.verified.all %} <a
|
||||||
|
href="{% url 'atlas:verified_detail' pk=verified.pk %}">{{verified}}</a>{% if not forloop.last %}, {% endif %}{% empty %}<span class="text-muted">None</span>{% endfor %}</p>
|
||||||
|
|
||||||
<p><b>Checked by:</b> {% for verified in case.verified.all %} <a
|
<p class="mb-2"><strong>Author(s):</strong> {% for author in case.author.all %} <a
|
||||||
href="{% url 'atlas:verified_detail' pk=verified.pk %}">{{verified}}</a>, {% endfor %}</p>
|
href="{% url 'atlas:author_detail' pk=author.pk %}">{{author}}</a>{% if not forloop.last %}, {% endif %}{% empty %}<span class="text-muted">None</span>{% endfor %}</p>
|
||||||
|
|
||||||
<p><b>Author(s):</b> {% for author in case.author.all %} <a
|
<p class="mb-0"><strong>Case size:</strong> {{ case.get_total_series_images_size | filesizeformat }}</p>
|
||||||
href="{% url 'atlas:author_detail' pk=author.pk %}">{{author}}</a>, {% endfor %}</p>
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<p><b>Case size:</b> {{ case.get_total_series_images_size | filesizeformat }}</p>
|
|
||||||
|
|
||||||
{% include 'atlas/partials/_finding_modal.html' %}
|
{% include 'atlas/partials/_finding_modal.html' %}
|
||||||
<!-- Reorder Series Modal -->
|
<!-- Reorder Series Modal -->
|
||||||
@@ -1317,6 +1348,7 @@
|
|||||||
// Show the alert when a result is received
|
// Show the alert when a result is received
|
||||||
const resultsSpan = document.getElementById("series-action-results");
|
const resultsSpan = document.getElementById("series-action-results");
|
||||||
const alertDiv = document.getElementById("series-action-alert");
|
const alertDiv = document.getElementById("series-action-alert");
|
||||||
|
const deleteSelectedSeriesBtn = document.getElementById("series-delete-selected-btn");
|
||||||
const observer = new MutationObserver(function(mutations) {
|
const observer = new MutationObserver(function(mutations) {
|
||||||
if (resultsSpan.textContent.trim() !== "") {
|
if (resultsSpan.textContent.trim() !== "") {
|
||||||
alertDiv.style.display = "block";
|
alertDiv.style.display = "block";
|
||||||
@@ -1326,6 +1358,27 @@
|
|||||||
});
|
});
|
||||||
observer.observe(resultsSpan, { childList: true, subtree: true });
|
observer.observe(resultsSpan, { childList: true, subtree: true });
|
||||||
|
|
||||||
|
if (deleteSelectedSeriesBtn) {
|
||||||
|
deleteSelectedSeriesBtn.addEventListener("htmx:beforeRequest", function() {
|
||||||
|
deleteSelectedSeriesBtn.disabled = true;
|
||||||
|
alertDiv.classList.remove("alert-success", "alert-danger");
|
||||||
|
alertDiv.classList.add("alert-info");
|
||||||
|
resultsSpan.textContent = "Deleting selected series...";
|
||||||
|
alertDiv.style.display = "block";
|
||||||
|
});
|
||||||
|
|
||||||
|
deleteSelectedSeriesBtn.addEventListener("htmx:afterRequest", function(evt) {
|
||||||
|
deleteSelectedSeriesBtn.disabled = false;
|
||||||
|
const status = evt.detail && evt.detail.xhr ? evt.detail.xhr.status : 0;
|
||||||
|
alertDiv.classList.remove("alert-info", "alert-success", "alert-danger");
|
||||||
|
if (status >= 200 && status < 300) {
|
||||||
|
alertDiv.classList.add("alert-success");
|
||||||
|
} else {
|
||||||
|
alertDiv.classList.add("alert-danger");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Listen for toggle events on the <details> element
|
// Listen for toggle events on the <details> element
|
||||||
if (detailsElement) {
|
if (detailsElement) {
|
||||||
detailsElement.addEventListener("toggle", toggleCheckboxes);
|
detailsElement.addEventListener("toggle", toggleCheckboxes);
|
||||||
@@ -1835,6 +1888,22 @@
|
|||||||
display: block;
|
display: block;
|
||||||
background: rgba(255,255,255,0.04);
|
background: rgba(255,255,255,0.04);
|
||||||
}
|
}
|
||||||
|
.series-card-thumb-generated,
|
||||||
|
.series-card-thumb-generated span {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
|
border-radius: 0.4rem;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid rgba(255,255,255,0.1);
|
||||||
|
background: rgba(255,255,255,0.04);
|
||||||
|
}
|
||||||
|
.series-card-thumb-generated img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
.series-card-thumb-placeholder {
|
.series-card-thumb-placeholder {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -1934,6 +2003,31 @@
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
#series-delete-indicator {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#series-delete-indicator.htmx-request {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.case-detail-section {
|
||||||
|
border: 1px solid rgba(255,255,255,0.08);
|
||||||
|
background: rgba(255,255,255,0.02);
|
||||||
|
}
|
||||||
|
.case-detail-section .card-header {
|
||||||
|
background: rgba(255,255,255,0.03);
|
||||||
|
border-bottom: 1px solid rgba(255,255,255,0.08);
|
||||||
|
}
|
||||||
|
.case-detail-section .card-body {
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
.case-detail-section .list-group-item {
|
||||||
|
background: transparent;
|
||||||
|
border-color: rgba(255,255,255,0.08);
|
||||||
|
}
|
||||||
|
.case-detail-section table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
@media (max-width: 991.98px) {
|
@media (max-width: 991.98px) {
|
||||||
.series-toolbar {
|
.series-toolbar {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -1941,6 +2035,12 @@
|
|||||||
.series-toolbar-btn {
|
.series-toolbar-btn {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
.case-detail-section .card-header {
|
||||||
|
padding: .65rem .85rem;
|
||||||
|
}
|
||||||
|
.case-detail-section .card-body {
|
||||||
|
padding: .75rem .85rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@media (max-width: 575.98px) {
|
@media (max-width: 575.98px) {
|
||||||
.series-block {
|
.series-block {
|
||||||
|
|||||||
+187
-187
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user