Add sorting to course details mock UI
This commit is contained in:
parent
49a75d2d42
commit
e70b8b8652
3 changed files with 61 additions and 2 deletions
app
styles/courses/mock1
templates/courses/mock1
views/courses/mock1
|
@ -1,5 +1,10 @@
|
||||||
#course-details-view
|
#course-details-view
|
||||||
|
|
||||||
|
.member-header
|
||||||
|
cursor: pointer
|
||||||
|
display: inline-block
|
||||||
|
padding: 2px
|
||||||
|
|
||||||
.textarea-emails
|
.textarea-emails
|
||||||
width: 50%
|
width: 50%
|
||||||
|
|
||||||
|
@ -13,6 +18,7 @@
|
||||||
|
|
||||||
.progress-header
|
.progress-header
|
||||||
margin-right: 14px
|
margin-right: 14px
|
||||||
|
cursor: pointer
|
||||||
|
|
||||||
.progress-key
|
.progress-key
|
||||||
cursor: default
|
cursor: default
|
||||||
|
|
|
@ -73,8 +73,19 @@ block content
|
||||||
thead
|
thead
|
||||||
tr
|
tr
|
||||||
th
|
th
|
||||||
|
span.member-header.spr Name
|
||||||
|
if memberSort === 'nameAsc'
|
||||||
|
span.member-header.glyphicon.glyphicon-chevron-up
|
||||||
|
else if memberSort === 'nameDesc'
|
||||||
|
span.member-header.glyphicon.glyphicon-chevron-down
|
||||||
th
|
th
|
||||||
span.progress-header Progress
|
span.progress-header.spr Progress
|
||||||
|
if memberSort === 'progressAsc'
|
||||||
|
span.progress-header.glyphicon.glyphicon-chevron-up
|
||||||
|
else if memberSort === 'progressDesc'
|
||||||
|
span.progress-header.glyphicon.glyphicon-chevron-down
|
||||||
|
else
|
||||||
|
span(style='padding-left:16px;')
|
||||||
span.progress-key.progress-key-complete complete
|
span.progress-key.progress-key-complete complete
|
||||||
span.progress-key.progress-key-started started
|
span.progress-key.progress-key-started started
|
||||||
span.progress-key not started
|
span.progress-key not started
|
||||||
|
|
|
@ -12,9 +12,11 @@ module.exports = class CourseDetailsView extends RootView
|
||||||
'change .expand-progress-checkbox': 'onExpandedProgressCheckbox'
|
'change .expand-progress-checkbox': 'onExpandedProgressCheckbox'
|
||||||
'change .select-session': 'onChangeSession'
|
'change .select-session': 'onChangeSession'
|
||||||
'change .student-mode-checkbox': 'onChangeStudent'
|
'change .student-mode-checkbox': 'onChangeStudent'
|
||||||
|
'click .btn-play-level': 'onClickPlayLevel'
|
||||||
'click .edit-class-name-btn': 'onClickEditClassName'
|
'click .edit-class-name-btn': 'onClickEditClassName'
|
||||||
'click .edit-description-btn': 'onClickEditClassDescription'
|
'click .edit-description-btn': 'onClickEditClassDescription'
|
||||||
'click .btn-play-level': 'onClickPlayLevel'
|
'click .member-header': 'onClickMemberHeader'
|
||||||
|
'click .progress-header': 'onClickProgressHeader'
|
||||||
|
|
||||||
constructor: (options, @courseID) ->
|
constructor: (options, @courseID) ->
|
||||||
super options
|
super options
|
||||||
|
@ -32,6 +34,7 @@ module.exports = class CourseDetailsView extends RootView
|
||||||
context.instances = @instances ? []
|
context.instances = @instances ? []
|
||||||
context.levelConceptsMap = @levelConceptsMap ? {}
|
context.levelConceptsMap = @levelConceptsMap ? {}
|
||||||
context.maxLastStartedIndex = @maxLastStartedIndex ? 0
|
context.maxLastStartedIndex = @maxLastStartedIndex ? 0
|
||||||
|
context.memberSort = @memberSort
|
||||||
context.userConceptsMap = @userConceptsMap ? {}
|
context.userConceptsMap = @userConceptsMap ? {}
|
||||||
context.userLevelStateMap = @userLevelStateMap ? {}
|
context.userLevelStateMap = @userLevelStateMap ? {}
|
||||||
context.showExpandedProgress = @course.levels.length <= 30 or @showExpandedProgress
|
context.showExpandedProgress = @course.levels.length <= 30 or @showExpandedProgress
|
||||||
|
@ -39,6 +42,7 @@ module.exports = class CourseDetailsView extends RootView
|
||||||
context
|
context
|
||||||
|
|
||||||
initData: ->
|
initData: ->
|
||||||
|
@memberSort = 'nameAsc'
|
||||||
mockData = require 'views/courses/mock1/CoursesMockData'
|
mockData = require 'views/courses/mock1/CoursesMockData'
|
||||||
@course = mockData.courses[@courseID]
|
@course = mockData.courses[@courseID]
|
||||||
@currentInstanceIndex = 0
|
@currentInstanceIndex = 0
|
||||||
|
@ -62,6 +66,33 @@ module.exports = class CourseDetailsView extends RootView
|
||||||
lastStartedIndex = lastCompletedIndex + 1
|
lastStartedIndex = lastCompletedIndex + 1
|
||||||
@userLevelStateMap[student][@course.levels[lastStartedIndex]] = 'started'
|
@userLevelStateMap[student][@course.levels[lastStartedIndex]] = 'started'
|
||||||
@maxLastStartedIndex = lastStartedIndex if lastStartedIndex > @maxLastStartedIndex
|
@maxLastStartedIndex = lastStartedIndex if lastStartedIndex > @maxLastStartedIndex
|
||||||
|
@sortMembers()
|
||||||
|
|
||||||
|
sortMembers: ->
|
||||||
|
# Progress sort precedence: most completed concepts, most started concepts, most levels, name sort
|
||||||
|
instance = @instances?[@currentInstanceIndex] ? {}
|
||||||
|
return if _.isEmpty(instance)
|
||||||
|
switch @memberSort
|
||||||
|
when "nameDesc"
|
||||||
|
instance.students.sort (a, b) -> b.localeCompare(a)
|
||||||
|
when "progressAsc"
|
||||||
|
instance.students.sort (a, b) =>
|
||||||
|
for level in @course.levels
|
||||||
|
if @userLevelStateMap[a][level] isnt 'complete' and @userLevelStateMap[b][level] is 'complete'
|
||||||
|
return -1
|
||||||
|
else if @userLevelStateMap[a][level] is 'complete' and @userLevelStateMap[b][level] isnt 'complete'
|
||||||
|
return 1
|
||||||
|
0
|
||||||
|
when "progressDesc"
|
||||||
|
instance.students.sort (a, b) =>
|
||||||
|
for level in @course.levels
|
||||||
|
if @userLevelStateMap[a][level] isnt 'complete' and @userLevelStateMap[b][level] is 'complete'
|
||||||
|
return 1
|
||||||
|
else if @userLevelStateMap[a][level] is 'complete' and @userLevelStateMap[b][level] isnt 'complete'
|
||||||
|
return -1
|
||||||
|
0
|
||||||
|
else
|
||||||
|
instance.students.sort (a, b) -> a.localeCompare(b)
|
||||||
|
|
||||||
onCampaignSync: ->
|
onCampaignSync: ->
|
||||||
return unless @campaigns.loaded
|
return unless @campaigns.loaded
|
||||||
|
@ -101,6 +132,7 @@ module.exports = class CourseDetailsView extends RootView
|
||||||
for val, index in @instances when val.name is newSessionValue
|
for val, index in @instances when val.name is newSessionValue
|
||||||
@currentInstanceIndex = index
|
@currentInstanceIndex = index
|
||||||
@updateLevelMaps()
|
@updateLevelMaps()
|
||||||
|
@onCampaignSync()
|
||||||
@render?()
|
@render?()
|
||||||
|
|
||||||
onExpandedProgressCheckbox: (e) ->
|
onExpandedProgressCheckbox: (e) ->
|
||||||
|
@ -115,6 +147,16 @@ module.exports = class CourseDetailsView extends RootView
|
||||||
onClickEditClassDescription: (e) ->
|
onClickEditClassDescription: (e) ->
|
||||||
alert 'TODO: Popup for editing description for this course session'
|
alert 'TODO: Popup for editing description for this course session'
|
||||||
|
|
||||||
|
onClickMemberHeader: (e) ->
|
||||||
|
@memberSort = if @memberSort is 'nameAsc' then 'nameDesc' else 'nameAsc'
|
||||||
|
@sortMembers()
|
||||||
|
@render?()
|
||||||
|
|
||||||
|
onClickProgressHeader: (e) ->
|
||||||
|
@memberSort = if @memberSort is 'progressAsc' then 'progressDesc' else 'progressAsc'
|
||||||
|
@sortMembers()
|
||||||
|
@render?()
|
||||||
|
|
||||||
onClickPlayLevel: (e) ->
|
onClickPlayLevel: (e) ->
|
||||||
levelName = $(e.target).data('level')
|
levelName = $(e.target).data('level')
|
||||||
levelSlug = @levelNameSlugMap[levelName]
|
levelSlug = @levelNameSlugMap[levelName]
|
||||||
|
|
Reference in a new issue