From 9330ef65a8957626edfdd858f3be88a2838dc287 Mon Sep 17 00:00:00 2001
From: Sarina Canelake
Date: Tue, 15 Oct 2013 11:31:27 -0400
Subject: [PATCH 1/4] Enable Pending Tasks section on new dash
Add Pending Tasks section to the following tabs:
* Course Info
* Student Email
* Data Download
* Email
LMS-1242
---
.../instructor/views/instructor_dashboard.py | 14 ++--
lms/envs/dev.py | 3 +-
.../instructor_dashboard/course_info.coffee | 29 +++++++-
.../instructor_dashboard/data_download.coffee | 26 ++++++-
.../instructor_dashboard/send_email.coffee | 26 +++++++
.../instructor_dashboard/student_admin.coffee | 69 ++++---------------
.../src/instructor_dashboard/util.coffee | 49 +++++++++++++
.../instructor_dashboard_2/course_info.html | 1 +
.../instructor_dashboard_2/data_download.html | 12 ++++
.../instructor_dashboard_2/send_email.html | 12 ++++
.../instructor_dashboard_2/student_admin.html | 12 ++++
11 files changed, 186 insertions(+), 67 deletions(-)
diff --git a/lms/djangoapps/instructor/views/instructor_dashboard.py b/lms/djangoapps/instructor/views/instructor_dashboard.py
index e579593a88a2..c48efa91f9e7 100644
--- a/lms/djangoapps/instructor/views/instructor_dashboard.py
+++ b/lms/djangoapps/instructor/views/instructor_dashboard.py
@@ -52,17 +52,17 @@ def instructor_dashboard_2(request, course_id):
_section_analytics(course_id),
]
+ # Gate access to course email by feature flag & by course-specific authorization
+ if settings.MITX_FEATURES['ENABLE_INSTRUCTOR_EMAIL'] and \
+ is_studio_course and CourseAuthorization.instructor_email_enabled(course_id):
+ sections.append(_section_send_email(course_id, access, course))
+
enrollment_count = sections[0]['enrollment_count']
disable_buttons = False
max_enrollment_for_buttons = settings.MITX_FEATURES.get("MAX_ENROLLMENT_INSTR_BUTTONS")
if max_enrollment_for_buttons is not None:
disable_buttons = enrollment_count > max_enrollment_for_buttons
- # Gate access by feature flag & by course-specific authorization
- if settings.MITX_FEATURES['ENABLE_INSTRUCTOR_EMAIL'] and \
- is_studio_course and CourseAuthorization.instructor_email_enabled(course_id):
- sections.append(_section_send_email(course_id, access, course))
-
context = {
'course': course,
'old_dashboard_url': reverse('instructor_dashboard', kwargs={'course_id': course_id}),
@@ -156,6 +156,7 @@ def _section_data_download(course_id):
'get_grading_config_url': reverse('get_grading_config', kwargs={'course_id': course_id}),
'get_students_features_url': reverse('get_students_features', kwargs={'course_id': course_id}),
'get_anon_ids_url': reverse('get_anon_ids', kwargs={'course_id': course_id}),
+ 'list_instructor_tasks_url': reverse('list_instructor_tasks', kwargs={'course_id': course_id}),
}
return section_data
@@ -171,7 +172,8 @@ def _section_send_email(course_id, access, course):
'section_display_name': _('Email'),
'access': access,
'send_email': reverse('send_email', kwargs={'course_id': course_id}),
- 'editor': email_editor
+ 'editor': email_editor,
+ 'list_instructor_tasks_url': reverse('list_instructor_tasks', kwargs={'course_id': course_id}),
}
return section_data
diff --git a/lms/envs/dev.py b/lms/envs/dev.py
index e873861196dc..e1eadf1331de 100644
--- a/lms/envs/dev.py
+++ b/lms/envs/dev.py
@@ -29,7 +29,8 @@
MITX_FEATURES['ENABLE_PSYCHOMETRICS'] = False # real-time psychometrics (eg item response theory analysis in instructor dashboard)
MITX_FEATURES['ENABLE_INSTRUCTOR_ANALYTICS'] = True
MITX_FEATURES['ENABLE_SERVICE_STATUS'] = True
-MITX_FEATURES['ENABLE_INSTRUCTOR_EMAIL'] = True
+MITX_FEATURES['ENABLE_INSTRUCTOR_EMAIL'] = True # Enable email for all Studio courses
+MITX_FEATURES['REQUIRE_COURSE_EMAIL_AUTH'] = False # Give all courses email (don't require django-admin perms)
MITX_FEATURES['ENABLE_HINTER_INSTRUCTOR_VIEW'] = True
MITX_FEATURES['ENABLE_INSTRUCTOR_BETA_DASHBOARD'] = True
MITX_FEATURES['MULTIPLE_ENROLLMENT_ROLES'] = True
diff --git a/lms/static/coffee/src/instructor_dashboard/course_info.coffee b/lms/static/coffee/src/instructor_dashboard/course_info.coffee
index 19f9ce9707b2..beca8db71202 100644
--- a/lms/static/coffee/src/instructor_dashboard/course_info.coffee
+++ b/lms/static/coffee/src/instructor_dashboard/course_info.coffee
@@ -1,15 +1,17 @@
###
Course Info Section
-This is the implementation of the simplest section
-of the instructor dashboard.
imports from other modules.
wrap in (-> ... apply) to defer evaluation
such that the value can be defined later than this assignment (file load order).
###
+# Load utilities
plantTimeout = -> window.InstructorDashboard.util.plantTimeout.apply this, arguments
std_ajax_err = -> window.InstructorDashboard.util.std_ajax_err.apply this, arguments
+load_IntervalManager = -> window.InstructorDashboard.util.IntervalManager
+create_task_list_table = -> window.InstructorDashboard.util.create_task_list_table.apply this, arguments
+
# A typical section object.
# constructed with $section, a jquery object
@@ -37,6 +39,29 @@ class CourseInfo
else
@$course_errors_wrapper.addClass 'open'
+ ### Pending Instructor Tasks Section ####
+ # Currently running tasks
+ @$table_running_tasks = @$section.find ".running-tasks-table"
+
+ # start polling for task list
+ # if the list is in the DOM
+ if @$table_running_tasks.length > 0
+ # reload every 20 seconds.
+ TASK_LIST_POLL_INTERVAL = 20000
+ @reload_running_tasks_list()
+ @task_poller = new (load_IntervalManager()) TASK_LIST_POLL_INTERVAL, =>
+ @reload_running_tasks_list()
+
+ # Populate the running tasks list
+ reload_running_tasks_list: =>
+ list_endpoint = @$table_running_tasks.data 'endpoint'
+ $.ajax
+ dataType: 'json'
+ url: list_endpoint
+ success: (data) => create_task_list_table @$table_running_tasks, data.tasks
+ error: std_ajax_err => console.warn "error listing all instructor tasks"
+ ### /Pending Instructor Tasks Section ####
+
# export for use
# create parent namespaces if they do not already exist.
diff --git a/lms/static/coffee/src/instructor_dashboard/data_download.coffee b/lms/static/coffee/src/instructor_dashboard/data_download.coffee
index b5bbde918290..ffc24a574b13 100644
--- a/lms/static/coffee/src/instructor_dashboard/data_download.coffee
+++ b/lms/static/coffee/src/instructor_dashboard/data_download.coffee
@@ -8,7 +8,8 @@ such that the value can be defined later than this assignment (file load order).
plantTimeout = -> window.InstructorDashboard.util.plantTimeout.apply this, arguments
std_ajax_err = -> window.InstructorDashboard.util.std_ajax_err.apply this, arguments
-
+load_IntervalManager = -> window.InstructorDashboard.util.IntervalManager
+create_task_list_table = -> window.InstructorDashboard.util.create_task_list_table.apply this, arguments
# Data Download Section
class DataDownload
@@ -81,6 +82,29 @@ class DataDownload
@$display_text.html data['grading_config_summary']
+ ### Pending Instructor Tasks Section ####
+ # Currently running tasks
+ @$table_running_tasks = @$section.find ".running-tasks-table"
+
+ # start polling for task list
+ # if the list is in the DOM
+ if @$table_running_tasks.length > 0
+ # reload every 20 seconds.
+ TASK_LIST_POLL_INTERVAL = 20000
+ @reload_running_tasks_list()
+ @task_poller = new (load_IntervalManager()) TASK_LIST_POLL_INTERVAL, =>
+ @reload_running_tasks_list()
+
+ # Populate the running tasks list
+ reload_running_tasks_list: =>
+ list_endpoint = @$table_running_tasks.data 'endpoint'
+ $.ajax
+ dataType: 'json'
+ url: list_endpoint
+ success: (data) => create_task_list_table @$table_running_tasks, data.tasks
+ error: std_ajax_err => console.warn "error listing all instructor tasks"
+ ### /Pending Instructor Tasks Section ####
+
clear_display: ->
@$display_text.empty()
@$display_table.empty()
diff --git a/lms/static/coffee/src/instructor_dashboard/send_email.coffee b/lms/static/coffee/src/instructor_dashboard/send_email.coffee
index 7fc839cca6bf..27eea3d339b5 100644
--- a/lms/static/coffee/src/instructor_dashboard/send_email.coffee
+++ b/lms/static/coffee/src/instructor_dashboard/send_email.coffee
@@ -6,8 +6,11 @@ wrap in (-> ... apply) to defer evaluation
such that the value can be defined later than this assignment (file load order).
###
+# Load utilities
plantTimeout = -> window.InstructorDashboard.util.plantTimeout.apply this, arguments
std_ajax_err = -> window.InstructorDashboard.util.std_ajax_err.apply this, arguments
+load_IntervalManager = -> window.InstructorDashboard.util.IntervalManager
+create_task_list_table = -> window.InstructorDashboard.util.create_task_list_table.apply this, arguments
class SendEmail
constructor: (@$container) ->
@@ -87,6 +90,29 @@ class Email
# isolate # initialize SendEmail subsection
plantTimeout 0, => new SendEmail @$section.find '.send-email'
+ ### Pending Instructor Tasks Section ####
+ # Currently running tasks
+ @$table_running_tasks = @$section.find ".running-tasks-table"
+
+ # start polling for task list
+ # if the list is in the DOM
+ if @$table_running_tasks.length > 0
+ # reload every 20 seconds.
+ TASK_LIST_POLL_INTERVAL = 20000
+ @reload_running_tasks_list()
+ @task_poller = new (load_IntervalManager()) TASK_LIST_POLL_INTERVAL, =>
+ @reload_running_tasks_list()
+
+ # Populate the running tasks list
+ reload_running_tasks_list: =>
+ list_endpoint = @$table_running_tasks.data 'endpoint'
+ $.ajax
+ dataType: 'json'
+ url: list_endpoint
+ success: (data) => create_task_list_table @$table_running_tasks, data.tasks
+ error: std_ajax_err => console.warn "error listing all instructor tasks"
+ ### /Pending Instructor Tasks Section ####
+
# handler for when the section title is clicked.
onClickTitle: ->
diff --git a/lms/static/coffee/src/instructor_dashboard/student_admin.coffee b/lms/static/coffee/src/instructor_dashboard/student_admin.coffee
index c07069a49384..198c7e84a5d0 100644
--- a/lms/static/coffee/src/instructor_dashboard/student_admin.coffee
+++ b/lms/static/coffee/src/instructor_dashboard/student_admin.coffee
@@ -6,10 +6,12 @@ wrap in (-> ... apply) to defer evaluation
such that the value can be defined later than this assignment (file load order).
###
+# Load utilities
plantTimeout = -> window.InstructorDashboard.util.plantTimeout.apply this, arguments
plantInterval = -> window.InstructorDashboard.util.plantInterval.apply this, arguments
std_ajax_err = -> window.InstructorDashboard.util.std_ajax_err.apply this, arguments
load_IntervalManager = -> window.InstructorDashboard.util.IntervalManager
+create_task_list_table = -> window.InstructorDashboard.util.create_task_list_table.apply this, arguments
# get jquery element and assert its existance
@@ -21,54 +23,6 @@ find_and_assert = ($root, selector) ->
else
item
-# render a task list table to the DOM
-# `$table_tasks` the $element in which to put the table
-# `tasks_data`
-create_task_list_table = ($table_tasks, tasks_data) ->
- $table_tasks.empty()
-
- options =
- enableCellNavigation: true
- enableColumnReorder: false
- autoHeight: true
- rowHeight: 60
- forceFitColumns: true
-
- columns = [
- id: 'task_type'
- field: 'task_type'
- name: 'Task Type'
- ,
- id: 'requester'
- field: 'requester'
- name: 'Requester'
- width: 30
- ,
- id: 'task_input'
- field: 'task_input'
- name: 'Input'
- ,
- id: 'task_state'
- field: 'task_state'
- name: 'State'
- width: 30
- ,
- id: 'task_id'
- field: 'task_id'
- name: 'Task ID'
- width: 50
- ,
- id: 'created'
- field: 'created'
- name: 'Created'
- ]
-
- table_data = tasks_data
-
- $table_placeholder = $ '', class: 'slickgrid'
- $table_tasks.append $table_placeholder
- grid = new Slick.Grid($table_placeholder, table_data, columns, options)
-
class StudentAdmin
constructor: (@$section) ->
@@ -100,15 +54,6 @@ class StudentAdmin
@$request_response_error_grade = find_and_assert @$section, ".student-grade-container .request-response-error"
@$request_response_error_all = @$section.find ".course-specific-container .request-response-error"
- # start polling for task list
- # if the list is in the DOM
- if @$table_running_tasks.length > 0
- # reload every 20 seconds.
- TASK_LIST_POLL_INTERVAL = 20000
- @reload_running_tasks_list()
- @task_poller = new (load_IntervalManager()) TASK_LIST_POLL_INTERVAL, =>
- @reload_running_tasks_list()
-
# attach click handlers
# go to student progress page
@@ -294,6 +239,16 @@ class StudentAdmin
create_task_list_table @$table_task_history_all, data.tasks
error: std_ajax_err => @$request_response_error_all.text gettext("Error listing task history for this student and problem.")
+ # start polling for task list
+ # if the list is in the DOM
+ if @$table_running_tasks.length > 0
+ # reload every 20 seconds.
+ TASK_LIST_POLL_INTERVAL = 20000
+ @reload_running_tasks_list()
+ @task_poller = new (load_IntervalManager()) TASK_LIST_POLL_INTERVAL, =>
+ @reload_running_tasks_list()
+
+ # Populate the running tasks list
reload_running_tasks_list: =>
list_endpoint = @$table_running_tasks.data 'endpoint'
$.ajax
diff --git a/lms/static/coffee/src/instructor_dashboard/util.coffee b/lms/static/coffee/src/instructor_dashboard/util.coffee
index 9217da506434..629532768ec0 100644
--- a/lms/static/coffee/src/instructor_dashboard/util.coffee
+++ b/lms/static/coffee/src/instructor_dashboard/util.coffee
@@ -17,6 +17,54 @@ std_ajax_err = (handler) -> (jqXHR, textStatus, errorThrown) ->
handler.apply this, arguments
+# render a task list table to the DOM
+# `$table_tasks` the $element in which to put the table
+# `tasks_data`
+create_task_list_table = ($table_tasks, tasks_data) ->
+ $table_tasks.empty()
+
+ options =
+ enableCellNavigation: true
+ enableColumnReorder: false
+ autoHeight: true
+ rowHeight: 60
+ forceFitColumns: true
+
+ columns = [
+ id: 'task_type'
+ field: 'task_type'
+ name: 'Task Type'
+ ,
+ id: 'requester'
+ field: 'requester'
+ name: 'Requester'
+ width: 30
+ ,
+ id: 'task_input'
+ field: 'task_input'
+ name: 'Input'
+ ,
+ id: 'task_state'
+ field: 'task_state'
+ name: 'State'
+ width: 30
+ ,
+ id: 'task_id'
+ field: 'task_id'
+ name: 'Task ID'
+ width: 50
+ ,
+ id: 'created'
+ field: 'created'
+ name: 'Created'
+ ]
+
+ table_data = tasks_data
+
+ $table_placeholder = $ '', class: 'slickgrid'
+ $table_tasks.append $table_placeholder
+ grid = new Slick.Grid($table_placeholder, table_data, columns, options)
+
# Helper class for managing the execution of interval tasks.
# Handles pausing and restarting.
class IntervalManager
@@ -47,3 +95,4 @@ if _?
plantInterval: plantInterval
std_ajax_err: std_ajax_err
IntervalManager: IntervalManager
+ create_task_list_table: create_task_list_table
diff --git a/lms/templates/instructor/instructor_dashboard_2/course_info.html b/lms/templates/instructor/instructor_dashboard_2/course_info.html
index cb113e18469b..626d1b8ec815 100644
--- a/lms/templates/instructor/instructor_dashboard_2/course_info.html
+++ b/lms/templates/instructor/instructor_dashboard_2/course_info.html
@@ -43,6 +43,7 @@ ${_("Course Information")}
${_("Pending Instructor Tasks")}
${_("The status for any active tasks appears in a table below.")}
+
diff --git a/lms/templates/instructor/instructor_dashboard_2/data_download.html b/lms/templates/instructor/instructor_dashboard_2/data_download.html
index 0bf21dd58ac6..b57fd7b30e46 100644
--- a/lms/templates/instructor/instructor_dashboard_2/data_download.html
+++ b/lms/templates/instructor/instructor_dashboard_2/data_download.html
@@ -19,4 +19,16 @@ ${_("Data Download")}
+
+%if settings.MITX_FEATURES.get('ENABLE_INSTRUCTOR_BACKGROUND_TASKS'):
+
+
+
${_("Pending Instructor Tasks")}
+
${_("The status for any active tasks appears in a table below.")}
+
+
+
+
+
+%endif
diff --git a/lms/templates/instructor/instructor_dashboard_2/send_email.html b/lms/templates/instructor/instructor_dashboard_2/send_email.html
index 0ff0360e91c0..b3970c509130 100644
--- a/lms/templates/instructor/instructor_dashboard_2/send_email.html
+++ b/lms/templates/instructor/instructor_dashboard_2/send_email.html
@@ -54,4 +54,16 @@ ${_("Send Email")}
+
+%if settings.MITX_FEATURES.get('ENABLE_INSTRUCTOR_BACKGROUND_TASKS'):
+
+
+
${_("Pending Instructor Tasks")}
+
${_("The status for any active tasks appears in a table below.")}
+
+
+
+
+
+%endif
diff --git a/lms/templates/instructor/instructor_dashboard_2/student_admin.html b/lms/templates/instructor/instructor_dashboard_2/student_admin.html
index 2ae60789df7e..4d608100088b 100644
--- a/lms/templates/instructor/instructor_dashboard_2/student_admin.html
+++ b/lms/templates/instructor/instructor_dashboard_2/student_admin.html
@@ -109,3 +109,15 @@ ${_('Course-specific grade adjustment')}
%endif
+
+%if settings.MITX_FEATURES.get('ENABLE_INSTRUCTOR_BACKGROUND_TASKS'):
+
+
+
${_("Pending Instructor Tasks")}
+
${_("The status for any active tasks appears in a table below.")}
+
+
+
+
+
+%endif
From 123e18109ddedff33e8bab1a50fe23a392473970 Mon Sep 17 00:00:00 2001
From: Sarina Canelake
Date: Tue, 15 Oct 2013 18:48:31 -0400
Subject: [PATCH 2/4] Reorganize Course Info dash section
LMS-1242
---
.../instructor/views/instructor_dashboard.py | 10 ++-
.../instructor_dashboard/course_info.coffee | 2 +-
.../instructor_dashboard/data_download.coffee | 2 +-
.../instructor_dashboard/send_email.coffee | 2 +-
.../instructor_dashboard_2/course_info.html | 83 ++++++++++++-------
5 files changed, 62 insertions(+), 37 deletions(-)
diff --git a/lms/djangoapps/instructor/views/instructor_dashboard.py b/lms/djangoapps/instructor/views/instructor_dashboard.py
index c48efa91f9e7..a0b830d53541 100644
--- a/lms/djangoapps/instructor/views/instructor_dashboard.py
+++ b/lms/djangoapps/instructor/views/instructor_dashboard.py
@@ -45,7 +45,7 @@ def instructor_dashboard_2(request, course_id):
raise Http404()
sections = [
- _section_course_info(course_id, access),
+ _section_course_info(course_id),
_section_membership(course_id, access),
_section_student_admin(course_id, access),
_section_data_download(course_id),
@@ -86,15 +86,19 @@ def instructor_dashboard_2(request, course_id):
""" # pylint: disable=W0105
-def _section_course_info(course_id, access):
+def _section_course_info(course_id):
""" Provide data for the corresponding dashboard section """
course = get_course_by_id(course_id, depth=None)
+ (course_org, course_num, course_name) = course_id.split('/')
+
section_data = {
'section_key': 'course_info',
'section_display_name': _('Course Info'),
'course_id': course_id,
- 'access': access,
+ 'course_org': course_org,
+ 'course_num': course_num,
+ 'course_name': course_name,
'course_display_name': course.display_name,
'enrollment_count': CourseEnrollment.objects.filter(course_id=course_id).count(),
'has_started': course.has_started(),
diff --git a/lms/static/coffee/src/instructor_dashboard/course_info.coffee b/lms/static/coffee/src/instructor_dashboard/course_info.coffee
index beca8db71202..98e85be3499b 100644
--- a/lms/static/coffee/src/instructor_dashboard/course_info.coffee
+++ b/lms/static/coffee/src/instructor_dashboard/course_info.coffee
@@ -41,7 +41,7 @@ class CourseInfo
### Pending Instructor Tasks Section ####
# Currently running tasks
- @$table_running_tasks = @$section.find ".running-tasks-table"
+ @$table_running_tasks = @$section.find ".running-tasks-table"
# start polling for task list
# if the list is in the DOM
diff --git a/lms/static/coffee/src/instructor_dashboard/data_download.coffee b/lms/static/coffee/src/instructor_dashboard/data_download.coffee
index ffc24a574b13..f9051f5260cb 100644
--- a/lms/static/coffee/src/instructor_dashboard/data_download.coffee
+++ b/lms/static/coffee/src/instructor_dashboard/data_download.coffee
@@ -84,7 +84,7 @@ class DataDownload
### Pending Instructor Tasks Section ####
# Currently running tasks
- @$table_running_tasks = @$section.find ".running-tasks-table"
+ @$table_running_tasks = @$section.find ".running-tasks-table"
# start polling for task list
# if the list is in the DOM
diff --git a/lms/static/coffee/src/instructor_dashboard/send_email.coffee b/lms/static/coffee/src/instructor_dashboard/send_email.coffee
index 27eea3d339b5..14eda493a8ce 100644
--- a/lms/static/coffee/src/instructor_dashboard/send_email.coffee
+++ b/lms/static/coffee/src/instructor_dashboard/send_email.coffee
@@ -92,7 +92,7 @@ class Email
### Pending Instructor Tasks Section ####
# Currently running tasks
- @$table_running_tasks = @$section.find ".running-tasks-table"
+ @$table_running_tasks = @$section.find ".running-tasks-table"
# start polling for task list
# if the list is in the DOM
diff --git a/lms/templates/instructor/instructor_dashboard_2/course_info.html b/lms/templates/instructor/instructor_dashboard_2/course_info.html
index 626d1b8ec815..c97ab0af3211 100644
--- a/lms/templates/instructor/instructor_dashboard_2/course_info.html
+++ b/lms/templates/instructor/instructor_dashboard_2/course_info.html
@@ -1,44 +1,68 @@
<%! from django.utils.translation import ugettext as _ %>
<%page args="section_data"/>
-${_("Course Information")}
+
+
${_("Enrollment Information")}
+
${_("Total number of enrollees (instructors, staff members, and students)")}
+
+
${ section_data['enrollment_count'] }
-
- ${_("Course Name")}:
- ${ section_data['course_display_name'] }
+
-
- ${_("Course ID")}:
- ${ section_data['course_id'] }
-
+
+
${_("Basic Course Information")}
-
- ${_("Students Enrolled")}:
- ${ section_data['enrollment_count'] }
-
+