mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-26 12:50:31 -04:00
Remove progress tab from course details view
This commit is contained in:
parent
52cb638a6c
commit
c610ce6ffd
3 changed files with 33 additions and 488 deletions
app
styles/courses
templates/courses
views/courses
|
@ -1,94 +1,11 @@
|
|||
#course-details-view
|
||||
|
||||
#invite-emails-textarea
|
||||
width: 50%
|
||||
|
||||
.progress-cell
|
||||
padding: 2px
|
||||
padding-bottom: 10px
|
||||
|
||||
.progress-popup-container
|
||||
display: none
|
||||
position: absolute
|
||||
padding: 10px
|
||||
border: 1px solid black
|
||||
z-index: 3
|
||||
background-color: blanchedalmond
|
||||
font-size: 10pt
|
||||
|
||||
.progress-concept-cell
|
||||
display: inline-block
|
||||
white-space: nowrap
|
||||
font-size: 12px
|
||||
line-height: 12px
|
||||
border: 1px solid gray
|
||||
margin: 0px
|
||||
padding: 2px
|
||||
|
||||
.progress-concept-cell-complete
|
||||
background-color: lightgreen
|
||||
|
||||
.progress-concept-cell-started
|
||||
background-color: lightyellow
|
||||
|
||||
.progress-concept-completion-container
|
||||
font-size: 10pt
|
||||
|
||||
.progress-concepts-label
|
||||
color: #317EAC
|
||||
font-size: 12pt
|
||||
.available-courses-title
|
||||
font-size: 20px
|
||||
font-weight: bold
|
||||
margin-top: 8px
|
||||
margin-bottom: 4px
|
||||
margin: 4px
|
||||
|
||||
.progress-concept-summary
|
||||
width: 100%
|
||||
background-color: white
|
||||
cursor: default
|
||||
display: inline-block
|
||||
white-space: nowrap
|
||||
font-size: 9pt
|
||||
font-weight: normal
|
||||
border: 1px solid gray
|
||||
margin: 0px
|
||||
padding: 2px
|
||||
background-color: white
|
||||
|
||||
.progress-concepts-container
|
||||
width: 100%
|
||||
|
||||
.progress-condensed-cell
|
||||
width: 100%
|
||||
|
||||
.progress-header
|
||||
margin-right: 14px
|
||||
cursor: pointer
|
||||
|
||||
.progress-key
|
||||
cursor: default
|
||||
display: inline-block
|
||||
white-space: nowrap
|
||||
font-size: 12px
|
||||
line-height: 12px
|
||||
font-weight: normal
|
||||
border: 1px solid gray
|
||||
margin: 0px
|
||||
padding: 2px
|
||||
|
||||
.progress-key-complete
|
||||
background-color: lightgreen
|
||||
|
||||
.progress-key-started
|
||||
background-color: lightyellow
|
||||
|
||||
.progress-expand-checkbox
|
||||
margin-left: 14px
|
||||
|
||||
.progress-expand-label
|
||||
font-weight: normal
|
||||
font-size: 14px
|
||||
|
||||
.progress-level-cell
|
||||
.concept
|
||||
display: inline-block
|
||||
white-space: nowrap
|
||||
font-size: 12px
|
||||
|
@ -97,50 +14,6 @@
|
|||
margin: 0px
|
||||
padding: 2px
|
||||
|
||||
.progress-level-cell-complete
|
||||
cursor: pointer
|
||||
background-color: lightgreen
|
||||
|
||||
.progress-level-cell-started
|
||||
cursor: pointer
|
||||
background-color: lightyellow
|
||||
|
||||
.progess-levels-label
|
||||
color: #317EAC
|
||||
font-size: 12pt
|
||||
font-weight: bold
|
||||
margin-top: 8px
|
||||
|
||||
.progress-member-cell
|
||||
width: 150px
|
||||
|
||||
.progress-member-header
|
||||
cursor: pointer
|
||||
display: inline-block
|
||||
padding: 2px
|
||||
|
||||
.progress-stats-container
|
||||
font-size: 12pt
|
||||
td
|
||||
padding-right: 8px
|
||||
|
||||
.progress-summary-container
|
||||
font-size: 14pt
|
||||
|
||||
#settingsModal .modal-dialog
|
||||
background-color: white
|
||||
font-size: 14pt
|
||||
|
||||
.settings-description-input
|
||||
width: 100%
|
||||
|
||||
.settings-language-select
|
||||
width: 200px
|
||||
display: inline
|
||||
|
||||
.settings-name-input
|
||||
width: 50%
|
||||
|
||||
.jumbotron
|
||||
form
|
||||
margin-top: -40px
|
||||
|
|
|
@ -115,238 +115,33 @@ block content
|
|||
em COMING SOON
|
||||
p We are hard at work making more courses for you!
|
||||
|
||||
if !me.isAnonymous()
|
||||
div.well.well-sm(role='tabpanel')
|
||||
ul.nav.nav-pills(role='tablist')
|
||||
if view.teacherMode
|
||||
li.active(role='presentation')
|
||||
a(href='#progress', aria-controls='progress', role='tab', data-toggle='tab', data-i18n="courses.progress")
|
||||
li(role='presentation')
|
||||
a(href='#levels', aria-controls='levels', role='tab', data-toggle='tab', data-i18n="nav.play")
|
||||
else
|
||||
li.active(role='presentation')
|
||||
a(href='#levels', aria-controls='levels', role='tab', data-toggle='tab', data-i18n="nav.play")
|
||||
li(role='presentation')
|
||||
a(href='#progress', aria-controls='progress', role='tab', data-toggle='tab', data-i18n="courses.progress")
|
||||
.tab-content
|
||||
if view.teacherMode
|
||||
.tab-pane.active#progress(role='tabpanel')
|
||||
+progress-tab
|
||||
.tab-pane#levels(role='tabpanel')
|
||||
+levels-tab
|
||||
else
|
||||
.tab-pane.active#levels(role='tabpanel')
|
||||
+levels-tab
|
||||
.tab-pane#progress(role='tabpanel')
|
||||
+progress-tab
|
||||
|
||||
mixin progress-tab
|
||||
.container-fluid.progress-summary-container
|
||||
.row
|
||||
.col-md-6
|
||||
+progress-summary-stats
|
||||
.col-md-6
|
||||
+progress-summary-concepts
|
||||
+progress-members
|
||||
|
||||
mixin progress-summary-stats
|
||||
h3(data-i18n="courses.stats")
|
||||
table.progress-stats-container
|
||||
tr
|
||||
td(data-i18n="courses.total_students")
|
||||
td
|
||||
if courseInstance
|
||||
div #{courseInstance.get('members').length}
|
||||
if instanceStats
|
||||
tr
|
||||
td(data-i18n="courses.average_time")
|
||||
if instanceStats.averageLevelPlaytime > 0
|
||||
td= moment.duration(instanceStats.averageLevelPlaytime, "seconds").humanize()
|
||||
else
|
||||
td 0
|
||||
tr
|
||||
td(data-i18n="courses.total_time")
|
||||
if instanceStats.totalPlayTime > 0
|
||||
td= moment.duration(instanceStats.totalPlayTime, "seconds").humanize()
|
||||
else
|
||||
td 0
|
||||
tr
|
||||
td(data-i18n="courses.average_levels")
|
||||
td #{instanceStats.averageLevelsCompleted.toFixed(2)}
|
||||
tr
|
||||
td(data-i18n="courses.total_levels")
|
||||
td= instanceStats.totalLevelsCompleted
|
||||
tr
|
||||
td(data-i18n="courses.furthest_level")
|
||||
td= instanceStats.furthestLevelCompleted.replace('Course: ', '')
|
||||
|
||||
mixin progress-summary-concepts
|
||||
h3(data-i18n="courses.concepts_covered")
|
||||
if course && courseInstance && conceptsCompleted
|
||||
table.progress-concepts-container
|
||||
each concept in course.get('concepts')
|
||||
- var conceptCompletion = Math.round(parseFloat(conceptsCompleted[concept]) / courseInstance.get('members').length * 100)
|
||||
if isNaN(conceptCompletion)
|
||||
- conceptCompletion = 0
|
||||
.available-courses-title Available Levels
|
||||
table.table.table-striped.table-condensed
|
||||
thead
|
||||
tr
|
||||
td.progress-concept-completion-container
|
||||
span.progress-concept-summary(style="width:#{conceptCompletion}%;")
|
||||
span.spr(data-i18n="concepts." + concept)
|
||||
span - #{conceptCompletion}%
|
||||
|
||||
mixin progress-members
|
||||
h3(data-i18n="courses.students")
|
||||
table.table.table-condensed
|
||||
thead
|
||||
tr
|
||||
th
|
||||
span.progress-member-header.spr(data-i18n="clans.name")
|
||||
if memberSort === 'nameAsc'
|
||||
span.progress-member-header.glyphicon.glyphicon-chevron-up
|
||||
else if memberSort === 'nameDesc'
|
||||
span.progress-member-header.glyphicon.glyphicon-chevron-down
|
||||
th
|
||||
span.progress-header.spr(data-i18n="clans.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(data-i18n="clans.complete_1")
|
||||
span.progress-key.progress-key-started(data-i18n="clans.started_1")
|
||||
if showExpandedProgress
|
||||
span.progress-key(data-i18n="clans.not_started_1")
|
||||
input.progress-expand-checkbox(type='checkbox')
|
||||
span.spl.progress-expand-label(data-i18n="courses.expand_details")
|
||||
tbody
|
||||
each memberID in sortedMembers
|
||||
tr
|
||||
td.progress-member-cell
|
||||
+progress-members-individual(memberID)
|
||||
td.progress-cell
|
||||
if showExpandedProgress
|
||||
.progress-concepts-label(data-i18n="courses.concepts")
|
||||
+progress-members-concepts(memberID)
|
||||
.progess-levels-label(data-i18n="nav.play")
|
||||
+progress-members-levels-expanded(memberID)
|
||||
else
|
||||
table
|
||||
tbody
|
||||
tr
|
||||
td.progress-concepts-label(data-i18n="courses.concepts")
|
||||
td.progress-condensed-cell
|
||||
+progress-members-concepts(memberID)
|
||||
tr
|
||||
td.progess-levels-label(data-i18n="nav.play")
|
||||
td.progress-condensed-cell
|
||||
+progress-members-levels-condensed(memberID)
|
||||
|
||||
mixin progress-members-individual(memberID)
|
||||
- var name = memberUserMap[memberID] ? memberUserMap[memberID].get('name') : 'Anoner'
|
||||
strong= name || 'Anoner'
|
||||
if memberStats && memberStats[memberID]
|
||||
div
|
||||
span #{memberStats[memberID].totalLevelsCompleted}
|
||||
span.spl(data-i18n="courses.levels")
|
||||
div
|
||||
span.spr(data-i18n="courses.played")
|
||||
span #{moment.duration(memberStats[memberID].totalPlayTime, "seconds").humanize()}
|
||||
|
||||
mixin progress-members-concepts(memberID)
|
||||
if course && userLevelStateMap[memberID]
|
||||
each concept in course.get('concepts')
|
||||
if userConceptStateMap[memberID][concept] === 'complete'
|
||||
span.spr.progress-concept-cell.progress-concept-cell-complete(data-i18n="concepts." + concept)
|
||||
else if userConceptStateMap[memberID][concept] === 'started'
|
||||
span.spr.progress-concept-cell.progress-concept-cell-started(data-i18n="concepts." + concept)
|
||||
else if showExpandedProgress
|
||||
span.spr.progress-concept-cell.progress-concept-cell-not-started(data-i18n="concepts." + concept)
|
||||
|
||||
mixin progress-members-levels-expanded(memberID)
|
||||
if campaign && userLevelStateMap[memberID]
|
||||
- var i = 0
|
||||
each level, levelID in campaign.get('levels')
|
||||
if userLevelStateMap[memberID][levelID] === 'complete'
|
||||
span.progress-level-cell.progress-level-cell-complete(data-level-id=levelID, data-level-slug=level.slug, data-user-id=memberID) #{i + 1}
|
||||
span.spl= level.name.replace('Course: ', '')
|
||||
+progress-members-popup-completed(i, level, (view.userLevelSessionMap[memberID] || {})[levelID])
|
||||
else if userLevelStateMap[memberID][levelID] === 'started'
|
||||
span.progress-level-cell.progress-level-cell-started(data-level-id=levelID, data-level-slug=level.slug, data-user-id=memberID) #{i + 1} #{level.name.replace('Course: ', '')}
|
||||
+progress-members-popup-started(i, level, (view.userLevelSessionMap[memberID] || {})[levelID])
|
||||
else
|
||||
span.progress-level-cell #{i + 1} #{level.name.replace('Course: ', '')}
|
||||
- i++
|
||||
|
||||
mixin progress-members-levels-condensed(memberID)
|
||||
if campaign && userLevelStateMap[memberID]
|
||||
- var numLevels = Object.keys(campaign.get('levels')).length
|
||||
- var levelCellWidth = 100.00
|
||||
if numLevels > 0
|
||||
levelCellWidth = 100.00 / numLevels
|
||||
- var i = 0
|
||||
each level, levelID in campaign.get('levels')
|
||||
if userLevelStateMap[memberID][levelID] === 'complete'
|
||||
span.progress-level-cell.progress-level-cell-complete(style="width:#{levelCellWidth}%;", data-level-id=levelID, data-level-slug=level.slug, data-user-id=memberID) #{i + 1}
|
||||
+progress-members-popup-completed(i, level, (view.userLevelSessionMap[memberID] || {})[levelID])
|
||||
else if userLevelStateMap[memberID][levelID] === 'started'
|
||||
span.progress-level-cell.progress-level-cell-started(style="width:#{levelCellWidth}%;", data-level-id=levelID, data-level-slug=level.slug, data-user-id=memberID) #{i + 1}
|
||||
+progress-members-popup-started(i, level, (view.userLevelSessionMap[memberID] || {})[levelID])
|
||||
else
|
||||
break
|
||||
- i++
|
||||
|
||||
mixin progress-members-popup-completed(i, level, session)
|
||||
.progress-popup-container
|
||||
h3 #{i + 1}. #{level.name.replace('Course: ', '')}
|
||||
p
|
||||
span.spr(data-i18n="courses.play_time")
|
||||
span #{moment.duration(session.get('playtime'), "seconds").humanize()}
|
||||
p
|
||||
span.spr(data-i18n="courses.completed")
|
||||
span #{moment(session.get('changed')).format('MMMM Do YYYY, h:mm:ss a')}
|
||||
if view.teacherMode || me.isAdmin()
|
||||
strong(data-i18n="clans.view_solution")
|
||||
|
||||
mixin progress-members-popup-started(i, level, session)
|
||||
.progress-popup-container
|
||||
h3 #{i + 1}. #{level.name.replace('Course: ', '')}
|
||||
p
|
||||
span.spr(data-i18n="courses.play_time")
|
||||
span #{moment.duration(session.get('playtime'), "seconds").humanize()}
|
||||
p
|
||||
span.spr(data-i18n="clans.last_played")
|
||||
span #{moment(session.get('changed')).format('MMMM Do YYYY, h:mm:ss a')}
|
||||
if view.teacherMode || me.isAdmin()
|
||||
strong(data-i18n="clans.view_attempt")
|
||||
|
||||
mixin levels-tab
|
||||
table.table.table-striped.table-condensed
|
||||
thead
|
||||
tr
|
||||
th
|
||||
th(data-i18n="clans.status")
|
||||
th(data-i18n="resources.level")
|
||||
th(data-i18n="courses.concepts")
|
||||
tbody
|
||||
if campaign
|
||||
- var lastLevelCompleted = true;
|
||||
- var levelCount = 0;
|
||||
each level, levelID in campaign.get('levels')
|
||||
tr
|
||||
td
|
||||
if lastLevelCompleted || view.teacherMode
|
||||
- var i18n = level.type === 'course-ladder' ? 'play.compete' : 'home.play';
|
||||
button.btn.btn-success.btn-play-level(data-level-slug=level.slug, data-i18n=i18n, data-level-id=levelID)
|
||||
td
|
||||
if userLevelStateMap[me.id]
|
||||
div= userLevelStateMap[me.id][levelID]
|
||||
- lastLevelCompleted = userLevelStateMap[me.id][levelID] === 'complete'
|
||||
else
|
||||
- lastLevelCompleted = false
|
||||
td= ++levelCount + '. ' + level.name.replace('Course: ', '')
|
||||
td
|
||||
if levelConceptMap[levelID]
|
||||
each concept in course.get('concepts')
|
||||
if levelConceptMap[levelID][concept]
|
||||
span.spr.progress-level-cell.progress-level-cell-not-started(data-i18n="concepts." + concept)
|
||||
th
|
||||
th(data-i18n="clans.status")
|
||||
th(data-i18n="resources.level")
|
||||
th(data-i18n="courses.concepts")
|
||||
tbody
|
||||
if campaign
|
||||
- var lastLevelCompleted = true;
|
||||
- var levelCount = 0;
|
||||
each level, levelID in campaign.get('levels')
|
||||
tr
|
||||
td
|
||||
if lastLevelCompleted || view.teacherMode
|
||||
- var i18n = level.type === 'course-ladder' ? 'play.compete' : 'home.play';
|
||||
button.btn.btn-success.btn-play-level(data-level-slug=level.slug, data-i18n=i18n, data-level-id=levelID)
|
||||
td
|
||||
if userLevelStateMap[me.id]
|
||||
div= userLevelStateMap[me.id][levelID]
|
||||
- lastLevelCompleted = userLevelStateMap[me.id][levelID] === 'complete'
|
||||
else
|
||||
- lastLevelCompleted = false
|
||||
td= ++levelCount + '. ' + level.name.replace('Course: ', '')
|
||||
td
|
||||
if levelConceptMap[levelID]
|
||||
each concept in course.get('concepts')
|
||||
if levelConceptMap[levelID][concept]
|
||||
span.spr.concept(data-i18n="concepts." + concept)
|
||||
|
|
|
@ -7,8 +7,6 @@ LevelSession = require 'models/LevelSession'
|
|||
RootView = require 'views/core/RootView'
|
||||
template = require 'templates/courses/course-details'
|
||||
User = require 'models/User'
|
||||
utils = require 'core/utils'
|
||||
Prepaid = require 'models/Prepaid'
|
||||
storage = require 'core/storage'
|
||||
|
||||
autoplayedOnce = false
|
||||
|
@ -21,14 +19,8 @@ module.exports = class CourseDetailsView extends RootView
|
|||
memberSort: 'nameAsc'
|
||||
|
||||
events:
|
||||
'change .progress-expand-checkbox': 'onCheckExpandedProgress'
|
||||
'click .btn-play-level': 'onClickPlayLevel'
|
||||
'click .btn-select-instance': 'onClickSelectInstance'
|
||||
'click .progress-member-header': 'onClickMemberHeader'
|
||||
'click .progress-header': 'onClickProgressHeader'
|
||||
'click .progress-level-cell': 'onClickProgressLevelCell'
|
||||
'mouseenter .progress-level-cell': 'onMouseEnterPoint'
|
||||
'mouseleave .progress-level-cell': 'onMouseLeavePoint'
|
||||
'submit #school-form': 'onSubmitSchoolForm'
|
||||
|
||||
constructor: (options, @courseID, @courseInstanceID) ->
|
||||
|
@ -38,7 +30,6 @@ module.exports = class CourseDetailsView extends RootView
|
|||
@classroom = new Classroom()
|
||||
@course = @supermodel.getModel(Course, @courseID) or new Course _id: @courseID
|
||||
@listenTo @course, 'sync', @onCourseSync
|
||||
@prepaid = new Prepaid()
|
||||
if @course.loaded
|
||||
@onCourseSync()
|
||||
else
|
||||
|
@ -47,23 +38,13 @@ module.exports = class CourseDetailsView extends RootView
|
|||
getRenderData: ->
|
||||
context = super()
|
||||
context.campaign = @campaign
|
||||
context.conceptsCompleted = @conceptsCompleted ? {}
|
||||
context.course = @course if @course?.loaded
|
||||
context.courseInstance = @courseInstance if @courseInstance?.loaded
|
||||
context.courseInstances = @courseInstances?.models ? []
|
||||
context.instanceStats = @instanceStats
|
||||
context.levelConceptMap = @levelConceptMap ? {}
|
||||
context.memberSort = @memberSort
|
||||
context.memberStats = @memberStats
|
||||
context.memberUserMap = @memberUserMap ? {}
|
||||
context.noCourseInstance = @noCourseInstance
|
||||
context.noCourseInstanceSelected = @noCourseInstanceSelected
|
||||
context.pricePerSeat = @course.get('pricePerSeat')
|
||||
context.showExpandedProgress = @showExpandedProgress
|
||||
context.sortedMembers = @sortedMembers ? []
|
||||
context.userConceptStateMap = @userConceptStateMap ? {}
|
||||
context.userLevelStateMap = @userLevelStateMap ? {}
|
||||
context.document = document
|
||||
context.promptForSchool = @courseComplete and not me.isAnonymous() and not me.get('schoolName') and not storage.load('no-school')
|
||||
context
|
||||
|
||||
|
@ -155,23 +136,8 @@ module.exports = class CourseDetailsView extends RootView
|
|||
@levelSessions = new CocoCollection([], { url: "/db/course_instance/#{@courseInstance.id}/level_sessions", model: LevelSession, comparator: '_id' })
|
||||
@listenToOnce @levelSessions, 'sync', @onLevelSessionsSync
|
||||
@supermodel.loadCollection @levelSessions, 'level_sessions', cache: false
|
||||
@members = new CocoCollection([], { url: "/db/course_instance/#{@courseInstance.id}/members", model: User, comparator: 'nameLower' })
|
||||
@listenToOnce @members, 'sync', @onMembersSync
|
||||
@supermodel.loadCollection @members, 'members', cache: false
|
||||
@owner = new User({_id: @courseInstance.get('ownerID')})
|
||||
@supermodel.loadModel @owner, 'user'
|
||||
if @teacherMode and prepaidID = @courseInstance.get('prepaidID')
|
||||
@prepaid = @supermodel.getModel(Prepaid, prepaidID) or new Prepaid _id: prepaidID
|
||||
@listenTo @prepaid, 'sync', @onPrepaidSync
|
||||
if @prepaid.loaded
|
||||
@onPrepaidSync()
|
||||
else
|
||||
@supermodel.loadModel @prepaid, 'prepaid'
|
||||
@render()
|
||||
|
||||
onPrepaidSync: ->
|
||||
return if @destroyed
|
||||
# TODO: why do we rerender here? Template doesn't use prepaid.
|
||||
@render()
|
||||
|
||||
onLevelSessionsSync: ->
|
||||
|
@ -180,7 +146,6 @@ module.exports = class CourseDetailsView extends RootView
|
|||
@instanceStats = averageLevelsCompleted: 0, furthestLevelCompleted: '', totalLevelsCompleted: 0, totalPlayTime: 0
|
||||
@memberStats = {}
|
||||
@userConceptStateMap = {}
|
||||
@userLevelSessionMap = {}
|
||||
@userLevelStateMap = {}
|
||||
levelStateMap = {}
|
||||
for levelSession in @levelSessions.models
|
||||
|
@ -211,9 +176,6 @@ module.exports = class CourseDetailsView extends RootView
|
|||
for concept of @levelConceptMap[levelID]
|
||||
@userConceptStateMap[userID][concept] = state
|
||||
|
||||
@userLevelSessionMap[userID] ?= {}
|
||||
@userLevelSessionMap[userID][levelID] = levelSession
|
||||
|
||||
@userLevelStateMap[userID] ?= {}
|
||||
@userLevelStateMap[userID][levelID] = state
|
||||
|
||||
|
@ -240,15 +202,6 @@ module.exports = class CourseDetailsView extends RootView
|
|||
autoplayedOnce = true
|
||||
@$el.find('button.btn-play-level').click()
|
||||
|
||||
onMembersSync: ->
|
||||
return if @destroyed
|
||||
# console.log 'onMembersSync'
|
||||
@memberUserMap = {}
|
||||
for user in @members.models
|
||||
@memberUserMap[user.id] = user
|
||||
@sortMembers()
|
||||
@render()
|
||||
|
||||
onAllCoursesSync: ->
|
||||
@findNextCourseInstance()
|
||||
|
||||
|
@ -265,22 +218,6 @@ module.exports = class CourseDetailsView extends RootView
|
|||
else
|
||||
@loadAllCourses()
|
||||
|
||||
onCheckExpandedProgress: (e) ->
|
||||
@showExpandedProgress = $('.progress-expand-checkbox').prop('checked')
|
||||
# TODO: why does render reset the checkbox to be unchecked?
|
||||
@render()
|
||||
$('.progress-expand-checkbox').attr('checked', @showExpandedProgress)
|
||||
|
||||
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) ->
|
||||
levelSlug = $(e.target).data('level-slug')
|
||||
levelID = $(e.target).data('level-id')
|
||||
|
@ -306,66 +243,6 @@ module.exports = class CourseDetailsView extends RootView
|
|||
@noCourseInstanceSelected = false
|
||||
@loadCourseInstance(courseInstanceID)
|
||||
|
||||
onClickProgressLevelCell: (e) ->
|
||||
return unless @teacherMode or me.isAdmin()
|
||||
levelID = $(e.currentTarget).data('level-id')
|
||||
levelSlug = $(e.currentTarget).data('level-slug')
|
||||
userID = $(e.currentTarget).data('user-id')
|
||||
return unless levelID and levelSlug and userID
|
||||
route = @getLevelURL levelSlug
|
||||
if @userLevelSessionMap[userID]?[levelID]
|
||||
route += "&session=#{@userLevelSessionMap[userID][levelID].id}&observing=true"
|
||||
Backbone.Mediator.publish 'router:navigate', {
|
||||
route: route
|
||||
viewClass: 'views/play/level/PlayLevelView'
|
||||
viewArgs: [{supermodel: @supermodel}, levelSlug]
|
||||
}
|
||||
|
||||
onMouseEnterPoint: (e) ->
|
||||
$('.progress-popup-container').hide()
|
||||
container = $(e.target).find('.progress-popup-container').show()
|
||||
margin = 20
|
||||
offset = $(e.target).offset()
|
||||
scrollTop = $('#page-container').scrollTop()
|
||||
height = container.outerHeight()
|
||||
container.css('left', offset.left + e.offsetX)
|
||||
container.css('top', offset.top + scrollTop - height - margin)
|
||||
|
||||
onMouseLeavePoint: (e) ->
|
||||
$(e.target).find('.progress-popup-container').hide()
|
||||
|
||||
sortMembers: ->
|
||||
# Progress sort precedence: most completed concepts, most started concepts, most levels, name sort
|
||||
return unless @campaign and @courseInstance and @memberUserMap
|
||||
@sortedMembers = @courseInstance.get('members')
|
||||
switch @memberSort
|
||||
when "nameDesc"
|
||||
@sortedMembers.sort (a, b) =>
|
||||
aName = @memberUserMap[a]?.get('name') ? 'Anoner'
|
||||
bName = @memberUserMap[b]?.get('name') ? 'Anoner'
|
||||
bName.localeCompare(aName)
|
||||
when "progressAsc"
|
||||
@sortedMembers.sort (a, b) =>
|
||||
for levelID, level of @campaign.get('levels')
|
||||
if @userLevelStateMap[a]?[levelID] isnt 'complete' and @userLevelStateMap[b]?[levelID] is 'complete'
|
||||
return -1
|
||||
else if @userLevelStateMap[a]?[levelID] is 'complete' and @userLevelStateMap[b]?[levelID] isnt 'complete'
|
||||
return 1
|
||||
0
|
||||
when "progressDesc"
|
||||
@sortedMembers.sort (a, b) =>
|
||||
for levelID, level of @campaign.get('levels')
|
||||
if @userLevelStateMap[a]?[levelID] isnt 'complete' and @userLevelStateMap[b]?[levelID] is 'complete'
|
||||
return 1
|
||||
else if @userLevelStateMap[a]?[levelID] is 'complete' and @userLevelStateMap[b]?[levelID] isnt 'complete'
|
||||
return -1
|
||||
0
|
||||
else
|
||||
@sortedMembers.sort (a, b) =>
|
||||
aName = @memberUserMap[a]?.get('name') ? 'Anoner'
|
||||
bName = @memberUserMap[b]?.get('name') ? 'Anoner'
|
||||
aName.localeCompare(bName)
|
||||
|
||||
getOwnerName: ->
|
||||
return if @owner.isNew()
|
||||
if @owner.get('firstName') and @owner.get('lastName')
|
||||
|
|
Loading…
Add table
Reference in a new issue