Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,4 @@ __pycache__/
# Spyder project settings
.spyderproject

.idea/
.idea//tmp/
32 changes: 32 additions & 0 deletions controllers/endpoints/courses.py
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,38 @@ def modify_time():
new_limits.append({"assignment": assignment.encode_json(), "time_limit": shown_amount})
return ajax_success({'new_limits': new_limits})

@courses.route('/reset_start_date', methods=['POST'])
@courses.route('/reset_start_date/', methods=['POST'])
@login_required
def reset_start_date():
course_id = get_course_id(False)
user, user_id = get_user()
student_id = maybe_int(request.values.get("student_id", ""))
assignment_ids = request.values.get("assignment_ids", "")
# Check permissions
require_course_instructor(g.user, course_id)
# Load Resources
course = Course.by_id(course_id)
student = User.by_id(student_id)
check_resource_exists(student, "User", student_id)
check_resource_exists(course, "Course", course_id)
# Reset the date_started for the assignments of this user
reset_assignments = []
for assignment_id in assignment_ids.split(","):
assignment_id = maybe_int(assignment_id)
if assignment_id is None:
continue
assignment = Assignment.by_id(assignment_id)
submission = assignment.load_or_new_submission(student_id, course_id)
# Reset the start date
old_date = submission.date_started
submission.edit(dict(date_started=None))
make_log_entry(submission.id, submission.version, assignment_id, assignment.version,
course_id, student_id, SubmissionLogEvent.RESET_START_DATE,
message=f"User {user_id} reset start date from `{old_date}`")
reset_assignments.append({"assignment": assignment.encode_json(), "old_date": str(old_date) if old_date else None})
return ajax_success({'reset_assignments': reset_assignments})

@courses.route('/manage_time', methods=['GET', 'POST'])
@courses.route('/manage_time/', methods=['GET', 'POST'])
@login_required
Expand Down
3 changes: 2 additions & 1 deletion models/enums/logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,5 @@ class SubmissionLogEvent(StrEnum):
TRANSFER = "transfer"
CANVAS = "canvas"
EXTEND_TIME = "extend_time"
START_TIMER = "start_timer"
START_TIMER = "start_timer"
RESET_START_DATE = "reset_start_date"
34 changes: 34 additions & 0 deletions templates/courses/manage_time.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,35 @@
);
}

function resetStartDate(studentId, resultTarget) {
var selected = $("#assignment-select").val().join(",");
if (selected === null || selected.length === 0) {
alert("Please select at least one assignment to update.");
return;
}
if (!confirm("Are you sure you want to reset the start date for this student? This will allow them to restart the exam timer.")) {
return;
}
$.post(
{{ url_for('courses.reset_start_date')|tojson}},
{
assignment_ids: selected,
student_id: studentId,
course_id: {{ course_id }}
},
function(data) {
if (data.success) {
const message = data.reset_assignments.map(
update => `${update.assignment.name}: Start date reset`
).join(", ");
$("#"+resultTarget).html(message + "<br><em>Student can now restart the timer.</em>");
} else {
alert("Error: " + data.message);
}
},
);
}

function MainModel() {
var self = this;
}
Expand Down Expand Up @@ -154,6 +183,11 @@ <h1>Manage Exam Time for Users</h1>
onclick="modifyTimeLimit({{ user.id }},'', 'time-limit-report-{{ user.id }}')">
Unset (use default time)
</button>
<br><br>
<button class="btn btn-sm btn-outline-warning" id="reset-start-date-{{ user.id }}"
onclick="resetStartDate({{ user.id }}, 'time-limit-report-{{ user.id }}')">
Reset Start Date
</button>
{# <span class="ml-4">#}
{# <input type="text" id="custom-set-time-amount">#}
{# <button class="btn btn-sm btn-outline-secondary" #}
Expand Down