improve findings
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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 () {
|
||||
|
||||
Reference in New Issue
Block a user