Enhance case collection update form with additional instructions and improve case detail links with icons

This commit is contained in:
Ross
2025-08-04 12:59:42 +01:00
parent 0af6b25349
commit b3304b6113
3 changed files with 147 additions and 70 deletions
@@ -3,6 +3,7 @@
{% load static %}
{% block content %}
<h2>Update Cases for Case: {{ object.title }}</h2>
This form allows you to update the cases associated with this collection. You can add, remove, or reorder cases as needed. This functionality is also available on the collection overview page (which is likely easier to use).
<form method="post" enctype="multipart/form-data" data-bs-theme="dark">
{% csrf_token %}
{% crispy form form.helper %}
+5 -4
View File
@@ -21,25 +21,26 @@
<li data-question_pk={{casedetail.case.pk}}><a title="sort_order: {{casedetail.sort_order}}" href="{% url 'atlas:collection_case_view' pk=collection.pk case_number=forloop.counter0 %}">Case {{forloop.counter}}</a>
: {{casedetail.case.title}}
(<a href="{% url 'atlas:collection_case_displaysetup' casedetail.collection.pk casedetail.case.pk %}">setup default display</a>
(<a href="{% url 'atlas:collection_case_displaysetup' casedetail.collection.pk casedetail.case.pk %}"><i class="bi bi-display" title="Setup default display"></i></a>
{% if casedetail.default_viewerstate %}
<i class="bi bi-check text-success" title="This case has a default viewerstate defined"></i>
{% endif %}
)
{% if collection.collection_type == "QUE" %}
(<a href='{% url "atlas:collection_case_details" casedetail.collection.pk casedetail.case.pk %}'>edit questions</a>
&nbsp;
(<a href='{% url "atlas:collection_case_details" casedetail.collection.pk casedetail.case.pk %}'>
{% if casedetail.question_schema %}
<i class="bi bi-question-square text-success" title="This case has questions defined."></i>
{% else %}
<i class="bi bi-question-square text-danger" title="This case has no questions defined."></i>
{% endif %}
</a>
)
{% endif %}
{% if casedetail.case.previous_case %}
(<a href='{% url "atlas:collection_case_priors" casedetail.collection.pk casedetail.case.pk %}'>manage priors</a>)
(<a href='{% url "atlas:collection_case_priors" casedetail.collection.pk casedetail.case.pk %}'>
<i class="bi bi-link-45deg" title="Manage priors"></i></a>)
{% endif %}
</li>
+141 -66
View File
@@ -13,22 +13,22 @@
})
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
.done(function (data) {
console.log(data);
console.log(data);
if (data.status == "success") {
toastr.info(`Exam: ${data.name} [${data.id}]
if (data.status == "success") {
toastr.info(`Exam: ${data.name} [${data.id}]
Active state changed to: ${data.active}.`)
}
}
// show some message according to the response.
// For eg. A message box showing that the status has been changed
})
})
.fail(function (data) {
console.log(data)
toastr.error(`Failed to change state<br/>${data.responseJSON.status}`);
})
console.log(data)
toastr.error(`Failed to change state<br/>${data.responseJSON.status}`);
})
.always(function () {
console.log('[Done]');
})
console.log('[Done]');
})
})
$("#exam-publish-results-switch, .exam-publish-results-switch").on("change", function (evt) {
$.ajax({
@@ -42,21 +42,21 @@
})
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
.done(function (data) {
console.log(data);
console.log(data);
if (data.status == "success") {
toastr.info(`Exam: ${data.name} [${data.id}]
if (data.status == "success") {
toastr.info(`Exam: ${data.name} [${data.id}]
Published state changed to: ${data.publish_results}.`)
}
}
// show some message according to the response.
// For eg. A message box showing that the status has been changed
})
})
.fail(function (data) {
toastr.error(`Failed to change state`);
})
toastr.error(`Failed to change state`);
})
.always(function () {
console.log('[Done]');
})
console.log('[Done]');
})
})
$(".exam-archived-switch").on("change", function (evt) {
$.ajax({
@@ -70,21 +70,21 @@
})
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
.done(function (data) {
console.log(data);
console.log(data);
if (data.status == "success") {
toastr.info(`Exam: ${data.name} [${data.id}]
if (data.status == "success") {
toastr.info(`Exam: ${data.name} [${data.id}]
Archived state changed to: ${data.archive}.`)
}
}
// show some message according to the response.
// For eg. A message box showing that the status has been changed
})
})
.fail(function (data) {
toastr.error(`Failed to change state`);
})
toastr.error(`Failed to change state`);
})
.always(function () {
console.log('[Done]');
})
console.log('[Done]');
})
})
$("#button-open-access").click(function (evt) {
$.ajax({
@@ -98,21 +98,21 @@
})
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
.done(function (data) {
console.log(data);
console.log(data);
if (data.status == "success") {
toastr.info('Question access state changed.');
} else {
toastr.warning("Error");
toastr.info(data.status);
}
})
if (data.status == "success") {
toastr.info('Question access state changed.');
} else {
toastr.warning("Error");
toastr.info(data.status);
}
})
.fail((e) => {
toastr.warning(`Error, ${e}`);
})
toastr.warning(`Error, ${e}`);
})
.always(function () {
console.log('[Done]');
})
console.log('[Done]');
})
})
$("#button-closed-access").click(function (evt) {
$.ajax({
@@ -126,42 +126,65 @@
})
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
.done(function (data) {
console.log(data);
console.log(data);
if (data.status == "success") {
toastr.info('Question access state changed.');
} else {
toastr.warning("Error");
toastr.info(data.status);
}
})
if (data.status == "success") {
toastr.info('Question access state changed.');
} else {
toastr.warning("Error");
toastr.info(data.status);
}
})
.fail((e) => {
toastr.warning(`Error, ${e}`);
})
toastr.warning(`Error, ${e}`);
})
.always(function () {
console.log('[Done]');
})
console.log('[Done]');
})
})
$("#button-edit-order").click(function (evt) {
$(this).remove();
sortable('.sortable');
$("#full-question-list").addClass('sorting');
// Add tooltip to each li to indicate drag-to-reorder
$("#full-question-list li").attr("title", "Drag to reorder");
$("#full-question-list").after($("<button id='random-order-button'>Randomise order</button>").click(() =>{
var ul = document.getElementById("full-question-list");
for (var i = ul.children.length; i >= 0; i--) {
ul.appendChild(ul.children[Math.random() * i | 0]);
}
var ul = document.getElementById("full-question-list");
for (var i = ul.children.length; i >= 0; i--) {
ul.appendChild(ul.children[Math.random() * i | 0]);
}
}))
$("#full-question-list li").each((n, el) => {
// Add up/down arrows at the start of each <li>
const upBtn = $("<button class='move-up btn btn-sm' title='Move up'>&#8593;</button>").click(function(e){
e.preventDefault();
const li = $(this).closest("li");
const prev = li.prev();
if (prev.length) {
prev.before(li);
}
});
const downBtn = $("<button class='move-down btn btn-sm' title='Move down'>&#8595;</button>").click(function(e){
e.preventDefault();
const li = $(this).closest("li");
const next = li.next();
if (next.length) {
next.after(li);
}
});
$(el).prepend(downBtn).prepend(upBtn);
// Existing delete button logic
$(el).append($(
"<span class='exam-question-delete flex-col'><button>DELETE</button></span>"
).click(() => {
el.remove();
}));
})
});
$("#full-question-list").after($(
"<button title='click and drag questions to change order'>Save exam order</button>"
@@ -181,18 +204,70 @@
})
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
.done(function (data) {
console.log(data);
console.log(data);
if (data.status == "success") {
toastr.info('Exam order changed.')
}
})
if (data.status == "success") {
toastr.info('Exam order changed.')
}
})
.always(function () {
console.log('[Done]');
})
console.log('[Done]');
})
}));
// Add cancel button
$("#full-question-list").after($(
"<button id='cancel-order-button' class='ms-2 btn btn-secondary btn-sm'>Cancel</button>"
).click(() => {
location.reload();
}));
});
});
</script>
</script>
<style>
#full-question-list .move-up,
#full-question-list .move-up,
#full-question-list .move-down {
margin-right: 4px;
padding: 2px 6px;
font-size: 1em;
background: #23272b;
color: #f8f9fa;
border: 1px solid #495057;
border-radius: 3px;
cursor: pointer;
transition: background 0.2s, color 0.2s;
}
#full-question-list .move-up:hover,
#full-question-list .move-down:hover {
background: #495057;
color: #fff;
}
#full-question-list.sorting li {
border: 1px dashed #495057;
}
#full-question-list .exam-question-delete button {
margin-left: auto;
margin-right: 0;
display: block;
float: right;
padding: 1px 6px;
font-size: 0.85em;
opacity: 1;
background: #dc3545;
color: #fff;
border: 1px solid #b52a37;
border-radius: 3px;
cursor: pointer;
transition: background 0.2s, color 0.2s;
}
#full-question-list .exam-question-delete button:hover {
background: #b52a37;
color: #fff;
}
</style>