cleanup
- rename list copy - add beta list - fix forum and admin API's to be more similar - add auto-enroll checkbox - fix list reload - remove extra js logging - add course errors visibility toggle - add underscore.js check
This commit is contained in:
@@ -18,7 +18,16 @@ from django_comment_common.models import (Role,
|
||||
|
||||
|
||||
def list_with_level(course, level):
|
||||
grpname = get_access_group_name(course, level)
|
||||
"""
|
||||
List users who have 'level' access.
|
||||
|
||||
level is in ['instructor', 'staff', 'beta']
|
||||
"""
|
||||
if level in ['beta']:
|
||||
grpname = course_beta_test_group_name(course.location)
|
||||
else:
|
||||
grpname = get_access_group_name(course, level)
|
||||
|
||||
try:
|
||||
return Group.objects.get(name=grpname).user_set.all()
|
||||
except Group.DoesNotExist:
|
||||
@@ -52,7 +61,7 @@ def _change_access(course, user, level, mode):
|
||||
"""
|
||||
|
||||
if level in ['beta']:
|
||||
grpname = course_beta_test_group_name(course)
|
||||
grpname = course_beta_test_group_name(course.location)
|
||||
else:
|
||||
grpname = get_access_group_name(course, level)
|
||||
group, _ = Group.objects.get_or_create(name=grpname)
|
||||
|
||||
@@ -31,22 +31,33 @@ import analytics.csvs
|
||||
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
def enroll_unenroll(request, course_id):
|
||||
def students_update_enrollment_email(request, course_id):
|
||||
"""
|
||||
Enroll or unenroll students by email.
|
||||
Requires staff access.
|
||||
|
||||
Query Parameters:
|
||||
- action in ['enroll', 'unenroll']
|
||||
- emails is string containing a list of emails separated by anything split_input_list can handle.
|
||||
- auto_enroll is a boolean (defaults to false)
|
||||
"""
|
||||
course = get_course_with_access(request.user, course_id, 'staff', depth=None)
|
||||
|
||||
emails_to_enroll = split_input_list(request.GET.get('enroll', ''))
|
||||
emails_to_unenroll = split_input_list(request.GET.get('unenroll', ''))
|
||||
action = request.GET.get('action', '')
|
||||
emails = split_input_list(request.GET.get('emails', ''))
|
||||
auto_enroll = request.GET.get('auto_enroll', '') in ['true', 'Talse', True]
|
||||
|
||||
enrolled_result = enroll_emails(course_id, emails_to_enroll)
|
||||
unenrolled_result = unenroll_emails(course_id, emails_to_unenroll)
|
||||
if action == 'enroll':
|
||||
results = enroll_emails(course_id, emails, auto_enroll=auto_enroll)
|
||||
elif action == 'unenroll':
|
||||
results = unenroll_emails(course_id, emails)
|
||||
else:
|
||||
raise ValueError("unrecognized action '{}'".format(action))
|
||||
|
||||
response_payload = {
|
||||
'enrolled': enrolled_result,
|
||||
'unenrolled': unenrolled_result,
|
||||
'action': action,
|
||||
'results': results,
|
||||
'auto_enroll': auto_enroll,
|
||||
}
|
||||
response = HttpResponse(json.dumps(response_payload), content_type="application/json")
|
||||
return response
|
||||
|
||||
@@ -40,9 +40,15 @@ def instructor_dashboard_2(request, course_id):
|
||||
if not staff_access:
|
||||
raise Http404
|
||||
|
||||
access = {
|
||||
'instructor': instructor_access,
|
||||
'staff': staff_access,
|
||||
'forum_admin': forum_admin_access,
|
||||
}
|
||||
|
||||
sections = [
|
||||
_section_course_info(course_id),
|
||||
_section_membership(course_id),
|
||||
_section_membership(course_id, access),
|
||||
_section_student_admin(course_id),
|
||||
_section_data_download(course_id),
|
||||
_section_analytics(course_id),
|
||||
@@ -100,13 +106,16 @@ def _section_course_info(course_id):
|
||||
return section_data
|
||||
|
||||
|
||||
def _section_membership(course_id):
|
||||
def _section_membership(course_id, access):
|
||||
""" Provide data for the corresponding dashboard section """
|
||||
section_data = {
|
||||
'section_key': 'membership',
|
||||
'section_display_name': 'Membership',
|
||||
'enroll_button_url': reverse('enroll_unenroll', kwargs={'course_id': course_id}),
|
||||
'unenroll_button_url': reverse('enroll_unenroll', kwargs={'course_id': course_id}),
|
||||
|
||||
'access': access,
|
||||
|
||||
'enroll_button_url': reverse('students_update_enrollment_email', kwargs={'course_id': course_id}),
|
||||
'unenroll_button_url': reverse('students_update_enrollment_email', kwargs={'course_id': course_id}),
|
||||
'list_course_role_members_url': reverse('list_course_role_members', kwargs={'course_id': course_id}),
|
||||
'access_allow_revoke_url': reverse('access_allow_revoke', kwargs={'course_id': course_id}),
|
||||
'list_forum_members_url': reverse('list_forum_members', kwargs={'course_id': course_id}),
|
||||
@@ -121,7 +130,7 @@ def _section_student_admin(course_id):
|
||||
'section_key': 'student_admin',
|
||||
'section_display_name': 'Student Admin',
|
||||
'get_student_progress_url': reverse('get_student_progress_url', kwargs={'course_id': course_id}),
|
||||
'unenroll_button_url': reverse('enroll_unenroll', kwargs={'course_id': course_id}),
|
||||
'unenroll_button_url': reverse('students_update_enrollment_email', kwargs={'course_id': course_id}),
|
||||
'reset_student_attempts_url': reverse('reset_student_attempts', kwargs={'course_id': course_id}),
|
||||
}
|
||||
return section_data
|
||||
|
||||
@@ -23,7 +23,7 @@ class Analytics
|
||||
|
||||
populate_selector: (cb) ->
|
||||
@get_profile_distributions [], (data) =>
|
||||
@$distribution_select.find('option').eq(0).text "-- Select distribution"
|
||||
@$distribution_select.find('option').eq(0).text "-- Select Distribution --"
|
||||
|
||||
for feature in data.available_features
|
||||
opt = $ '<option/>',
|
||||
@@ -107,7 +107,8 @@ class Analytics
|
||||
|
||||
|
||||
# exports
|
||||
_.defaults window, InstructorDashboard: {}
|
||||
_.defaults window.InstructorDashboard, sections: {}
|
||||
_.defaults window.InstructorDashboard.sections,
|
||||
Analytics: Analytics
|
||||
if _?
|
||||
_.defaults window, InstructorDashboard: {}
|
||||
_.defaults window.InstructorDashboard, sections: {}
|
||||
_.defaults window.InstructorDashboard.sections,
|
||||
Analytics: Analytics
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
log = -> console.log.apply console, arguments
|
||||
plantTimeout = (ms, cb) -> setTimeout cb, ms
|
||||
|
||||
class CourseInfo
|
||||
constructor: (@$section) ->
|
||||
log "setting up instructor dashboard section - course info"
|
||||
@$section.data 'wrapper', @
|
||||
|
||||
@$course_errors_wrapper = @$section.find '.course-errors-wrapper'
|
||||
|
||||
if @$course_errors_wrapper.length
|
||||
@$course_error_toggle = @$course_errors_wrapper.find('h2').eq(0)
|
||||
@$course_error_visibility_wrapper = @$course_errors_wrapper.find '.course-errors-visibility-wrapper'
|
||||
@$course_errors = @$course_errors_wrapper.find('.course-error')
|
||||
|
||||
@$course_error_toggle.text @$course_error_toggle.text() + " (#{@$course_errors.length})"
|
||||
|
||||
@$course_error_toggle.click (e) =>
|
||||
e.preventDefault()
|
||||
@$course_error_visibility_wrapper.toggle()
|
||||
|
||||
|
||||
# exports
|
||||
if _?
|
||||
_.defaults window, InstructorDashboard: {}
|
||||
_.defaults window.InstructorDashboard, sections: {}
|
||||
_.defaults window.InstructorDashboard.sections,
|
||||
CourseInfo: CourseInfo
|
||||
@@ -48,7 +48,8 @@ class DataDownload
|
||||
|
||||
|
||||
# exports
|
||||
_.defaults window, InstructorDashboard: {}
|
||||
_.defaults window.InstructorDashboard, sections: {}
|
||||
_.defaults window.InstructorDashboard.sections,
|
||||
DataDownload: DataDownload
|
||||
if _?
|
||||
_.defaults window, InstructorDashboard: {}
|
||||
_.defaults window.InstructorDashboard, sections: {}
|
||||
_.defaults window.InstructorDashboard.sections,
|
||||
DataDownload: DataDownload
|
||||
|
||||
@@ -26,6 +26,7 @@ setup_instructor_dashboard = (idash_content) =>
|
||||
# setup section header click handlers
|
||||
for link in ($ link for link in links)
|
||||
link.click (e) ->
|
||||
e.preventDefault()
|
||||
# deactivate (styling) all sections
|
||||
idash_content.find(".#{CSS_IDASH_SECTION}").removeClass CSS_ACTIVE_SECTION
|
||||
idash_content.find(".#{CSS_INSTRUCTOR_NAV}").children().removeClass CSS_ACTIVE_SECTION
|
||||
@@ -34,8 +35,6 @@ setup_instructor_dashboard = (idash_content) =>
|
||||
section_name = $(this).data 'section'
|
||||
section = idash_content.find "##{section_name}"
|
||||
|
||||
section.data('wrapper')?.onClickTitle?()
|
||||
|
||||
# activate (styling) active
|
||||
section.addClass CSS_ACTIVE_SECTION
|
||||
$(this).addClass CSS_ACTIVE_SECTION
|
||||
@@ -43,8 +42,7 @@ setup_instructor_dashboard = (idash_content) =>
|
||||
# write deep link
|
||||
location.hash = "#{HASH_LINK_PREFIX}#{section_name}"
|
||||
|
||||
log "clicked #{section_name}"
|
||||
e.preventDefault()
|
||||
plantTimeout 0, -> section.data('wrapper')?.onClickTitle?()
|
||||
|
||||
# recover deep link from url
|
||||
# click default or go to section specified by hash
|
||||
@@ -62,6 +60,7 @@ setup_instructor_dashboard_sections = (idash_content) ->
|
||||
log "setting up instructor dashboard sections"
|
||||
# fault isolation
|
||||
# an error thrown in one section will not block other sections from exectuing
|
||||
plantTimeout 0, -> new window.InstructorDashboard.sections.CourseInfo idash_content.find ".#{CSS_IDASH_SECTION}#course_info"
|
||||
plantTimeout 0, -> new window.InstructorDashboard.sections.DataDownload idash_content.find ".#{CSS_IDASH_SECTION}#data_download"
|
||||
plantTimeout 0, -> new window.InstructorDashboard.sections.Membership idash_content.find ".#{CSS_IDASH_SECTION}#membership"
|
||||
plantTimeout 0, -> new window.InstructorDashboard.sections.StudentAdmin idash_content.find ".#{CSS_IDASH_SECTION}#student_admin"
|
||||
|
||||
@@ -9,6 +9,8 @@ class BatchEnrollment
|
||||
$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']'")
|
||||
window.autoenroll = $checkbox_autoenroll
|
||||
$task_response = @$container.find(".task-response")
|
||||
|
||||
$emails_input.click -> log 'click $emails_input'
|
||||
@@ -16,20 +18,27 @@ class BatchEnrollment
|
||||
$btn_unenroll.click -> log 'click $btn_unenroll'
|
||||
|
||||
$btn_enroll.click ->
|
||||
$.getJSON $btn_enroll.data('endpoint'), enroll: $emails_input.val() , (data) ->
|
||||
send_data =
|
||||
action: 'enroll'
|
||||
emails: $emails_input.val()
|
||||
auto_enroll: $checkbox_autoenroll.is(':checked')
|
||||
$.getJSON $btn_enroll.data('endpoint'), send_data, (data) ->
|
||||
log 'received response for enroll button', data
|
||||
display_response(data)
|
||||
|
||||
$btn_unenroll.click ->
|
||||
log 'VAL', $emails_input.val()
|
||||
$.getJSON $btn_unenroll.data('endpoint'), unenroll: $emails_input.val() , (data) ->
|
||||
# log 'received response for unenroll button', data
|
||||
# display_response(data)
|
||||
send_data =
|
||||
action: 'unenroll'
|
||||
emails: $emails_input.val()
|
||||
auto_enroll: $checkbox_autoenroll.is(':checked')
|
||||
$.getJSON $btn_unenroll.data('endpoint'), send_data, (data) ->
|
||||
log 'received response for unenroll button', data
|
||||
display_response(data)
|
||||
|
||||
display_response = (data_from_server) ->
|
||||
$task_response.empty()
|
||||
|
||||
response_code_dict = _.extend {}, data_from_server.enrolled, data_from_server.unenrolled
|
||||
response_code_dict = _.extend {}, data_from_server.results
|
||||
# response_code_dict e.g. {'code': ['email1', 'email2'], ...}
|
||||
message_ordering = [
|
||||
'msg_error_enroll'
|
||||
@@ -77,13 +86,10 @@ class BatchEnrollment
|
||||
will_attach = false
|
||||
|
||||
for code in msg_to_codes[msg_symbol]
|
||||
log 'logging code', code
|
||||
emails = response_code_dict[code]
|
||||
log 'emails', emails
|
||||
|
||||
if emails and emails.length
|
||||
for email in emails
|
||||
log 'logging email', email
|
||||
email_list.append $ '<li/>', text: email
|
||||
will_attach = true
|
||||
|
||||
@@ -114,7 +120,6 @@ class AuthList
|
||||
reload_auth_list: =>
|
||||
list_endpoint = @$display_table.data 'endpoint'
|
||||
$.getJSON list_endpoint, {rolename: @rolename}, (data) =>
|
||||
log data
|
||||
|
||||
@$display_table.empty()
|
||||
|
||||
@@ -139,11 +144,9 @@ class AuthList
|
||||
]
|
||||
|
||||
table_data = data[@rolename]
|
||||
log 'table_data', table_data
|
||||
|
||||
$table_placeholder = $ '<div/>', class: 'slickgrid'
|
||||
@$display_table.append $table_placeholder
|
||||
log '@$display_table', $table_placeholder
|
||||
grid = new Slick.Grid($table_placeholder, table_data, columns, options)
|
||||
grid.autosizeColumns()
|
||||
|
||||
@@ -152,11 +155,16 @@ class AuthList
|
||||
if args.cell is 2
|
||||
@access_change(item.email, @rolename, 'revoke', @reload_auth_list)
|
||||
|
||||
# slickgrid collapses when rendered in an invisible div
|
||||
# use this method to reload the widget
|
||||
refresh: ->
|
||||
@$display_table.empty()
|
||||
@reload_auth_list()
|
||||
|
||||
access_change: (email, rolename, mode, cb) ->
|
||||
access_change_endpoint = @$add_section.data 'endpoint'
|
||||
$.getJSON access_change_endpoint, {email: email, rolename: @rolename, mode: mode}, (data) ->
|
||||
log data
|
||||
cb?()
|
||||
cb?(data)
|
||||
|
||||
|
||||
class Membership
|
||||
@@ -164,36 +172,41 @@ class Membership
|
||||
log "setting up instructor dashboard section - membership"
|
||||
@$section.data 'wrapper', @
|
||||
|
||||
# isolate sections from each other's errors.
|
||||
plantTimeout 0, => @batchenrollment = new BatchEnrollment @$section.find '.batch-enrollment'
|
||||
plantTimeout 0, => @stafflist = new AuthList (@$section.find '.auth-list-container.auth-list-staff'), 'staff'
|
||||
plantTimeout 0, => @instructorlist = new AuthList (@$section.find '.auth-list-container.auth-list-instructor'), 'instructor'
|
||||
@$list_selector = @$section.find('select#member-lists-selector')
|
||||
|
||||
plantTimeout 0, => @batchenrollment = new BatchEnrollment @$section.find '.batch-enrollment'
|
||||
|
||||
@auth_lists = _.map (@$section.find '.auth-list-container'), (auth_list_container) ->
|
||||
rolename = $(auth_list_container).data 'rolename'
|
||||
new AuthList $(auth_list_container), rolename
|
||||
|
||||
# populate selector
|
||||
@$list_selector.empty()
|
||||
for auth_list in @auth_lists
|
||||
@$list_selector.append $ '<option/>',
|
||||
text: auth_list.$container.data 'display-name'
|
||||
data:
|
||||
auth_list: auth_list
|
||||
|
||||
@$list_selector.change =>
|
||||
$opt = @$list_selector.children('option:selected')
|
||||
for auth_list in @auth_lists
|
||||
auth_list.$container.removeClass 'active'
|
||||
auth_list = $opt.data('auth_list')
|
||||
auth_list.refresh()
|
||||
auth_list.$container.addClass 'active'
|
||||
|
||||
@$list_selector.change()
|
||||
|
||||
# TODO names like 'Administrator' should come from server through template.
|
||||
plantTimeout 0, => @forum_admin_list = new AuthList (@$section.find '.auth-list-container.auth-list-forum-admin'), 'Administrator'
|
||||
plantTimeout 0, => @forum_mod_list = new AuthList (@$section.find '.auth-list-container.auth-list-forum-moderator'), 'Moderator'
|
||||
plantTimeout 0, => @forum_comta_list = new AuthList (@$section.find '.auth-list-container.auth-list-forum-community-ta'), 'Community TA'
|
||||
|
||||
onClickTitle: ->
|
||||
@stafflist.$display_table.empty()
|
||||
@stafflist.reload_auth_list()
|
||||
|
||||
@instructorlist.$display_table.empty()
|
||||
@instructorlist.reload_auth_list()
|
||||
|
||||
@forum_admin_list.$display_table.empty()
|
||||
@forum_admin_list.reload_auth_list()
|
||||
|
||||
@forum_mod_list.$display_table.empty()
|
||||
@forum_mod_list.reload_auth_list()
|
||||
|
||||
@forum_comta_list.$display_table.empty()
|
||||
@forum_comta_list.reload_auth_list()
|
||||
|
||||
for auth_list in @auth_lists
|
||||
auth_list.refresh()
|
||||
|
||||
|
||||
# exports
|
||||
_.defaults window, InstructorDashboard: {}
|
||||
_.defaults window.InstructorDashboard, sections: {}
|
||||
_.defaults window.InstructorDashboard.sections,
|
||||
Membership: Membership
|
||||
if _?
|
||||
_.defaults window, InstructorDashboard: {}
|
||||
_.defaults window.InstructorDashboard, sections: {}
|
||||
_.defaults window.InstructorDashboard.sections,
|
||||
Membership: Membership
|
||||
|
||||
@@ -24,8 +24,12 @@ class StudentAdmin
|
||||
console.warn 'error getting student progress url for ' + email
|
||||
|
||||
@$unenroll_btn.click =>
|
||||
$.getJSON @$unenroll_btn.data('endpoint'), unenroll: @$student_email_field.val(), (data) ->
|
||||
log 'data'
|
||||
send_data =
|
||||
action: 'unenroll'
|
||||
emails: @$student_email_field.val()
|
||||
auto_enroll: false
|
||||
$.getJSON @$unenroll_btn.data('endpoint'), send_data, (data) ->
|
||||
log data
|
||||
|
||||
@$reset_attempts_btn.click =>
|
||||
email = @$student_email_field.val()
|
||||
@@ -77,7 +81,8 @@ class StudentAdmin
|
||||
|
||||
|
||||
# exports
|
||||
_.defaults window, InstructorDashboard: {}
|
||||
_.defaults window.InstructorDashboard, sections: {}
|
||||
_.defaults window.InstructorDashboard.sections,
|
||||
StudentAdmin: StudentAdmin
|
||||
if _?
|
||||
_.defaults window, InstructorDashboard: {}
|
||||
_.defaults window.InstructorDashboard, sections: {}
|
||||
_.defaults window.InstructorDashboard.sections,
|
||||
StudentAdmin: StudentAdmin
|
||||
|
||||
@@ -63,19 +63,28 @@
|
||||
|
||||
|
||||
.instructor-dashboard-wrapper-2 section.idash-section#course_info {
|
||||
.error-log {
|
||||
margin-top: 1em;
|
||||
.course-errors-wrapper {
|
||||
margin-top: 2em;
|
||||
|
||||
.course-error {
|
||||
margin-bottom: 1em;
|
||||
h2 {
|
||||
color: #D60000;
|
||||
}
|
||||
|
||||
code {
|
||||
&.course-error-first {
|
||||
color: #111;
|
||||
}
|
||||
.course-errors-visibility-wrapper {
|
||||
display: none;
|
||||
|
||||
&.course-error-second {
|
||||
color: black;
|
||||
.course-error {
|
||||
margin-bottom: 1em;
|
||||
margin-left: 0.5em;
|
||||
|
||||
code {
|
||||
&.course-error-first {
|
||||
color: #111;
|
||||
}
|
||||
|
||||
&.course-error-second {
|
||||
color: #111;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,17 +95,26 @@
|
||||
.instructor-dashboard-wrapper-2 section.idash-section#membership {
|
||||
.vert-left {
|
||||
float: left;
|
||||
width: 45%;
|
||||
width: 47%;
|
||||
}
|
||||
|
||||
.vert-right {
|
||||
float: right;
|
||||
width: 45%;
|
||||
width: 47%;
|
||||
}
|
||||
|
||||
select {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.auth-list-container {
|
||||
display: none;
|
||||
margin-bottom: 1.5em;
|
||||
|
||||
&.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.auth-list-table {
|
||||
.slickgrid {
|
||||
height: 250px;
|
||||
@@ -110,6 +128,9 @@
|
||||
|
||||
.batch-enrollment {
|
||||
textarea {
|
||||
margin-top: 0.2em;
|
||||
margin-bottom: 1em;
|
||||
|
||||
height: 100px;
|
||||
width: 500px;
|
||||
}
|
||||
@@ -146,6 +167,7 @@
|
||||
input {
|
||||
// display: block;
|
||||
margin-bottom: 1em;
|
||||
line-height: 1.3em;
|
||||
}
|
||||
|
||||
.data-display {
|
||||
|
||||
@@ -37,14 +37,16 @@
|
||||
${ section_data['offline_grades'] }
|
||||
</div>
|
||||
|
||||
<div class="error-log">
|
||||
%if len(section_data['course_errors']):
|
||||
<h2>Course Errors:</h2>
|
||||
%for error in section_data['course_errors']:
|
||||
<div class="course-error">
|
||||
<code class=course-error-first> ${ error[0] } </code><br>
|
||||
<code class=course-error-second> ${ error[1] } </code>
|
||||
</div>
|
||||
%endfor
|
||||
%endif
|
||||
</div>
|
||||
%if len(section_data['course_errors']):
|
||||
<div class="course-errors-wrapper">
|
||||
<a href=""><h2 class="title">Course Warnings:</h2></a>
|
||||
<div class="course-errors-visibility-wrapper">
|
||||
%for error in section_data['course_errors']:
|
||||
<div class="course-error">
|
||||
<code class=course-error-first> ${ error[0] } </code><br>
|
||||
<code class=course-error-second> ${ error[1] } </code>
|
||||
</div>
|
||||
%endfor
|
||||
</div>
|
||||
</div>
|
||||
%endif
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
<%page args="section_data"/>
|
||||
|
||||
<input type="button" name="list-profiles" value="List enrolled students with profile information" data-endpoint="${ section_data['enrolled_students_profiles_url'] }" >
|
||||
<input type="button" name="list-profiles" value="[CSV]" data-csv="true" data-endpoint="${ section_data['enrolled_students_profiles_url'] }" >
|
||||
<input type="button" name="list-profiles" value="CSV" data-csv="true" class="csv" data-endpoint="${ section_data['enrolled_students_profiles_url'] }" >
|
||||
<br>
|
||||
<input type="button" name="list-grades" value="Student grades">
|
||||
<br>
|
||||
<input type="button" name="list-answer-distributions" value="Answer distributions (x students got y points)">
|
||||
<br>
|
||||
<input type="button" name="dump-gradeconf" value="Grading Configuration" data-endpoint="${ section_data['grading_config_url'] }">
|
||||
|
||||
<div class="data-display">
|
||||
<div class="data-display-text"></div>
|
||||
<div class="data-display-table"></div>
|
||||
|
||||
@@ -7,52 +7,68 @@
|
||||
<br>
|
||||
<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'] }" >
|
||||
<input type="checkbox" name="auto-enroll" value="Auto-Enroll">
|
||||
<label for="auto-enroll">Auto Enroll</label>
|
||||
<div class="task-response"></div>
|
||||
|
||||
<div class="auth-list-container auth-list-forum-admin">
|
||||
<h2>Instructor Management</h2>
|
||||
<div class="auth-list-table" data-endpoint="${ section_data['list_forum_members_url'] }"></div>
|
||||
<div class="auth-list-add" data-endpoint="${ section_data['update_forum_role_membership_url'] }">
|
||||
<input type="text" name="email" placeholder="Enter Email" spellcheck="false">
|
||||
<input type="button" name="allow" value="Grant Forum Admin">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="auth-list-container auth-list-forum-moderator">
|
||||
<h2>Instructor Management</h2>
|
||||
<div class="auth-list-table" data-endpoint="${ section_data['list_forum_members_url'] }"></div>
|
||||
<div class="auth-list-add" data-endpoint="${ section_data['update_forum_role_membership_url'] }">
|
||||
<input type="text" name="email" placeholder="Enter Email" spellcheck="false">
|
||||
<input type="button" name="allow" value="Grant Forum Moderator">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="auth-list-container auth-list-forum-community-ta">
|
||||
<h2>Instructor Management</h2>
|
||||
<div class="auth-list-table" data-endpoint="${ section_data['list_forum_members_url'] }"></div>
|
||||
<div class="auth-list-add" data-endpoint="${ section_data['update_forum_role_membership_url'] }">
|
||||
<input type="text" name="email" placeholder="Enter Email" spellcheck="false">
|
||||
<input type="button" name="allow" value="Grant Community TA">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="vert-right instructor-staff-management">
|
||||
<div class="auth-list-container auth-list-staff">
|
||||
<h2>Staff Management</h2>
|
||||
<div class="auth-list-table" data-endpoint="${ section_data['list_instructors_staff_url'] }"></div>
|
||||
<div class="vert-right member-lists-management">
|
||||
<h2> Member List Management </h2>
|
||||
|
||||
<select id="member-lists-selector">
|
||||
<option> Getting available lists... </option>
|
||||
</select>
|
||||
|
||||
<div class="auth-list-container" data-rolename="staff" data-display-name="Staff">
|
||||
<div class="auth-list-table" data-endpoint="${ section_data['list_course_role_members_url'] }"></div>
|
||||
<div class="auth-list-add" data-endpoint="${ section_data['access_allow_revoke_url'] }">
|
||||
<input type="text" name="email" placeholder="Enter Email" spellcheck="false">
|
||||
<input type="button" name="allow" value="Grant Staff Access">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="auth-list-container auth-list-instructor">
|
||||
<h2>Instructor Management</h2>
|
||||
<div class="auth-list-table" data-endpoint="${ section_data['list_instructors_staff_url'] }"></div>
|
||||
%if section_data['access']['instructor']:
|
||||
<div class="auth-list-container" data-rolename="instructor" data-display-name="Instructors">
|
||||
<div class="auth-list-table" data-endpoint="${ section_data['list_course_role_members_url'] }"></div>
|
||||
<div class="auth-list-add" data-endpoint="${ section_data['access_allow_revoke_url'] }">
|
||||
<input type="text" name="email" placeholder="Enter Email" spellcheck="false">
|
||||
<input type="button" name="allow" value="Grant Instructor Access">
|
||||
</div>
|
||||
</div>
|
||||
%endif
|
||||
|
||||
<div class="auth-list-container" data-rolename="beta" data-display-name="Beta Testers">
|
||||
<div class="auth-list-table" data-endpoint="${ section_data['list_course_role_members_url'] }"></div>
|
||||
<div class="auth-list-add" data-endpoint="${ section_data['access_allow_revoke_url'] }">
|
||||
<input type="text" name="email" placeholder="Enter Email" spellcheck="false">
|
||||
<input type="button" name="allow" value="Grant Instructor Access">
|
||||
<input type="button" name="allow" value="Grant Beta Tester Access">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
%if section_data['access']['forum_admin']:
|
||||
<div class="auth-list-container" data-rolename="Administrator" data-display-name="Forum Admins">
|
||||
<div class="auth-list-table" data-endpoint="${ section_data['list_forum_members_url'] }"></div>
|
||||
<div class="auth-list-add" data-endpoint="${ section_data['update_forum_role_membership_url'] }">
|
||||
<input type="text" name="email" placeholder="Enter Email" spellcheck="false">
|
||||
<input type="button" name="allow" value="Grant Forum Admin">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="auth-list-container" data-rolename="Moderator" data-display-name="Forum Moderators">
|
||||
<div class="auth-list-table" data-endpoint="${ section_data['list_forum_members_url'] }"></div>
|
||||
<div class="auth-list-add" data-endpoint="${ section_data['update_forum_role_membership_url'] }">
|
||||
<input type="text" name="email" placeholder="Enter Email" spellcheck="false">
|
||||
<input type="button" name="allow" value="Grant Forum Moderator">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="auth-list-container" data-rolename="Community TA" data-display-name="Forum Community TAs">
|
||||
<div class="auth-list-table" data-endpoint="${ section_data['list_forum_members_url'] }"></div>
|
||||
<div class="auth-list-add" data-endpoint="${ section_data['update_forum_role_membership_url'] }">
|
||||
<input type="text" name="email" placeholder="Enter Email" spellcheck="false">
|
||||
<input type="button" name="allow" value="Grant Community TA">
|
||||
</div>
|
||||
</div>
|
||||
%endif
|
||||
|
||||
</div>
|
||||
|
||||
@@ -255,8 +255,8 @@ if settings.COURSEWARE_ENABLED:
|
||||
'instructor.views.instructor_dashboard.instructor_dashboard_2', name="instructor_dashboard_2"),
|
||||
|
||||
# api endpoints for instructor
|
||||
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/instructor_dashboard/api/enroll_unenroll$',
|
||||
'instructor.views.api.enroll_unenroll', name="enroll_unenroll"),
|
||||
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/instructor_dashboard/api/students_update_enrollment_email$',
|
||||
'instructor.views.api.students_update_enrollment_email', name="students_update_enrollment_email"),
|
||||
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/instructor_dashboard/api/list_course_role_members$',
|
||||
'instructor.views.api.list_course_role_members', name="list_course_role_members"),
|
||||
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/instructor_dashboard/api/access_allow_revoke$',
|
||||
|
||||
Reference in New Issue
Block a user