Commit 1e8cb7df by Miles Steele

clean & comment coffeescript, add util.coffee

parent e05d0f97
log = -> console.log.apply console, arguments # Analytics Section
plantTimeout = (ms, cb) -> setTimeout cb, ms
std_ajax_err = (handler) -> (jqXHR, textStatus, errorThrown) ->
console.warn """ajax error
textStatus: #{textStatus}
errorThrown: #{errorThrown}"""
handler.apply this, arguments
# imports from other modules.
# wrap in (-> ... apply) to defer evaluation
# 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
# Analytics Section
class Analytics class Analytics
constructor: (@$section) -> constructor: (@$section) ->
log "setting up instructor dashboard section - analytics" # gather elements
@$display = @$section.find '.distribution-display' @$display = @$section.find '.distribution-display'
@$display_text = @$display.find '.distribution-display-text' @$display_text = @$display.find '.distribution-display-text'
@$display_graph = @$display.find '.distribution-display-graph' @$display_graph = @$display.find '.distribution-display-graph'
...@@ -21,20 +19,23 @@ class Analytics ...@@ -21,20 +19,23 @@ class Analytics
@populate_selector => @$distribution_select.change => @on_selector_change() @populate_selector => @$distribution_select.change => @on_selector_change()
reset_display: -> reset_display: ->
@$display_text.empty() @$display_text.empty()
@$display_graph.empty() @$display_graph.empty()
@$display_table.empty() @$display_table.empty()
@$request_response_error.empty() @$request_response_error.empty()
# fetch and list available distributions
# `cb` is a callback to be run after
populate_selector: (cb) -> populate_selector: (cb) ->
@get_profile_distributions [], @get_profile_distributions [],
# on error, print to console and dom.
error: std_ajax_err => @$request_response_error.text "Error getting available distributions." error: std_ajax_err => @$request_response_error.text "Error getting available distributions."
success: (data) => success: (data) =>
# replace loading text in drop-down with "-- Select Distribution --"
@$distribution_select.find('option').eq(0).text "-- Select Distribution --" @$distribution_select.find('option').eq(0).text "-- Select Distribution --"
# add all fetched available features to drop-down
for feature in data.available_features for feature in data.available_features
opt = $ '<option/>', opt = $ '<option/>',
text: data.display_names[feature] text: data.display_names[feature]
...@@ -43,14 +44,13 @@ class Analytics ...@@ -43,14 +44,13 @@ class Analytics
@$distribution_select.append opt @$distribution_select.append opt
# call callback if one was supplied
cb?() cb?()
# display data
on_selector_change: -> on_selector_change: ->
# log 'changeargs', arguments
opt = @$distribution_select.children('option:selected') opt = @$distribution_select.children('option:selected')
feature = opt.data 'feature' feature = opt.data 'feature'
log "distribution selected: #{feature}"
@reset_display() @reset_display()
return unless feature return unless feature
...@@ -64,7 +64,7 @@ class Analytics ...@@ -64,7 +64,7 @@ class Analytics
@$display_text.text 'Error fetching data' @$display_text.text 'Error fetching data'
else else
if feature_res.type is 'EASY_CHOICE' if feature_res.type is 'EASY_CHOICE'
# setup SlickGrid # display on SlickGrid
options = options =
enableCellNavigation: true enableCellNavigation: true
enableColumnReorder: false enableColumnReorder: false
...@@ -89,7 +89,6 @@ class Analytics ...@@ -89,7 +89,6 @@ class Analytics
table_placeholder = $ '<div/>', class: 'slickgrid' table_placeholder = $ '<div/>', class: 'slickgrid'
@$display_table.append table_placeholder @$display_table.append table_placeholder
grid = new Slick.Grid(table_placeholder, grid_data, columns, options) grid = new Slick.Grid(table_placeholder, grid_data, columns, options)
# grid.autosizeColumns()
else if feature is 'year_of_birth' else if feature is 'year_of_birth'
graph_placeholder = $ '<div/>', class: 'year-of-birth' graph_placeholder = $ '<div/>', class: 'year-of-birth'
@$display_graph.append graph_placeholder @$display_graph.append graph_placeholder
...@@ -104,7 +103,9 @@ class Analytics ...@@ -104,7 +103,9 @@ class Analytics
@$display_text.text 'Unavailable Metric\n' + JSON.stringify(feature_res) @$display_text.text 'Unavailable Metric\n' + JSON.stringify(feature_res)
# handler can be either a callback for success or a mapping e.g. {success: ->, error: ->, complete: ->} # fetch distribution data from server.
# `handler` can be either a callback for success
# or a mapping e.g. {success: ->, error: ->, complete: ->}
get_profile_distributions: (featurelist, handler) -> get_profile_distributions: (featurelist, handler) ->
settings = settings =
dataType: 'json' dataType: 'json'
...@@ -119,7 +120,9 @@ class Analytics ...@@ -119,7 +120,9 @@ class Analytics
$.ajax settings $.ajax settings
# exports # export for use
# create parent namespaces if they do not already exist.
# abort if underscore can not be found.
if _? if _?
_.defaults window, InstructorDashboard: {} _.defaults window, InstructorDashboard: {}
_.defaults window.InstructorDashboard, sections: {} _.defaults window.InstructorDashboard, sections: {}
......
log = -> console.log.apply console, arguments # Course Info Section
plantTimeout = (ms, cb) -> setTimeout cb, ms # 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).
plantTimeout = -> window.InstructorDashboard.util.plantTimeout.apply this, arguments
std_ajax_err = -> window.InstructorDashboard.util.std_ajax_err.apply this, arguments
# A typical section object.
# constructed with $section, a jquery object
# which holds the section body container.
class CourseInfo class CourseInfo
constructor: (@$section) -> constructor: (@$section) ->
log "setting up instructor dashboard section - course info"
@$section.data 'wrapper', @
@$course_errors_wrapper = @$section.find '.course-errors-wrapper' @$course_errors_wrapper = @$section.find '.course-errors-wrapper'
# if there are errors
if @$course_errors_wrapper.length if @$course_errors_wrapper.length
@$course_error_toggle = @$course_errors_wrapper.find('.toggle-wrapper').eq(0) @$course_error_toggle = @$course_errors_wrapper.find '.toggle-wrapper'
@$course_error_toggle_text = @$course_error_toggle.find('h2').eq(0) @$course_error_toggle_text = @$course_error_toggle.find 'h2'
@$course_error_visibility_wrapper = @$course_errors_wrapper.find '.course-errors-visibility-wrapper' @$course_error_visibility_wrapper = @$course_errors_wrapper.find '.course-errors-visibility-wrapper'
@$course_errors = @$course_errors_wrapper.find('.course-error') @$course_errors = @$course_errors_wrapper.find '.course-error'
# append "(34)" to the course errors label
@$course_error_toggle_text.text @$course_error_toggle_text.text() + " (#{@$course_errors.length})" @$course_error_toggle_text.text @$course_error_toggle_text.text() + " (#{@$course_errors.length})"
# toggle .open class on errors
# to show and hide them.
@$course_error_toggle.click (e) => @$course_error_toggle.click (e) =>
e.preventDefault() e.preventDefault()
if @$course_errors_wrapper.hasClass 'open' if @$course_errors_wrapper.hasClass 'open'
...@@ -24,7 +35,9 @@ class CourseInfo ...@@ -24,7 +35,9 @@ class CourseInfo
@$course_errors_wrapper.addClass 'open' @$course_errors_wrapper.addClass 'open'
# exports # export for use
# create parent namespaces if they do not already exist.
# abort if underscore can not be found.
if _? if _?
_.defaults window, InstructorDashboard: {} _.defaults window, InstructorDashboard: {}
_.defaults window.InstructorDashboard, sections: {} _.defaults window.InstructorDashboard, sections: {}
......
log = -> console.log.apply console, arguments # Data Download Section
plantTimeout = (ms, cb) -> setTimeout cb, ms
std_ajax_err = (handler) -> (jqXHR, textStatus, errorThrown) -> # imports from other modules.
console.warn """ajax error # wrap in (-> ... apply) to defer evaluation
textStatus: #{textStatus} # such that the value can be defined later than this assignment (file load order).
errorThrown: #{errorThrown}""" plantTimeout = -> window.InstructorDashboard.util.plantTimeout.apply this, arguments
handler.apply this, arguments std_ajax_err = -> window.InstructorDashboard.util.std_ajax_err.apply this, arguments
# Data Download Section
class DataDownload class DataDownload
constructor: (@$section) -> constructor: (@$section) ->
log "setting up instructor dashboard section - data download" # gather elements
@$display = @$section.find '.data-display' @$display = @$section.find '.data-display'
@$display_text = @$display.find '.data-display-text' @$display_text = @$display.find '.data-display-text'
@$display_table = @$display.find '.data-display-table' @$display_table = @$display.find '.data-display-table'
@$request_response_error = @$display.find '.request-response-error' @$request_response_error = @$display.find '.request-response-error'
@$list_studs_btn = @$section.find("input[name='list-profiles']'")
@$grade_config_btn = @$section.find("input[name='dump-gradeconf']'")
# attach click handlers
$list_studs_btn = @$section.find("input[name='list-profiles']'") # this handler binds to both the download
$list_studs_btn.click (e) => # and the csv button
log "fetching student list" @$list_studs_btn.click (e) =>
url = $list_studs_btn.data('endpoint') url = @$list_studs_btn.data 'endpoint'
# handle csv special case
if $(e.target).data 'csv' if $(e.target).data 'csv'
# redirect the document to the csv file.
url += '/csv' url += '/csv'
location.href = url location.href = url
else else
@clear_display() @clear_display()
@$display_table.text 'Loading...' @$display_table.text 'Loading...'
# fetch user list
$.ajax $.ajax
dataType: 'json' dataType: 'json'
url: url url: url
...@@ -36,7 +44,7 @@ class DataDownload ...@@ -36,7 +44,7 @@ class DataDownload
success: (data) => success: (data) =>
@clear_display() @clear_display()
# setup SlickGrid # display on a SlickGrid
options = options =
enableCellNavigation: true enableCellNavigation: true
enableColumnReorder: false enableColumnReorder: false
...@@ -50,10 +58,9 @@ class DataDownload ...@@ -50,10 +58,9 @@ class DataDownload
grid = new Slick.Grid($table_placeholder, grid_data, columns, options) grid = new Slick.Grid($table_placeholder, grid_data, columns, options)
# grid.autosizeColumns() # grid.autosizeColumns()
$grade_config_btn = @$section.find("input[name='dump-gradeconf']'") @$grade_config_btn.click (e) =>
$grade_config_btn.click (e) => url = @$grade_config_btn.data 'endpoint'
log "fetching grading config" # display html from grading config endpoint
url = $grade_config_btn.data('endpoint')
$.ajax $.ajax
dataType: 'json' dataType: 'json'
url: url url: url
...@@ -71,7 +78,9 @@ class DataDownload ...@@ -71,7 +78,9 @@ class DataDownload
@$request_response_error.empty() @$request_response_error.empty()
# exports # export for use
# create parent namespaces if they do not already exist.
# abort if underscore can not be found.
if _? if _?
_.defaults window, InstructorDashboard: {} _.defaults window, InstructorDashboard: {}
_.defaults window.InstructorDashboard, sections: {} _.defaults window.InstructorDashboard, sections: {}
......
# Instructor Dashboard Tab Manager # Instructor Dashboard Tab Manager
# The instructor dashboard is broken into sections.
log = -> console.log.apply console, arguments # Only one section is visible at a time,
plantTimeout = (ms, cb) -> setTimeout cb, ms # and is responsible for its own functionality.
#
# NOTE: plantTimeout (which is just setTimeout from util.coffee)
# # intercepts a jquery method # is used frequently in the instructor dashboard to isolate
# # calls the original method after callback # failures. If one piece of code under a plantTimeout fails
# intercept_jquery_method = (method_name, callback) -> # then it will not crash the rest of the dashboard.
# original = jQuery.fn[method_name] #
# jQuery.fn[method_name] = -> # NOTE: The instructor dashboard currently does not
# callback.apply this, arguments # use backbone. Just lots of jquery. This should be fixed.
# original.apply this, arguments #
# NOTE: Server endpoints in the dashboard are stored in
# the 'data-endpoint' attribute of relevant html elements.
# intercept_jquery_method 'on', (event_name) -> # The urls are rendered there by a template.
# this.addClass "has-event-handler-for-#{event_name}" #
# NOTE: For an example of what a section object should look like
# see course_info.coffee
# imports from other modules
# wrap in (-> ... apply) to defer evaluation
# 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
# CSS classes
CSS_INSTRUCTOR_CONTENT = 'instructor-dashboard-content-2' CSS_INSTRUCTOR_CONTENT = 'instructor-dashboard-content-2'
CSS_ACTIVE_SECTION = 'active-section' CSS_ACTIVE_SECTION = 'active-section'
CSS_IDASH_SECTION = 'idash-section' CSS_IDASH_SECTION = 'idash-section'
CSS_INSTRUCTOR_NAV = 'instructor-nav' CSS_INSTRUCTOR_NAV = 'instructor-nav'
# prefix for deep-linking
HASH_LINK_PREFIX = '#view-' HASH_LINK_PREFIX = '#view-'
# once we're ready, check if this page is the instructor dashboard
# once we're ready, check if this page has the instructor dashboard
$ => $ =>
instructor_dashboard_content = $ ".#{CSS_INSTRUCTOR_CONTENT}" instructor_dashboard_content = $ ".#{CSS_INSTRUCTOR_CONTENT}"
if instructor_dashboard_content.length != 0 console.log 'checking if we are on the instructor dashboard'
log "setting up instructor dashboard" if instructor_dashboard_content.length > 0
console.log 'we are on the instructor dashboard'
setup_instructor_dashboard instructor_dashboard_content setup_instructor_dashboard instructor_dashboard_content
setup_instructor_dashboard_sections instructor_dashboard_content setup_instructor_dashboard_sections instructor_dashboard_content
# enable links # enable navigation bar
# handles hiding and showing sections
setup_instructor_dashboard = (idash_content) => setup_instructor_dashboard = (idash_content) =>
# clickable section titles
links = idash_content.find(".#{CSS_INSTRUCTOR_NAV}").find('a') links = idash_content.find(".#{CSS_INSTRUCTOR_NAV}").find('a')
# setup section header click handlers
for link in ($ link for link in links) for link in ($ link for link in links)
link.click (e) -> link.click (e) ->
e.preventDefault() e.preventDefault()
# deactivate (styling) all sections
idash_content.find(".#{CSS_IDASH_SECTION}").removeClass CSS_ACTIVE_SECTION # deactivate all link & section styles
idash_content.find(".#{CSS_INSTRUCTOR_NAV}").children().removeClass CSS_ACTIVE_SECTION idash_content.find(".#{CSS_INSTRUCTOR_NAV}").children().removeClass CSS_ACTIVE_SECTION
idash_content.find(".#{CSS_IDASH_SECTION}").removeClass CSS_ACTIVE_SECTION
# find paired section # discover section paired to link
section_name = $(this).data 'section' section_name = $(this).data 'section'
section = idash_content.find "##{section_name}" section = idash_content.find "##{section_name}"
# activate (styling) active # activate link & section styling
section.addClass CSS_ACTIVE_SECTION
$(this).addClass CSS_ACTIVE_SECTION $(this).addClass CSS_ACTIVE_SECTION
section.addClass CSS_ACTIVE_SECTION
# tracking # tracking
# analytics.pageview "instructor_#{section_name}" # analytics.pageview "instructor_#{section_name}"
# write deep link # deep linking
# write to url
location.hash = "#{HASH_LINK_PREFIX}#{section_name}" location.hash = "#{HASH_LINK_PREFIX}#{section_name}"
log "clicked section #{section_name}"
plantTimeout 0, -> section.data('wrapper')?.onClickTitle?() plantTimeout 0, -> section.data('wrapper')?.onClickTitle?()
# plantTimeout 0, -> section.data('wrapper')?.onExit?() # plantTimeout 0, -> section.data('wrapper')?.onExit?()
# recover deep link from url
# click default or go to section specified by hash # activate an initial section by programmatically clicking on it.
# check for a deep-link, or click the first link.
if (new RegExp "^#{HASH_LINK_PREFIX}").test location.hash if (new RegExp "^#{HASH_LINK_PREFIX}").test location.hash
rmatch = (new RegExp "^#{HASH_LINK_PREFIX}(.*)").exec location.hash rmatch = (new RegExp "^#{HASH_LINK_PREFIX}(.*)").exec location.hash
section_name = rmatch[1] section_name = rmatch[1]
...@@ -78,11 +91,10 @@ setup_instructor_dashboard = (idash_content) => ...@@ -78,11 +91,10 @@ setup_instructor_dashboard = (idash_content) =>
# call setup handlers for each section # enable sections
setup_instructor_dashboard_sections = (idash_content) -> setup_instructor_dashboard_sections = (idash_content) ->
log "setting up instructor dashboard sections" # see fault isolation NOTE at top of file.
# fault isolation # an error thrown in one section will not block other sections from exectuing.
# 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.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.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.Membership idash_content.find ".#{CSS_IDASH_SECTION}#membership"
......
log = -> console.log.apply console, arguments # Student Admin Section
plantTimeout = (ms, cb) -> setTimeout cb, ms
plantInterval = (ms, cb) -> setInterval cb, ms
# imports from other modules.
std_ajax_err = (handler) -> (jqXHR, textStatus, errorThrown) -> # wrap in (-> ... apply) to defer evaluation
console.warn """ajax error # such that the value can be defined later than this assignment (file load order).
textStatus: #{textStatus} plantTimeout = -> window.InstructorDashboard.util.plantTimeout.apply this, arguments
errorThrown: #{errorThrown}""" plantInterval = -> window.InstructorDashboard.util.plantInterval.apply this, arguments
handler.apply this, arguments std_ajax_err = -> window.InstructorDashboard.util.std_ajax_err.apply this, arguments
# get jquery element and assert its existance # get jquery element and assert its existance
find_and_assert = ($root, selector) -> find_and_assert = ($root, selector) ->
...@@ -18,6 +16,9 @@ find_and_assert = ($root, selector) -> ...@@ -18,6 +16,9 @@ find_and_assert = ($root, selector) ->
else else
item 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) -> create_task_list_table = ($table_tasks, tasks_data) ->
$table_tasks.empty() $table_tasks.empty()
...@@ -66,11 +67,11 @@ create_task_list_table = ($table_tasks, tasks_data) -> ...@@ -66,11 +67,11 @@ create_task_list_table = ($table_tasks, tasks_data) ->
class StudentAdmin class StudentAdmin
constructor: (@$section) -> constructor: (@$section) ->
log "setting up instructor dashboard section - student admin"
@$section.data 'wrapper', @ @$section.data 'wrapper', @
# collect buttons # gather buttons
# some buttons are optional because they can be flipped by the instructor task feature switch # some buttons are optional because they can be flipped by the instructor task feature switch
# student-specific
@$field_student_select = find_and_assert @$section, "input[name='student-select']" @$field_student_select = find_and_assert @$section, "input[name='student-select']"
@$progress_link = find_and_assert @$section, "a.progress-link" @$progress_link = find_and_assert @$section, "a.progress-link"
@$btn_enroll = find_and_assert @$section, "input[name='enroll']" @$btn_enroll = find_and_assert @$section, "input[name='enroll']"
...@@ -82,7 +83,7 @@ class StudentAdmin ...@@ -82,7 +83,7 @@ class StudentAdmin
@$btn_task_history_single = @$section.find "input[name='task-history-single']" @$btn_task_history_single = @$section.find "input[name='task-history-single']"
@$table_task_history_single = @$section.find ".task-history-single-table" @$table_task_history_single = @$section.find ".task-history-single-table"
# course-specific level buttons # course-specific
@$field_problem_select_all = @$section.find "input[name='problem-select-all']" @$field_problem_select_all = @$section.find "input[name='problem-select-all']"
@$btn_reset_attempts_all = @$section.find "input[name='reset-attempts-all']" @$btn_reset_attempts_all = @$section.find "input[name='reset-attempts-all']"
@$btn_rescore_problem_all = @$section.find "input[name='rescore-problem-all']" @$btn_rescore_problem_all = @$section.find "input[name='rescore-problem-all']"
...@@ -90,12 +91,16 @@ class StudentAdmin ...@@ -90,12 +91,16 @@ class StudentAdmin
@$table_task_history_all = @$section.find ".task-history-all-table" @$table_task_history_all = @$section.find ".task-history-all-table"
@$table_running_tasks = @$section.find ".running-tasks-table" @$table_running_tasks = @$section.find ".running-tasks-table"
# response areas
@$request_response_error_single = find_and_assert @$section, ".student-specific-container .request-response-error" @$request_response_error_single = find_and_assert @$section, ".student-specific-container .request-response-error"
@$request_response_error_all = @$section.find ".course-specific-container .request-response-error" @$request_response_error_all = @$section.find ".course-specific-container .request-response-error"
# start polling for task list
if @$table_running_tasks.length > 0 if @$table_running_tasks.length > 0
@start_refresh_running_task_poll_loop() @start_refresh_running_task_poll_loop()
# attach click handlers
# go to student progress page # go to student progress page
@$progress_link.click (e) => @$progress_link.click (e) =>
e.preventDefault() e.preventDefault()
...@@ -106,7 +111,6 @@ class StudentAdmin ...@@ -106,7 +111,6 @@ class StudentAdmin
url: @$progress_link.data 'endpoint' url: @$progress_link.data 'endpoint'
data: student_email: email data: student_email: email
success: @clear_errors_then (data) -> success: @clear_errors_then (data) ->
log 'redirecting...'
window.location = data.progress_url window.location = data.progress_url
error: std_ajax_err => @$request_response_error_single.text "Error getting student progress url for '#{email}'." error: std_ajax_err => @$request_response_error_single.text "Error getting student progress url for '#{email}'."
...@@ -148,7 +152,7 @@ class StudentAdmin ...@@ -148,7 +152,7 @@ class StudentAdmin
dataType: 'json' dataType: 'json'
url: @$btn_reset_attempts_single.data 'endpoint' url: @$btn_reset_attempts_single.data 'endpoint'
data: send_data data: send_data
success: @clear_errors_then -> log 'problem attempts reset' success: @clear_errors_then -> console.log 'problem attempts reset'
error: std_ajax_err => @$request_response_error_single.text "Error resetting problem attempts." error: std_ajax_err => @$request_response_error_single.text "Error resetting problem attempts."
# delete state for student on problem # delete state for student on problem
...@@ -162,7 +166,7 @@ class StudentAdmin ...@@ -162,7 +166,7 @@ class StudentAdmin
dataType: 'json' dataType: 'json'
url: @$btn_delete_state_single.data 'endpoint' url: @$btn_delete_state_single.data 'endpoint'
data: send_data data: send_data
success: @clear_errors_then -> log 'module state deleted' success: @clear_errors_then -> console.log 'module state deleted'
error: std_ajax_err => @$request_response_error_single.text "Error deleting problem state." error: std_ajax_err => @$request_response_error_single.text "Error deleting problem state."
# start task to rescore problem for student # start task to rescore problem for student
...@@ -175,7 +179,7 @@ class StudentAdmin ...@@ -175,7 +179,7 @@ class StudentAdmin
dataType: 'json' dataType: 'json'
url: @$btn_rescore_problem_single.data 'endpoint' url: @$btn_rescore_problem_single.data 'endpoint'
data: send_data data: send_data
success: @clear_errors_then -> log 'started rescore problem task' success: @clear_errors_then -> console.log 'started rescore problem task'
error: std_ajax_err => @$request_response_error_single.text "Error starting a task to rescore student's problem." error: std_ajax_err => @$request_response_error_single.text "Error starting a task to rescore student's problem."
# list task history for student+problem # list task history for student+problem
...@@ -207,7 +211,7 @@ class StudentAdmin ...@@ -207,7 +211,7 @@ class StudentAdmin
dataType: 'json' dataType: 'json'
url: @$btn_reset_attempts_all.data 'endpoint' url: @$btn_reset_attempts_all.data 'endpoint'
data: send_data data: send_data
success: @clear_errors_then -> log 'started reset attempts task' success: @clear_errors_then -> console.log 'started reset attempts task'
error: std_ajax_err => @$request_response_error_all.text "Error starting a task to reset attempts for all students on this problem." error: std_ajax_err => @$request_response_error_all.text "Error starting a task to reset attempts for all students on this problem."
# start task to rescore problem for all students # start task to rescore problem for all students
...@@ -220,7 +224,7 @@ class StudentAdmin ...@@ -220,7 +224,7 @@ class StudentAdmin
dataType: 'json' dataType: 'json'
url: @$btn_rescore_problem_all.data 'endpoint' url: @$btn_rescore_problem_all.data 'endpoint'
data: send_data data: send_data
success: @clear_errors_then -> log 'started rescore problem task' success: @clear_errors_then -> console.log 'started rescore problem task'
error: std_ajax_err => @$request_response_error_all.text "Error starting a task to rescore this problem for all students." error: std_ajax_err => @$request_response_error_all.text "Error starting a task to rescore this problem for all students."
# list task history for problem # list task history for problem
...@@ -253,21 +257,27 @@ class StudentAdmin ...@@ -253,21 +257,27 @@ class StudentAdmin
if @$section.hasClass 'active-section' if @$section.hasClass 'active-section'
plantTimeout 5000, => @start_refresh_running_task_poll_loop() plantTimeout 5000, => @start_refresh_running_task_poll_loop()
# wraps a function, but first clear the error displays
clear_errors_then: (cb) -> clear_errors_then: (cb) ->
@$request_response_error_single.empty() @$request_response_error_single.empty()
@$request_response_error_all.empty() @$request_response_error_all.empty()
-> ->
cb?.apply this, arguments cb?.apply this, arguments
# handler for when the section title is clicked.
onClickTitle: -> onClickTitle: ->
if @$table_running_tasks.length > 0 if @$table_running_tasks.length > 0
@start_refresh_running_task_poll_loop() @start_refresh_running_task_poll_loop()
# handler for when the section is closed
# not working yet.
# onExit: -> # onExit: ->
# clearInterval @reload_running_task_list_slot # clearInterval @reload_running_task_list_slot
# exports # export for use
# create parent namespaces if they do not already exist.
# abort if underscore can not be found.
if _? if _?
_.defaults window, InstructorDashboard: {} _.defaults window, InstructorDashboard: {}
_.defaults window.InstructorDashboard, sections: {} _.defaults window.InstructorDashboard, sections: {}
......
# Common utilities for instructor dashboard components.
# reverse arguments on common functions to enable
# better coffeescript with callbacks at the end.
plantTimeout = (ms, cb) -> setTimeout cb, ms
plantInterval = (ms, cb) -> setInterval cb, ms
# standard ajax error wrapper
#
# wraps a `handler` function so that first
# it prints basic error information to the console.
std_ajax_err = (handler) -> (jqXHR, textStatus, errorThrown) ->
console.warn """ajax error
textStatus: #{textStatus}
errorThrown: #{errorThrown}"""
handler.apply this, arguments
# export for use
# create parent namespaces if they do not already exist.
# abort if underscore can not be found.
if _?
_.defaults window, InstructorDashboard: {}
window.InstructorDashboard.util =
plantTimeout: plantTimeout
plantInterval: plantInterval
std_ajax_err: std_ajax_err
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
## links which are tied to idash-sections below. ## links which are tied to idash-sections below.
## the links are acativated and handled in instructor_dashboard.coffee ## the links are acativated and handled in instructor_dashboard.coffee
## when the javascript loads, it clicks on idash-default-section ## when the javascript loads, it clicks on the first section
<h2 class="instructor-nav"> <h2 class="instructor-nav">
% for section_data in sections: % for section_data in sections:
<a href="" data-section="${ section_data['section_key'] }">${ section_data['section_display_name'] }</a> <a href="" data-section="${ section_data['section_key'] }">${ section_data['section_display_name'] }</a>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment