Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
1e8cb7df
Commit
1e8cb7df
authored
Jul 12, 2013
by
Miles Steele
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
clean & comment coffeescript, add util.coffee
parent
e05d0f97
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
349 additions
and
248 deletions
+349
-248
lms/static/coffee/src/instructor_dashboard/analytics.coffee
+22
-19
lms/static/coffee/src/instructor_dashboard/course_info.coffee
+22
-9
lms/static/coffee/src/instructor_dashboard/data_download.coffee
+28
-19
lms/static/coffee/src/instructor_dashboard/instructor_dashboard.coffee
+49
-37
lms/static/coffee/src/instructor_dashboard/membership.coffee
+171
-144
lms/static/coffee/src/instructor_dashboard/student_admin.coffee
+29
-19
lms/static/coffee/src/instructor_dashboard/util.coffee
+27
-0
lms/templates/courseware/instructor_dashboard_2/instructor_dashboard_2.html
+1
-1
No files found.
lms/static/coffee/src/instructor_dashboard/analytics.coffee
View file @
1e8cb7df
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
:
{}
...
...
lms/static/coffee/src/instructor_dashboard/course_info.coffee
View file @
1e8cb7df
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
:
{}
...
...
lms/static/coffee/src/instructor_dashboard/data_download.coffee
View file @
1e8cb7df
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
handle
r
.
apply
this
,
arguments
std_ajax_err
=
->
window
.
InstructorDashboard
.
util
.
std_ajax_er
r
.
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
:
{}
...
...
lms/static/coffee/src/instructor_dashboard/instructor_dashboard.coffee
View file @
1e8cb7df
# 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"
...
...
lms/static/coffee/src/instructor_dashboard/membership.coffee
View file @
1e8cb7df
log
=
->
console
.
log
.
apply
console
,
arguments
# Membership 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
handle
r
.
apply
this
,
arguments
std_ajax_err
=
->
window
.
InstructorDashboard
.
util
.
std_ajax_er
r
.
apply
this
,
arguments
# Wrapper for the batch enrollment subsection.
# This object handles buttons, success and failure reporting,
# and server communication.
class
BatchEnrollment
class
BatchEnrollment
constructor
:
(
@
$container
)
->
constructor
:
(
@
$container
)
->
log
"setting up instructor dashboard subsection - batch enrollment"
# gather elements
@
$emails_input
=
@
$container
.
find
(
"textarea[name='student-emails']'"
)
@
$btn_enroll
=
@
$container
.
find
(
"input[name='enroll']'"
)
@
$btn_unenroll
=
@
$container
.
find
(
"input[name='unenroll']'"
)
@
$checkbox_autoenroll
=
@
$container
.
find
(
"input[name='auto-enroll']'"
)
@
$task_response
=
@
$container
.
find
(
".request-response"
)
@
$request_response_error
=
@
$container
.
find
(
".request-response-error"
)
$emails_input
=
@
$container
.
find
(
"textarea[name='student-emails']'"
)
# attach click handlers
$btn_enroll
=
@
$container
.
find
(
"input[name='enroll']'"
)
$btn_unenroll
=
@
$container
.
find
(
"input[name='unenroll']'"
)
$checkbox_autoenroll
=
@
$container
.
find
(
"input[name='auto-enroll']'"
)
$task_response
=
@
$container
.
find
(
".request-response"
)
$request_response_error
=
@
$container
.
find
(
".request-response-error"
)
$emails_input
.
click
->
log
'click $emails_input'
@
$btn_enroll
.
click
=>
$btn_enroll
.
click
->
log
'click $btn_enroll'
$btn_unenroll
.
click
->
log
'click $btn_unenroll'
$btn_enroll
.
click
->
send_data
=
send_data
=
action
:
'enroll'
action
:
'enroll'
emails
:
$emails_input
.
val
()
emails
:
@
$emails_input
.
val
()
auto_enroll
:
$checkbox_autoenroll
.
is
(
':checked'
)
auto_enroll
:
@
$checkbox_autoenroll
.
is
(
':checked'
)
$
.
ajax
$
.
ajax
dataType
:
'json'
dataType
:
'json'
url
:
$btn_enroll
.
data
'endpoint'
url
:
@
$btn_enroll
.
data
'endpoint'
data
:
send_data
data
:
send_data
success
:
(
data
)
->
display_response
(
data
)
success
:
(
data
)
=>
@
display_response
data
error
:
std_ajax_err
->
fail_with_error
"Error enrolling/unenrolling students."
error
:
std_ajax_err
=>
@
fail_with_error
"Error enrolling/unenrolling students."
$btn_unenroll
.
click
-
>
@
$btn_unenroll
.
click
=
>
send_data
=
send_data
=
action
:
'unenroll'
action
:
'unenroll'
emails
:
$emails_input
.
val
()
emails
:
@
$emails_input
.
val
()
auto_enroll
:
$checkbox_autoenroll
.
is
(
':checked'
)
auto_enroll
:
@
$checkbox_autoenroll
.
is
(
':checked'
)
$
.
ajax
$
.
ajax
dataType
:
'json'
dataType
:
'json'
url
:
$btn_unenroll
.
data
'endpoint'
url
:
@
$btn_unenroll
.
data
'endpoint'
data
:
send_data
data
:
send_data
success
:
(
data
)
->
display_response
(
data
)
success
:
(
data
)
=>
@
display_response
data
error
:
std_ajax_err
->
fail_with_error
"Error enrolling/unenrolling students."
error
:
std_ajax_err
=>
@
fail_with_error
"Error enrolling/unenrolling students."
fail_with_error
=
(
msg
)
->
fail_with_error
:
(
msg
)
->
console
.
warn
msg
console
.
warn
msg
$task_response
.
empty
()
@
$task_response
.
empty
()
$request_response_error
.
empty
()
@
$request_response_error
.
empty
()
$request_response_error
.
text
msg
@
$request_response_error
.
text
msg
display_response
=
(
data_from_server
)
->
display_response
:
(
data_from_server
)
->
$task_response
.
empty
()
@
$task_response
.
empty
()
$request_response_error
.
empty
()
@
$request_response_error
.
empty
()
# these results arrays contain student_results
# these results arrays contain student_results
# only populated arrays will be rendered
# only populated arrays will be rendered
#
# students for which there was an error during the action
errors
=
[]
# students who are now enrolled in the course
enrolled
=
[]
# students who are now allowed to enroll in the course
allowed
=
[]
# students who will be autoenrolled on registration
autoenrolled
=
[]
# students who are now not enrolled in the course
notenrolled
=
[]
# categorize student results into the above arrays.
for
student_results
in
data_from_server
.
results
# for a successful action.
# student_results is of the form {
# "email": "jd405@edx.org",
# "before": {
# "enrollment": true,
# "auto_enroll": false,
# "user": true,
# "allowed": false
# }
# "after": {
# "enrollment": true,
# "auto_enroll": false,
# "user": true,
# "allowed": false
# },
# }
#
#
# students for which there was an error during the action
# for an action error.
errors
=
[]
# student_results is of the form {
# students who are now enrolled in the course
# 'email': email,
enrolled
=
[]
# 'error': True,
# students who are now allowed to enroll in the course
# }
allowed
=
[]
# students who will be autoenrolled on registration
if
student_results
.
error
autoenrolled
=
[]
errors
.
push
student_results
# students who are now not enrolled in the course
else
if
student_results
.
after
.
enrollment
notenrolled
=
[]
enrolled
.
push
student_results
else
if
student_results
.
after
.
allowed
# categorize student results into the above arrays.
if
student_results
.
after
.
auto_enroll
for
student_results
in
data_from_server
.
results
autoenrolled
.
push
student_results
# for a successful action.
# student_results is of the form {
# "email": "jd405@edx.org",
# "before": {
# "enrollment": true,
# "auto_enroll": false,
# "user": true,
# "allowed": false
# }
# "after": {
# "enrollment": true,
# "auto_enroll": false,
# "user": true,
# "allowed": false
# },
# }
#
# for an action error.
# student_results is of the form {
# 'email': email,
# 'error': True,
# }
if
student_results
.
error
!=
undefined
errors
.
push
student_results
else
if
student_results
.
after
.
enrollment
enrolled
.
push
student_results
else
if
student_results
.
after
.
allowed
if
student_results
.
after
.
auto_enroll
autoenrolled
.
push
student_results
else
allowed
.
push
student_results
else
if
not
student_results
.
after
.
enrollment
notenrolled
.
push
student_results
else
else
console
.
warn
'student results not reported to user'
allowed
.
push
student_results
console
.
warn
student_results
else
if
not
student_results
.
after
.
enrollment
notenrolled
.
push
student_results
# render populated result arrays
else
render_list
=
(
label
,
emails
)
->
console
.
warn
'student results not reported to user'
log
emails
console
.
warn
student_results
task_res_section
=
$
'<div/>'
,
class
:
'request-res-section'
task_res_section
.
append
$
'<h3/>'
,
text
:
label
# render populated result arrays
email_list
=
$
'<ul/>'
render_list
=
(
label
,
emails
)
=>
task_res_section
.
append
email_list
task_res_section
=
$
'<div/>'
,
class
:
'request-res-section'
task_res_section
.
append
$
'<h3/>'
,
text
:
label
for
email
in
emails
email_list
=
$
'<ul/>'
email_list
.
append
$
'<li/>'
,
text
:
email
task_res_section
.
append
email_list
$task_response
.
append
task_res_section
for
email
in
emails
email_list
.
append
$
'<li/>'
,
text
:
email
if
errors
.
length
errors_label
=
do
->
@
$task_response
.
append
task_res_section
if
data_from_server
.
action
is
'enroll'
"There was an error enrolling:"
if
errors
.
length
else
if
data_from_server
.
action
is
'unenroll'
errors_label
=
do
->
"There was an error unenrolling:"
if
data_from_server
.
action
is
'enroll'
else
"There was an error enrolling:"
console
.
warn
"unknown action from server '
#{
data_from_server
.
action
}
'"
else
if
data_from_server
.
action
is
'unenroll'
"There was an error processing:"
"There was an error unenrolling:"
else
console
.
warn
"unknown action from server '
#{
data_from_server
.
action
}
'"
"There was an error processing:"
for
student_results
in
errors
for
student_results
in
errors
console
.
log
'error with'
:
student_results
.
email
render_list
errors_label
,
(
sr
.
email
for
sr
in
errors
)
if
enrolled
.
length
if
enrolled
.
length
render_list
"Students Enrolled:"
,
(
sr
.
email
for
sr
in
enrolled
)
render_list
"Students Enrolled:"
,
(
sr
.
email
for
sr
in
enrolled
)
if
allowed
.
length
if
allowed
.
length
render_list
"These students will be allowed to enroll once they register:"
,
render_list
"These students will be allowed to enroll once they register:"
,
(
sr
.
email
for
sr
in
allowed
)
(
sr
.
email
for
sr
in
allowed
)
if
autoenrolled
.
length
if
autoenrolled
.
length
render_list
"These students will be enrolled once they register:"
,
render_list
"These students will be enrolled once they register:"
,
(
sr
.
email
for
sr
in
autoenrolled
)
(
sr
.
email
for
sr
in
autoenrolled
)
if
notenrolled
.
length
if
notenrolled
.
length
render_list
"These students are now not enrolled:"
,
render_list
"These students are now not enrolled:"
,
(
sr
.
email
for
sr
in
notenrolled
)
(
sr
.
email
for
sr
in
notenrolled
)
# manages a list of instructors or staff and the control of their access.
# Wrapper for auth list subsection.
# manages a list of users who have special access.
# these could be instructors, staff, beta users, or forum roles.
# uses slickgrid to display list.
class
AuthList
class
AuthList
# rolename is
in
['instructor', 'staff'] for instructor_staff endpoints
# rolename is
one of
['instructor', 'staff'] for instructor_staff endpoints
# rolename is the name of Role for forums for the forum endpoints
# rolename is the name of Role for forums for the forum endpoints
constructor
:
(
@
$container
,
@
rolename
)
->
constructor
:
(
@
$container
,
@
rolename
)
->
log
"setting up instructor dashboard subsection - authlist management for
#{
@
rolename
}
"
# gather elements
@
$display_table
=
@
$container
.
find
(
'.auth-list-table'
)
@
$display_table
=
@
$container
.
find
(
'.auth-list-table'
)
@
$request_response_error
=
@
$container
.
find
(
'.request-response-error'
)
@
$request_response_error
=
@
$container
.
find
(
'.request-response-error'
)
@
$add_section
=
@
$container
.
find
(
'.auth-list-add'
)
@
$add_section
=
@
$container
.
find
(
'.auth-list-add'
)
@
$allow_field
=
@
$add_section
.
find
(
"input[name='email']"
)
@
$allow_field
=
@
$add_section
.
find
(
"input[name='email']"
)
@
$allow_button
=
@
$add_section
.
find
(
"input[name='allow']"
)
@
$allow_button
=
@
$add_section
.
find
(
"input[name='allow']"
)
# attach click handler
@
$allow_button
.
click
=>
@
$allow_button
.
click
=>
@
access_change
@
$allow_field
.
val
(),
@
rolename
,
'allow'
,
=>
@
reload_auth_list
()
@
access_change
@
$allow_field
.
val
(),
'allow'
,
=>
@
reload_auth_list
()
@
$allow_field
.
val
''
@
$allow_field
.
val
''
@
reload_auth_list
()
@
reload_auth_list
()
# fetch and display list of users who match criteria
reload_auth_list
:
->
reload_auth_list
:
->
# helper function to display server data in the list
load_auth_list
=
(
data
)
=>
load_auth_list
=
(
data
)
=>
# clear existing data
@
$request_response_error
.
empty
()
@
$request_response_error
.
empty
()
@
$display_table
.
empty
()
@
$display_table
.
empty
()
# setup slickgrid
options
=
options
=
enableCellNavigation
:
true
enableCellNavigation
:
true
enableColumnReorder
:
false
enableColumnReorder
:
false
# autoHeight: true
# autoHeight: true
forceFitColumns
:
true
forceFitColumns
:
true
# this is a hack to put a button/link in a slick grid cell
# if you change columns, then you must update
# WHICH_CELL_IS_REVOKE to have the index
# of the revoke column (left to right).
WHICH_CELL_IS_REVOKE
=
3
WHICH_CELL_IS_REVOKE
=
3
columns
=
[
columns
=
[
id
:
'username'
id
:
'username'
...
@@ -216,13 +225,15 @@ class AuthList
...
@@ -216,13 +225,15 @@ class AuthList
$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
,
table_data
,
columns
,
options
)
grid
=
new
Slick
.
Grid
(
$table_placeholder
,
table_data
,
columns
,
options
)
# grid.autosizeColumns()
# click handler part of the revoke button/link hack.
grid
.
onClick
.
subscribe
(
e
,
args
)
=>
grid
.
onClick
.
subscribe
(
e
,
args
)
=>
item
=
args
.
grid
.
getDataItem
(
args
.
row
)
item
=
args
.
grid
.
getDataItem
(
args
.
row
)
if
args
.
cell
is
WHICH_CELL_IS_REVOKE
if
args
.
cell
is
WHICH_CELL_IS_REVOKE
@
access_change
item
.
email
,
@
rolename
,
'revoke'
,
=>
@
reload_auth_list
()
@
access_change
item
.
email
,
'revoke'
,
=>
@
reload_auth_list
()
# fetch data from the endpoint
# the endpoint comes from data-endpoint of the table
$
.
ajax
$
.
ajax
dataType
:
'json'
dataType
:
'json'
url
:
@
$display_table
.
data
'endpoint'
url
:
@
$display_table
.
data
'endpoint'
...
@@ -231,33 +242,45 @@ class AuthList
...
@@ -231,33 +242,45 @@ class AuthList
error
:
std_ajax_err
=>
@
$request_response_error
.
text
"Error fetching list for '
#{
@
rolename
}
'"
error
:
std_ajax_err
=>
@
$request_response_error
.
text
"Error fetching list for '
#{
@
rolename
}
'"
# slickgrid collapses when rendered in an invisible div
# slickgrid's layout collapses when rendered
# use this method to reload the widget
# in an invisible div. use this method to reload
# the AuthList widget
refresh
:
->
refresh
:
->
@
$display_table
.
empty
()
@
$display_table
.
empty
()
@
reload_auth_list
()
@
reload_auth_list
()
access_change
:
(
email
,
rolename
,
mode
,
cb
)
->
# update the access of a user.
# (add or remove them from the list)
# mode should be one of ['allow', 'revoke']
access_change
:
(
email
,
mode
,
cb
)
->
$
.
ajax
$
.
ajax
dataType
:
'json'
dataType
:
'json'
url
:
@
$add_section
.
data
'endpoint'
url
:
@
$add_section
.
data
'endpoint'
data
:
data
:
email
:
email
email
:
email
rolename
:
rolename
rolename
:
@
rolename
mode
:
mode
mode
:
mode
success
:
(
data
)
->
cb
?
(
data
)
success
:
(
data
)
->
cb
?
(
data
)
error
:
std_ajax_err
=>
@
$request_response_error
.
text
"Error changing user's permissions."
error
:
std_ajax_err
=>
@
$request_response_error
.
text
"Error changing user's permissions."
# Membership Section
class
Membership
class
Membership
# enable subsections.
constructor
:
(
@
$section
)
->
constructor
:
(
@
$section
)
->
log
"setting up instructor dashboard section - membership"
# attach self to html
# so that instructor_dashboard.coffee can find this object
# to call event handlers like 'onClickTitle'
@
$section
.
data
'wrapper'
,
@
@
$section
.
data
'wrapper'
,
@
@
$list_selector
=
@
$section
.
find
(
'select#member-lists-selector'
)
# isolate # initialize BatchEnrollment subsection
plantTimeout
0
,
=>
new
BatchEnrollment
@
$section
.
find
'.batch-enrollment'
plantTimeout
0
,
=>
@
batchenrollment
=
new
BatchEnrollment
@
$section
.
find
'.batch-enrollment'
# gather elements
@
$list_selector
=
@
$section
.
find
(
'select#member-lists-selector'
)
# initialize & store AuthList subsections
# one for each .auth-list-container in the section.
@
auth_lists
=
_
.
map
(
@
$section
.
find
'.auth-list-container'
),
(
auth_list_container
)
->
@
auth_lists
=
_
.
map
(
@
$section
.
find
'.auth-list-container'
),
(
auth_list_container
)
->
rolename
=
$
(
auth_list_container
).
data
'rolename'
rolename
=
$
(
auth_list_container
).
data
'rolename'
new
AuthList
$
(
auth_list_container
),
rolename
new
AuthList
$
(
auth_list_container
),
rolename
...
@@ -279,15 +302,19 @@ class Membership
...
@@ -279,15 +302,19 @@ class Membership
auth_list
.
refresh
()
auth_list
.
refresh
()
auth_list
.
$container
.
addClass
'active'
auth_list
.
$container
.
addClass
'active'
# one-time first selection of top list.
@
$list_selector
.
change
()
@
$list_selector
.
change
()
# handler for when the section title is clicked.
onClickTitle
:
->
onClickTitle
:
->
for
auth_list
in
@
auth_lists
for
auth_list
in
@
auth_lists
auth_list
.
refresh
()
auth_list
.
refresh
()
# 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
:
{}
...
...
lms/static/coffee/src/instructor_dashboard/student_admin.coffee
View file @
1e8cb7df
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
handle
r
.
apply
this
,
arguments
std_ajax_err
=
->
window
.
InstructorDashboard
.
util
.
std_ajax_er
r
.
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
:
{}
...
...
lms/static/coffee/src/instructor_dashboard/util.coffee
0 → 100644
View file @
1e8cb7df
# 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
lms/templates/courseware/instructor_dashboard_2/instructor_dashboard_2.html
View file @
1e8cb7df
...
@@ -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>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment