Bulk beta tester add/remove on instructor dashboard
LMS-1287
This commit is contained in:
committed by
Sarina Canelake
parent
2d6bfbadec
commit
d7c9491f23
@@ -278,6 +278,54 @@ def students_update_enrollment(request, course_id):
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('instructor')
|
||||
@common_exceptions_400
|
||||
@require_query_params(
|
||||
emails="stringified list of emails",
|
||||
action="add or remove",
|
||||
)
|
||||
def bulk_modify_access(request, course_id):
|
||||
action = request.GET.get('action')
|
||||
emails_raw = request.GET.get('emails')
|
||||
emails = _split_input_list(emails_raw)
|
||||
results = []
|
||||
rolename = 'beta'
|
||||
course = get_course_by_id(course_id)
|
||||
for email in emails:
|
||||
try:
|
||||
user = User.objects.get(email=email)
|
||||
if action == 'add':
|
||||
allow_access(course, user, rolename)
|
||||
elif action == 'remove':
|
||||
revoke_access(course, user, rolename)
|
||||
else:
|
||||
return HttpResponseBadRequest(strip_tags(
|
||||
"Unrecognized action '{}'".format(action)
|
||||
))
|
||||
results.append({
|
||||
'email': email,
|
||||
'error': False,
|
||||
})
|
||||
|
||||
# catch and log any exceptions
|
||||
# so that one error doesn't cause a 500.
|
||||
except Exception as exc: # pylint: disable=W0703
|
||||
log.exception("Error while #{}ing student")
|
||||
log.exception(exc)
|
||||
results.append({
|
||||
'email': email,
|
||||
'error': True,
|
||||
})
|
||||
|
||||
response_payload = {
|
||||
'action': action,
|
||||
'results': results,
|
||||
}
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('instructor')
|
||||
|
||||
@@ -11,6 +11,8 @@ urlpatterns = patterns('', # nopep8
|
||||
'instructor.views.api.list_course_role_members', name="list_course_role_members"),
|
||||
url(r'^modify_access$',
|
||||
'instructor.views.api.modify_access', name="modify_access"),
|
||||
url(r'^bulk_modify_access$',
|
||||
'instructor.views.api.bulk_modify_access', name="bulk_modify_access"),
|
||||
url(r'^get_grading_config$',
|
||||
'instructor.views.api.get_grading_config', name="get_grading_config"),
|
||||
url(r'^get_students_features(?P<csv>/csv)?$',
|
||||
|
||||
@@ -146,6 +146,7 @@ def _section_membership(course_id, access):
|
||||
'access': access,
|
||||
'enroll_button_url': reverse('students_update_enrollment', kwargs={'course_id': course_id}),
|
||||
'unenroll_button_url': reverse('students_update_enrollment', kwargs={'course_id': course_id}),
|
||||
'modify_beta_testers_button_url': reverse('bulk_modify_access', kwargs={'course_id': course_id}),
|
||||
'list_course_role_members_url': reverse('list_course_role_members', kwargs={'course_id': course_id}),
|
||||
'modify_access_url': reverse('modify_access', kwargs={'course_id': course_id}),
|
||||
'list_forum_members_url': reverse('list_forum_members', kwargs={'course_id': course_id}),
|
||||
|
||||
@@ -160,50 +160,90 @@ class AuthListWidget extends MemberListWidget
|
||||
error: std_ajax_err => cb? gettext "Error changing user's permissions."
|
||||
|
||||
|
||||
class BetaTesterBulkAddition
|
||||
constructor: (@$container) ->
|
||||
# gather elements
|
||||
@$emails_input = @$container.find("textarea[name='student-emails-for-beta']")
|
||||
@$btn_beta_testers = @$container.find("input[name='beta-testers']")
|
||||
# @$checkbox_emailstudents = @$container.find("input[name='email-students']")
|
||||
@$task_response = @$container.find(".request-response")
|
||||
@$request_response_error = @$container.find(".request-response-error")
|
||||
|
||||
# click handlers
|
||||
@$btn_beta_testers.click =>
|
||||
# emailStudents = @$checkbox_emailstudents.is(':checked')
|
||||
send_data =
|
||||
action: $(event.target).data('action')
|
||||
emails: @$emails_input.val()
|
||||
email_students: emailStudents
|
||||
|
||||
$.ajax
|
||||
dataType: 'json'
|
||||
url: @$btn_beta_testers.data 'endpoint'
|
||||
data: send_data
|
||||
success: (data) => @display_response data
|
||||
# error: std_ajax_err => @fail_with_error "Error enrolling/unenrolling students."
|
||||
|
||||
# success: (data) => @display_response data
|
||||
|
||||
# fail_with_error: (msg) ->
|
||||
# console.warn msg
|
||||
# @$task_response.empty()
|
||||
# @$request_response_error.empty()
|
||||
# @$request_response_error.text msg
|
||||
|
||||
display_response: (data_from_server) ->
|
||||
@$task_response.empty()
|
||||
# @$request_response_error.empty()
|
||||
errors = []
|
||||
sucesses = []
|
||||
for student_results in data_from_server.results
|
||||
if student_results.error
|
||||
errors.push student_results
|
||||
else
|
||||
sucesses.push student_results
|
||||
|
||||
console.log(sr.email for sr in sucesses)
|
||||
|
||||
render_list = (label, emails) =>
|
||||
task_res_section = $ '<div/>', class: 'request-res-section'
|
||||
task_res_section.append $ '<h3/>', text: label
|
||||
email_list = $ '<ul/>'
|
||||
task_res_section.append email_list
|
||||
|
||||
for email in emails
|
||||
email_list.append $ '<li/>', text: email
|
||||
|
||||
@$task_response.append task_res_section
|
||||
|
||||
render_list gettext("these students were added as beta testers"), (sr.email for sr in sucesses)
|
||||
render_list gettext("these students were not added as beta testers"), (sr.email for sr in errors)
|
||||
|
||||
# Wrapper for the batch enrollment subsection.
|
||||
# This object handles buttons, success and failure reporting,
|
||||
# and server communication.
|
||||
class BatchEnrollment
|
||||
constructor: (@$container) ->
|
||||
# gather elements
|
||||
@$emails_input = @$container.find("textarea[name='student-emails']'")
|
||||
@$btn_enroll = @$container.find("input[name='enroll']'")
|
||||
@$btn_unenroll = @$container.find("input[name='unenroll']'")
|
||||
@$checkbox_autoenroll = @$container.find("input[name='auto-enroll']'")
|
||||
@$checkbox_emailstudents = @$container.find("input[name='email-students']'")
|
||||
@$emails_input = @$container.find("textarea[name='student-emails']")
|
||||
@$enrollment_button = @$container.find(".enrollment-button")
|
||||
@$checkbox_autoenroll = @$container.find("input[name='auto-enroll']")
|
||||
@$checkbox_emailstudents = @$container.find("input[name='email-students']")
|
||||
@$task_response = @$container.find(".request-response")
|
||||
@$request_response_error = @$container.find(".request-response-error")
|
||||
|
||||
# attach click handlers
|
||||
|
||||
@$btn_enroll.click =>
|
||||
emailStudents = @$checkbox_emailstudents.is(':checked')
|
||||
|
||||
# attach click handler for enrollment buttons
|
||||
@$enrollment_button.click =>
|
||||
emailStudents: @$checkbox_emailstudents.is(':checked')
|
||||
send_data =
|
||||
action: 'enroll'
|
||||
action: $(event.target).data('action') # 'enroll' or 'unenroll'
|
||||
emails: @$emails_input.val()
|
||||
auto_enroll: @$checkbox_autoenroll.is(':checked')
|
||||
email_students: emailStudents
|
||||
|
||||
$.ajax
|
||||
dataType: 'json'
|
||||
url: @$btn_enroll.data 'endpoint'
|
||||
data: send_data
|
||||
success: (data) => @display_response data
|
||||
error: std_ajax_err => @fail_with_error "Error enrolling/unenrolling students."
|
||||
|
||||
@$btn_unenroll.click =>
|
||||
emailStudents = @$checkbox_emailstudents.is(':checked')
|
||||
|
||||
send_data =
|
||||
action: 'unenroll'
|
||||
emails: @$emails_input.val()
|
||||
auto_enroll: @$checkbox_autoenroll.is(':checked')
|
||||
email_students: emailStudents
|
||||
|
||||
$.ajax
|
||||
dataType: 'json'
|
||||
url: @$btn_unenroll.data 'endpoint'
|
||||
url: $(event.target).data 'endpoint'
|
||||
data: send_data
|
||||
success: (data) => @display_response data
|
||||
error: std_ajax_err => @fail_with_error gettext "Error enrolling/unenrolling students."
|
||||
@@ -475,6 +515,9 @@ class Membership
|
||||
|
||||
# isolate # initialize BatchEnrollment subsection
|
||||
plantTimeout 0, => new BatchEnrollment @$section.find '.batch-enrollment'
|
||||
|
||||
# initialize BetaTesterBulkAddition subsection
|
||||
plantTimeout 0, => new BetaTesterBulkAddition @$section.find '.batch-beta-testers'
|
||||
|
||||
# gather elements
|
||||
@$list_selector = @$section.find 'select#member-lists-selector'
|
||||
|
||||
@@ -292,7 +292,7 @@ section.instructor-dashboard-content-2 {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.batch-enrollment {
|
||||
.batch-enrollment, .batch-beta-testers {
|
||||
textarea {
|
||||
margin-top: 0.2em;
|
||||
height: auto;
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<div class="vert-left batch-enrollment">
|
||||
<div class="vert-left">
|
||||
<div class="batch-enrollment">
|
||||
<h2> ${_("Batch Enrollment")} </h2>
|
||||
<p>
|
||||
<label for="student-emails">${_("Enter student emails separated by new lines or commas.")} </label>
|
||||
@@ -51,15 +52,41 @@
|
||||
<p> ${_("If email students is <em>checked</em> students will receive an email notification.")}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input type="button" name="enrollment-button" class="enrollment-button" value="${_("Enroll")}" data-endpoint="${ section_data['enroll_button_url'] }" data-action="enroll" >
|
||||
<input type="button" name="enrollment-button" class="enrollment-button" value="${_("Unenroll")}" data-endpoint="${ section_data['unenroll_button_url'] }" data-action="unenroll" >
|
||||
</div>
|
||||
<div class="request-response"></div>
|
||||
<div class="request-response-error"></div>
|
||||
</div>
|
||||
|
||||
<div class="enroll-actions actions">
|
||||
<input type="button" name="enroll" value="${_("Enroll")}" data-endpoint="${ section_data['enroll_button_url'] }" >
|
||||
<input type="button" name="unenroll" value="${_("Unenroll")}" data-endpoint="${ section_data['unenroll_button_url'] }" >
|
||||
%if section_data['access']['instructor']:
|
||||
<div class="batch-beta-testers">
|
||||
<h2> ${_("Add Beta Testers")} </h2>
|
||||
<p> ${_("Enter student emails separated by new lines or commas.")} </p>
|
||||
<textarea rows="6" cols="50" name="student-emails-for-beta" placeholder="${_("Student Emails")}" spellcheck="false"></textarea>
|
||||
<br>
|
||||
|
||||
<div>
|
||||
<input type="checkbox" name="email-students" value="Notify-students-by-email">
|
||||
<label for="email-students">${_("Notify students by email")}</label>
|
||||
<div class="email-students-hint">
|
||||
<p> ${_("If email students is <em>checked</em> students will receive an email notification.")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input type="button" name="beta-testers" class="" value="${_("Add students as beta testers")}" data-endpoint="${ section_data['modify_beta_testers_button_url'] }" data-action="add" >
|
||||
<input type="button" name="beta-testers" class="" value="${_("Remove students as beta testers")}" data-endpoint="${ section_data['modify_beta_testers_button_url'] }" data-action="remove" >
|
||||
</div>
|
||||
|
||||
<div class="request-response"></div>
|
||||
<div class="request-response-error"></div>
|
||||
</div>
|
||||
%endif
|
||||
</div>
|
||||
|
||||
<div class="vert-right member-lists-management">
|
||||
<h2> ${_("Administration List Management")} </h2>
|
||||
|
||||
Reference in New Issue
Block a user