improve findings

This commit is contained in:
Ross
2025-05-19 11:15:40 +01:00
parent ead5bfcace
commit 503c8f854a
13 changed files with 329 additions and 14 deletions
@@ -214,8 +214,6 @@
>
<span>
<a href="{{series.get_absolute_url}}?show_finding={{finding.pk}}"><button class="btn btn-primary btn-sm">View</button></a>
<a target="_blank" href="{{series.get_absolute_url}}?show_finding={{finding.pk}}"><button class="btn btn-primary btn-sm">Popup</button></a>
<button class="btn btn-secondary btn-sm view-finding-modal" data-finding-id="{{ finding.pk }}" data-series-id="{{ series.pk }}">
View in Modal
</button>
+63 -1
View File
@@ -51,8 +51,70 @@
$('#add_more_resource').click(() => { add_resource_input_form() });
})
</script>
{% comment %} document.addEventListener("DOMContentLoaded", function () {
// Select all text input fields and textareas
const textFields = document.querySelectorAll("input[type='text'], textarea");
textFields.forEach((field) => {
// Create a clear button for each text field or textarea
const clearButton = document.createElement("button");
clearButton.type = "button";
clearButton.className = "btn btn-danger btn-sm clear-input-button";
clearButton.textContent = "×";
// Wrap the input field or textarea in a container with position-relative
const wrapper = document.createElement("div");
wrapper.className = "position-relative";
field.parentNode.insertBefore(wrapper, field);
wrapper.appendChild(field);
wrapper.appendChild(clearButton);
// Function to toggle the visibility of the clear button
const toggleClearButton = () => {
if (field.value.trim() !== "") {
clearButton.classList.add("show"); // Add the "show" class
} else {
clearButton.classList.remove("show"); // Remove the "show" class
}
};
// Initial check
toggleClearButton();
// Add event listeners to monitor changes in the input field or textarea
field.addEventListener("input", toggleClearButton);
// Add click event to clear the field or textarea
clearButton.addEventListener("click", function () {
field.value = ""; // Clear the field
toggleClearButton(); // Update the button visibility
});
});
});
{% endcomment %}
</script>
{% comment %} <style>
/* Ensure the parent container is positioned relatively */
.position-relative {
position: relative;
}
/* Style the clear button */
.clear-input-button {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
display: none; /* Hidden by default */
z-index: 1;
}
/* Show the clear button only when the input field or textarea is hovered and contains text */
.position-relative:hover .clear-input-button.show {
display: inline-block;
}
</style> {% endcomment %}
<!-- {{ form.media }} -->
{% endblock %}
{% block content %}
@@ -0,0 +1,124 @@
<div class="modal-dialog modal-dialog-centered related-finding-modal bg-dark">
<div class="modal-content bg-dark text-light border-secondary">
<div class="modal-content bg-dark text-light">
<h5 class="modal-title">Related findings from case</h5>
</div>
<div class="modal-body">
<details class="help-text">
<summary><i class="bi bi-info-circle"></i> Help</summary>
<p>This form is designed to quickly populate the same finding across different series.</p>
<p>Cloning a finding from this form will populate the details with a blank viewport (you will need to add visual annotation and set the display as intended).</p>
</details>
<ul class="list-group list-group-flush bg-dark">
{% for finding in findings %}
<li class="list-group-item bg-dark text-light border-secondary">
<div class="fw-bold mb-1 text-info">{{ finding.title }}</div>
{% if finding.description %}
Description:
<div class="text-muted small mb-1" style="color:#b0b0b0 !important;">{{ finding.description|truncatechars:100 }}</div>
{% endif %}
{% if finding.findings.all %}
<div class="mb-1">
<span class="fw-semibold text-warning">Findings:</span>
{% for subfinding in finding.findings.all %}
{{ subfinding.get_link }}{% if not forloop.last %}, {% endif %}
{% endfor %}
</div>
{% endif %}
{% if finding.structures.all %}
<div class="mb-1">
<span class="fw-semibold text-warning">Structures:</span>
{% for structure in finding.structures.all %}
{{ structure.get_link }}{% if not forloop.last %}, {% endif %}
{% endfor %}
</div>
{% endif %}
{% if finding.conditions.all %}
<div class="mb-1">
<span class="fw-semibold text-warning">Conditions:</span>
{% for condition in finding.conditions.all %}
{{ condition.get_link }}{% if not forloop.last %}, {% endif %}
{% endfor %}
</div>
{% endif %}
<div class="mt-2">
<button
class="btn btn-sm btn-primary text-light use-finding-base-btn"
type="button"
data-finding-id="{{ finding.pk }}"
data-finding-description="{{ finding.description|default_if_none:''|escapejs }}"
{% if finding.conditions.all %}
data-finding-conditions="{% for c in finding.conditions.all %}{{ c.pk }}{% if not forloop.last %},{% endif %}{% endfor %}"
data-finding-conditions-names="{% for c in finding.conditions.all %}{{ c }}{% if not forloop.last %}|{% endif %}{% endfor %}"
{% endif %}
{% if finding.structures.all %}
data-finding-structures="{% for s in finding.structures.all %}{{ s.pk }}{% if not forloop.last %},{% endif %}{% endfor %}"
data-finding-structures-names="{% for s in finding.structures.all %}{{ s }}{% if not forloop.last %}|{% endif %}{% endfor %}"
{% endif %}
{% if finding.findings.all %}
data-finding-findings="{% for f in finding.findings.all %}{{ f.pk }}{% if not forloop.last %},{% endif %}{% endfor %}"
data-finding-findings-names="{% for f in finding.findings.all %}{{ f }}{% if not forloop.last %}|{% endif %}{% endfor %}"
{% endif %}
>Use as finding base</button>
</div>
</li>
{% endfor %}
</ul>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
<script>
document.querySelectorAll('.use-finding-base-btn').forEach(function(btn) {
btn.addEventListener('click', function() {
console.log('Button clicked:', btn);
// Example: populate #hidden-form fields with finding data
const form = window.parent.document.querySelector('#hidden-form');
if (!form) return;
form.style.display = 'block'; // Show the form if hidden
document.querySelector('#add-finding-button').style.display = 'none'; // Hide the button
// Set values (adjust field names as needed)
form.querySelector('[name="description"]').value = btn.getAttribute('data-finding-description');
function setSelect2Values(fieldName, dataAttr, namesAttr) {
const values = btn.getAttribute(dataAttr);
const names = btn.getAttribute(namesAttr);
const select = form.querySelector(`[name="${fieldName}"]`);
if (values && select) {
const valueArr = values.split(',').map(v => v.trim()).filter(Boolean);
const nameArr = names ? names.split('|') : [];
valueArr.forEach((val, idx) => {
if (val && !Array.from(select.options).some(opt => opt.value == val)) {
const opt = document.createElement('option');
opt.value = val;
opt.text = nameArr[idx] || val;
opt.selected = true;
select.appendChild(opt);
}
});
$(select).val(valueArr).trigger('change');
}
}
// Usage inside your click handler:
setSelect2Values('conditions', 'data-finding-conditions', 'data-finding-conditions-names');
setSelect2Values('structures', 'data-finding-structures', 'data-finding-structures-names');
setSelect2Values('findings', 'data-finding-findings', 'data-finding-findings-names');
// Optionally, close the modal (if using Bootstrap modal JS)
const modal = window.parent.document.querySelector('#clone-findings-modal');
if (modal) {
const modalInstance = bootstrap.Modal.getInstance(modal);
if (modalInstance) modalInstance.hide();
}
});
});
</script>
+17
View File
@@ -47,6 +47,13 @@
{% if editing_finding < 1 %}
<button id="add-finding-button">Add finding</button>
{% endif %}
<button id="clone-finding-button" title="Click to copy the details of a finding that is already associated with the series/case"
hx-get="{% url 'atlas:series_finding_related' series.pk %}"
hx-target="#clone-findings-modal"
hx-trigger="click"
data-bs-toggle="modal"
data-bs-target="#clone-findings-modal"
>Clone existing finding</button>
<button id="reset-viewport-button">Reset viewport</button>
<div id="finding-form">
<div class="hide" id="hidden-form">
@@ -182,6 +189,16 @@
{% endif %}
<div id="clone-findings-modal"
class="modal modal-blur fade"
style="display: none"
aria-hidden="false"
tabindex="-1">
<div class="modal-dialog modal-dialog-centered related-finding-modal" style="max-width: 700px;">
<div class="modal-content"></div>
</div>
</div>
<script>
$(document).ready(function () {