Skip to content

Commit

Permalink
allow arbitrary pages for versioning in the UI
Browse files Browse the repository at this point in the history
  • Loading branch information
IonMich committed Dec 8, 2023
1 parent d23b25f commit 6da7f0c
Show file tree
Hide file tree
Showing 5 changed files with 356 additions and 142 deletions.
220 changes: 188 additions & 32 deletions assignments/static/assignments/detail.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,25 @@ async function getIdentifyPages() {
return identifyPages;
}

async function getVersioningPages() {
const url_preferences = "/profile/preferences/";
const options = {
method: "GET",
headers: {
"Content-Type": "application/json",
}
};
let versioningPages = null;
try {
const response = await fetch(url_preferences, options);
const data = await response.json();
versioningPages = data.versioning_pages;
} catch (error) {
console.log(error);
}
return versioningPages;
}

const courseId = JSON.parse(document.getElementById('course_id').textContent);
const assignmentId = JSON.parse(document.getElementById('assignment_id').textContent);

Expand Down Expand Up @@ -188,7 +207,129 @@ async function initializeCheckedPages() {
});
}

async function initializeVersioningCheckedPages() {
let checked_pages = await getVersioningPages();
console.log("checked_pages", checked_pages);
console.log("course_id", courseId, "assignment_id", assignmentId);
let checkedPages;
let default_type;
if (checked_pages && checked_pages[courseId] && checked_pages[courseId][assignmentId]) {
checkedPages = checked_pages[courseId][assignmentId];
default_type = 'assignment';
} else {
if (checked_pages && checked_pages[courseId] && checked_pages[courseId]["default"]) {
checkedPages = checked_pages[courseId]["default"];
default_type = "course";
} else if (checked_pages && checked_pages["default"]) {
checkedPages = checked_pages["default"];
default_type = "user";
} else {
checkedPages = [0,];
default_type = "global";
}
// the checkedPages is set here to a default set of checked pages
}
console.log("Pages to check:", checkedPages, "default_type:", default_type);
// initialize the text describing the checked pages to say `their ID on pages ${checkedPages}`
// const checkedPagesText = document.getElementById('versioning-method-text');
// if (checkedPages.length === 1) {
// // convert the page number to 1-indexed
// checkedPagesText.innerHTML = `on page ${checkedPages[0] + 1}`;
// } else if (checkedPages.length > 1) {
// // convert the page numbers to 1-indexed
// checkedPagesText.innerHTML = `on pages ${checkedPages.map(page => page + 1).join(', ')}`;
// } else {
// checkedPagesText.innerHTML = "";
// }
// select inputs whose name starts with "page-selected-"
// names are created with forloop.counter, so they are 1-indexed
const pageCheckInputs = document.querySelectorAll('input[name^="versioningpage-selected-"]');
pageCheckInputs.forEach(input => {
// get the page number from the input name
let pageNumber = input.name.split('-')[2];
pageNumber = parseInt(pageNumber);
console.log(pageNumber);
// if the page number is in checkedPages, set the input to checked
// We subtract 1 from the page number because the checkedPages is 0-indexed
if (checkedPages.includes(Math.max(pageNumber - 1, 0))) {
input.checked = true;
console.log("checked");
}
});
}

async function handleDefaultVersioningPages(event) {
// stop the default action of the button
event.preventDefault();

const versioningForm = document.getElementById('initiateVersioningForm');
const csrfToken = versioningForm.querySelector("input[name='csrfmiddlewaretoken']").value;

// get all the checkboxes in the form
const checkboxes = versioningForm.querySelectorAll("input[type='checkbox']");
// get the indices of the checked checkboxes
let page_indices = [];
for (let i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked) {
page_indices.push(i);
}
}
console.log(page_indices);
const url = "/profile/preferences/edit/";
const data = {
"versioning_pages": {
[courseId]: {
[assignmentId]: page_indices
}
}
};

const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRFToken": csrfToken
},
body: JSON.stringify(data)
};

try {
const response = await fetch(url, options);
const responseJSON = await response.json();
console.log(responseJSON);
// if the message is success
if (responseJSON['success']) {
// create a toast
const toast = createToastElement(
"Default pages for versioning submisssions updated successfully.",
"success"
);
// append the toast to the toast-container
const toastContainer = document.querySelector('#toast-container');
toastContainer.appendChild(toast);
console.log("toast", toast);
let toastElement = new bootstrap.Toast(toast,
{delay: 10000, autohide: false});
toastElement.show();
}
} catch (error) {
// create a toast
const toast = createToastElement(
"Default pages for versioning submissions could not be updated.",
"danger"
);
// append the toast to the toast-container
const toastContainer = document.querySelector('#toast-container');
toastContainer.appendChild(toast);
console.log("toast", toast);
let toastElement = new bootstrap.Toast(toast,
{delay: 10000, autohide: false});
toastElement.show();
}
}

const identifyStudentsForm = document.getElementById('identifyStudentsForm');
const versioningSubmissionsForm = document.getElementById('versioningSubmissionsForm');

if (identifyStudentsForm) {
identifyStudentsForm.addEventListener("submit", (event) =>
Expand Down Expand Up @@ -1042,8 +1183,6 @@ if (updateGradingSchemeButton) {
const equalGrades = document.getElementById('equal_grades').checked;
const maxGrades = document.getElementById('max_grades').value;
const applyToAll = document.getElementById('apply_to_all').checked;

const courseId = JSON.parse(document.getElementById('course_id').textContent);

const url = '/course/' + courseId + '/grading_scheme/update/';
const data = {
Expand Down Expand Up @@ -1086,43 +1225,55 @@ if (updateGradingSchemeButton) {
// Clustering/versioning changes made here
const versionButton = document.getElementById('initiateVersioningBtn');
if(versionButton) {
initializeVersioningCheckedPages();
versionButton.addEventListener('click', async (event) => {
// change the button text to a spinner
// store the original text of the button
const buttonText = versionButton.textContent;
versionButton.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Versioning...';
// disable the button
versionButton.disabled = true;

const url = `/courses/${courseId}/assignments/${assignmentId}/version/`
const data = {
assignment_id: assignmentId
};
initiateVersioning(event)
});
}

const versionForm = document.getElementById('initiateVersioningForm');
const csrfToken = versionForm.querySelector("input[name='csrfmiddlewaretoken']").value;
async function initiateVersioning (event) {
// change the button text to a spinner
// store the original text of the button
const buttonText = versionButton.textContent;
versionButton.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Versioning...';
// disable the button
versionButton.disabled = true;
const versionForm = document.getElementById('initiateVersioningForm');
const formData = new FormData(versionForm);
const numbers_selected = Array.from(formData.keys()).filter(key => key.startsWith('versioningpage-selected-')).map(key => key.split('-')[2]);

const url = `/courses/${courseId}/assignments/${assignmentId}/version/`
const data = {
pages: numbers_selected,
assignment_id: assignmentId
};
console.log(numbers_selected, data, JSON.stringify(data), typeof(data), JSON.stringify(data));
const csrfToken = versionForm.querySelector("input[name='csrfmiddlewaretoken']").value;

const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrfToken

},
body: JSON.stringify(data)
};
try {
const response = await fetch(url, options)
const data = await response.json();
const options = {
method: 'POST',
headers: {
// 'Content-Type': 'application/json',
'X-CSRFToken': csrfToken

},
body: JSON.stringify(data)
};
try {
const response = await fetch(url, options)
const data = await response.json();
if (data["success"]) {
// call the function to display the message
render_version_modal(data["submissions"], [], [], 0);
console.log(data);
} catch (error) {
console.log(error);
} else {
throw new Error("Error while versioning");
}
versionButton.innerHTML = buttonText;
versionButton.disabled = false;
});
} catch (error) {
console.log(error);
}
versionButton.innerHTML = buttonText;
versionButton.disabled = false;
}

const saveVersionCommentsBtn = document.getElementById('updateClusterBtn');
Expand Down Expand Up @@ -1263,6 +1414,11 @@ if(btnDefaultIdentifyPages) {
btnDefaultIdentifyPages.addEventListener('click', handleDefaultIdentifyPages);
}

const btnDefaultVersioningPages = document.getElementById('btn-default-versioning-pages');
if(btnDefaultVersioningPages) {
btnDefaultVersioningPages.addEventListener('click', handleDefaultVersioningPages);
}

async function handleDefaultIdentifyPages(event) {
// stop the default action of the button
event.preventDefault();
Expand Down
25 changes: 22 additions & 3 deletions assignments/templates/assignments/detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,7 @@ <h1 class="modal-title fs-5" id="settingsModalLabel">Select grading scheme</h1>
id="btn-pageSelect-{{forloop.counter}}"
autocomplete="off"
name="page-selected-{{forloop.counter}}"
value="1"
{% if forloop.counter in page_UIDs %}checked{% endif %}>
value="1">
<label class="btn btn-outline-success mb-3" for="btn-pageSelect-{{forloop.counter}}">{{forloop.counter}}</label>
{% endfor %}
{% endwith %}
Expand Down Expand Up @@ -303,6 +302,26 @@ <h1 class="modal-title fs-5" id="clusterModalLabel">Versions</h1>
<form id="initiateVersioningForm" action="" method="POST">
{% csrf_token %}
<button type="button" id="initiateVersioningBtn" class="btn btn-primary d-block m-auto">Identify Versions</button>
<div class="d-flex flex-column align-items-center mt-3">
<p class="mt-3 mb-1">Page(s) to search for versions:</p>
<div class="ms-1">
{% with ''|center:assignment.get_max_page_number as range %}
{% for _ in range %}
<input
type="checkbox" class="btn-check"
id="btn-versioningPageSelect-{{forloop.counter}}"
autocomplete="off"
name="versioningpage-selected-{{forloop.counter}}"
value="1">
<label class="btn btn-outline-success mb-3" for="btn-versioningPageSelect-{{forloop.counter}}">{{forloop.counter}}</label>
{% endfor %}
{% endwith %}
</div>
{% comment %} make default button: {% endcomment %}
<div class="mb-3">
<button type="button" class="btn btn-outline-secondary btn-sm" id="btn-default-versioning-pages">Set as Default</button>
</div>
</div>
</form>
</div>
<div id="versionsDetails" class="modal-body">
Expand All @@ -314,7 +333,7 @@ <h1 class="modal-title fs-5" id="clusterModalLabel">Versions</h1>
</form>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" id="resetClusterBtn" class="btn btn-danger">Reset</button>
<button type="button" id="updateClusterBtn" class="btn btn-primary">Save</button>
<button type="button" id="updateClusterBtn" class="btn btn-primary">Save Comments</button>
</div>
</div>
</div>
Expand Down
Loading

0 comments on commit 6da7f0c

Please sign in to comment.