Enable Pending Tasks section on new dash
Add Pending Tasks section to the following tabs: * Course Info * Student Email * Data Download * Email LMS-1242
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@ MITX_FEATURES['ENABLE_MANUAL_GIT_RELOAD'] = True
|
||||
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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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: ->
|
||||
|
||||
|
||||
@@ -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 = $ '<div/>', 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
|
||||
|
||||
@@ -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 = $ '<div/>', 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
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
<hr>
|
||||
<h2> ${_("Pending Instructor Tasks")} </h2>
|
||||
<p>${_("The status for any active tasks appears in a table below.")} </p>
|
||||
<br />
|
||||
|
||||
<div class="running-tasks-table" data-endpoint="${ section_data['list_instructor_tasks_url'] }"></div>
|
||||
</div>
|
||||
|
||||
@@ -19,4 +19,16 @@
|
||||
<div class="data-display-text"></div>
|
||||
<div class="data-display-table"></div>
|
||||
<div class="request-response-error"></div>
|
||||
|
||||
%if settings.MITX_FEATURES.get('ENABLE_INSTRUCTOR_BACKGROUND_TASKS'):
|
||||
<div class="running-tasks-container action-type-container">
|
||||
<hr>
|
||||
<h2> ${_("Pending Instructor Tasks")} </h2>
|
||||
<p>${_("The status for any active tasks appears in a table below.")} </p>
|
||||
<br />
|
||||
|
||||
<div class="running-tasks-table" data-endpoint="${ section_data['list_instructor_tasks_url'] }"></div>
|
||||
</div>
|
||||
|
||||
%endif
|
||||
</div>
|
||||
|
||||
@@ -54,4 +54,16 @@
|
||||
<br />
|
||||
<input type="button" name="send" value="${_("Send Email")}" data-endpoint="${ section_data['send_email'] }" >
|
||||
<div class="request-response-error"></div>
|
||||
|
||||
%if settings.MITX_FEATURES.get('ENABLE_INSTRUCTOR_BACKGROUND_TASKS'):
|
||||
<div class="running-tasks-container action-type-container">
|
||||
<hr>
|
||||
<h2> ${_("Pending Instructor Tasks")} </h2>
|
||||
<p>${_("The status for any active tasks appears in a table below.")} </p>
|
||||
<br />
|
||||
|
||||
<div class="running-tasks-table" data-endpoint="${ section_data['list_instructor_tasks_url'] }"></div>
|
||||
</div>
|
||||
|
||||
%endif
|
||||
</div>
|
||||
|
||||
@@ -109,3 +109,15 @@
|
||||
</p>
|
||||
</div>
|
||||
%endif
|
||||
|
||||
%if settings.MITX_FEATURES.get('ENABLE_INSTRUCTOR_BACKGROUND_TASKS'):
|
||||
<div class="running-tasks-container action-type-container">
|
||||
<hr>
|
||||
<h2> ${_("Pending Instructor Tasks")} </h2>
|
||||
<p>${_("The status for any active tasks appears in a table below.")} </p>
|
||||
<br />
|
||||
|
||||
<div class="running-tasks-table" data-endpoint="${ section_data['list_instructor_tasks_url'] }"></div>
|
||||
</div>
|
||||
|
||||
%endif
|
||||
|
||||
Reference in New Issue
Block a user