mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-23 23:58:02 -05:00
Add member sorting to premium clan dashboard
This commit is contained in:
parent
8a4645ebc6
commit
6a53237e65
3 changed files with 63 additions and 6 deletions
|
@ -55,8 +55,11 @@
|
||||||
vertical-align: middle
|
vertical-align: middle
|
||||||
|
|
||||||
|
|
||||||
|
.member-header
|
||||||
|
cursor: pointer
|
||||||
|
|
||||||
.progress-header
|
.progress-header
|
||||||
margin-right: 14px
|
cursor: pointer
|
||||||
|
|
||||||
.progress-key
|
.progress-key
|
||||||
cursor: default
|
cursor: default
|
||||||
|
@ -74,6 +77,7 @@
|
||||||
|
|
||||||
.progress-key-complete
|
.progress-key-complete
|
||||||
background-color: lightgray
|
background-color: lightgray
|
||||||
|
margin-left: 14px
|
||||||
|
|
||||||
.expand-progress-checkbox
|
.expand-progress-checkbox
|
||||||
margin-left: 14px
|
margin-left: 14px
|
||||||
|
|
|
@ -83,10 +83,21 @@ block content
|
||||||
table.table.table-condensed
|
table.table.table-condensed
|
||||||
thead
|
thead
|
||||||
tr
|
tr
|
||||||
th(data-i18n="resources.hero") Hero
|
|
||||||
th
|
th
|
||||||
span.progress-header(data-i18n="clans.progress") Progress
|
span.member-header.spr(data-i18n="resources.hero") Hero
|
||||||
span.progress-key.progress-key-complete(data-i18n="clans.complete_1") complete
|
if memberSort === 'nameAsc'
|
||||||
|
span.member-header.glyphicon.glyphicon-chevron-up
|
||||||
|
else if memberSort === 'nameDesc'
|
||||||
|
span.member-header.glyphicon.glyphicon-chevron-down
|
||||||
|
th
|
||||||
|
span.progress-header.spr(data-i18n="clans.progress") 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.spl.progress-key.progress-key-complete(data-i18n="clans.complete_1") complete
|
||||||
span.progress-key.progress-key-started(data-i18n="clans.started_1") started
|
span.progress-key.progress-key-started(data-i18n="clans.started_1") started
|
||||||
span.progress-key(data-i18n="clans.not_started_1") not started
|
span.progress-key(data-i18n="clans.not_started_1") not started
|
||||||
input.expand-progress-checkbox(type='checkbox')
|
input.expand-progress-checkbox(type='checkbox')
|
||||||
|
|
|
@ -27,6 +27,8 @@ module.exports = class ClanDetailsView extends RootView
|
||||||
'click .edit-name-save-btn': 'onEditNameSave'
|
'click .edit-name-save-btn': 'onEditNameSave'
|
||||||
'click .join-clan-btn': 'onJoinClan'
|
'click .join-clan-btn': 'onJoinClan'
|
||||||
'click .leave-clan-btn': 'onLeaveClan'
|
'click .leave-clan-btn': 'onLeaveClan'
|
||||||
|
'click .member-header': 'onClickMemberHeader'
|
||||||
|
'click .progress-header': 'onClickProgressHeader'
|
||||||
'click .progress-level-cell': 'onClickLevel'
|
'click .progress-level-cell': 'onClickLevel'
|
||||||
'click .remove-member-btn': 'onRemoveMember'
|
'click .remove-member-btn': 'onRemoveMember'
|
||||||
'mouseenter .progress-level-cell': 'onMouseEnterPoint'
|
'mouseenter .progress-level-cell': 'onMouseEnterPoint'
|
||||||
|
@ -41,6 +43,7 @@ module.exports = class ClanDetailsView extends RootView
|
||||||
|
|
||||||
initData: ->
|
initData: ->
|
||||||
@showExpandedProgress = false
|
@showExpandedProgress = false
|
||||||
|
@memberSort = 'nameAsc'
|
||||||
@stats = {}
|
@stats = {}
|
||||||
|
|
||||||
@campaigns = new CocoCollection([], { url: "/db/campaign", model: Campaign, comparator:'_id' })
|
@campaigns = new CocoCollection([], { url: "/db/campaign", model: Campaign, comparator:'_id' })
|
||||||
|
@ -77,22 +80,25 @@ module.exports = class ClanDetailsView extends RootView
|
||||||
context.memberLanguageMap = @memberLanguageMap
|
context.memberLanguageMap = @memberLanguageMap
|
||||||
context.memberLevelStateMap = @memberLevelMap ? {}
|
context.memberLevelStateMap = @memberLevelMap ? {}
|
||||||
context.memberMaxLevelCount = @memberMaxLevelCount
|
context.memberMaxLevelCount = @memberMaxLevelCount
|
||||||
context.members = @members?.models
|
context.memberSort = @memberSort
|
||||||
context.isOwner = @clan.get('ownerID') is me.id
|
context.isOwner = @clan.get('ownerID') is me.id
|
||||||
context.isMember = @clanID in (me.get('clans') ? [])
|
context.isMember = @clanID in (me.get('clans') ? [])
|
||||||
context.stats = @stats
|
context.stats = @stats
|
||||||
|
|
||||||
# Find last campaign level for each user
|
# Find last campaign level for each user
|
||||||
|
# TODO: why do we do this for every render?
|
||||||
|
highestUserLevelCountMap = {}
|
||||||
lastUserCampaignLevelMap = {}
|
lastUserCampaignLevelMap = {}
|
||||||
maxLastUserCampaignLevel = 0
|
maxLastUserCampaignLevel = 0
|
||||||
userConceptsMap = {}
|
userConceptsMap = {}
|
||||||
if @campaigns.loaded
|
if @campaigns.loaded
|
||||||
|
levelCount = 0
|
||||||
for campaign in @campaigns.models
|
for campaign in @campaigns.models
|
||||||
campaignID = campaign.id
|
campaignID = campaign.id
|
||||||
lastLevelIndex = 0
|
lastLevelIndex = 0
|
||||||
for levelID, level of campaign.get('levels')
|
for levelID, level of campaign.get('levels')
|
||||||
levelSlug = level.slug
|
levelSlug = level.slug
|
||||||
for member in context.members
|
for member in @members?.models ? []
|
||||||
if context.memberLevelStateMap[member.id]?[levelSlug]
|
if context.memberLevelStateMap[member.id]?[levelSlug]
|
||||||
lastUserCampaignLevelMap[member.id] ?= {}
|
lastUserCampaignLevelMap[member.id] ?= {}
|
||||||
lastUserCampaignLevelMap[member.id][campaignID] ?= {}
|
lastUserCampaignLevelMap[member.id][campaignID] ?= {}
|
||||||
|
@ -105,8 +111,12 @@ module.exports = class ClanDetailsView extends RootView
|
||||||
for concept in level.concepts
|
for concept in level.concepts
|
||||||
continue if userConceptsMap[member.id][concept] is 'complete'
|
continue if userConceptsMap[member.id][concept] is 'complete'
|
||||||
userConceptsMap[member.id][concept] = context.memberLevelStateMap[member.id][levelSlug].state
|
userConceptsMap[member.id][concept] = context.memberLevelStateMap[member.id][levelSlug].state
|
||||||
|
highestUserLevelCountMap[member.id] = levelCount
|
||||||
lastLevelIndex++
|
lastLevelIndex++
|
||||||
|
levelCount++
|
||||||
|
|
||||||
|
@sortMembers(highestUserLevelCountMap, userConceptsMap) if @clan.get('dashboardType') is 'premium'
|
||||||
|
context.members = @members?.models ? []
|
||||||
context.lastUserCampaignLevelMap = lastUserCampaignLevelMap
|
context.lastUserCampaignLevelMap = lastUserCampaignLevelMap
|
||||||
context.showExpandedProgress = maxLastUserCampaignLevel <= 30 or @showExpandedProgress
|
context.showExpandedProgress = maxLastUserCampaignLevel <= 30 or @showExpandedProgress
|
||||||
context.userConceptsMap = userConceptsMap
|
context.userConceptsMap = userConceptsMap
|
||||||
|
@ -122,6 +132,30 @@ module.exports = class ClanDetailsView extends RootView
|
||||||
@memberAchievements.fetch cache: false
|
@memberAchievements.fetch cache: false
|
||||||
@memberSessions.fetch cache: false
|
@memberSessions.fetch cache: false
|
||||||
|
|
||||||
|
sortMembers: (highestUserLevelCountMap, userConceptsMap) ->
|
||||||
|
# Progress sort precedence: most concepts, most levels, name sort
|
||||||
|
return unless @members? and @memberSort?
|
||||||
|
switch @memberSort
|
||||||
|
when "nameDesc"
|
||||||
|
@members.comparator = (a, b) -> return (b.get('name') or 'Anoner').localeCompare(a.get('name') or 'Anoner')
|
||||||
|
when "progressAsc"
|
||||||
|
@members.comparator = (a, b) ->
|
||||||
|
if Object.keys(userConceptsMap[a.id]).length < Object.keys(userConceptsMap[b.id]).length then return -1
|
||||||
|
else if Object.keys(userConceptsMap[a.id]).length > Object.keys(userConceptsMap[b.id]).length then return 1
|
||||||
|
if highestUserLevelCountMap[a.id] < highestUserLevelCountMap[b.id] then return -1
|
||||||
|
else if highestUserLevelCountMap[a.id] > highestUserLevelCountMap[b.id] then return 1
|
||||||
|
(a.get('name') or 'Anoner').localeCompare(b.get('name') or 'Anoner')
|
||||||
|
when "progressDesc"
|
||||||
|
@members.comparator = (a, b) ->
|
||||||
|
if Object.keys(userConceptsMap[a.id]).length > Object.keys(userConceptsMap[b.id]).length then return -1
|
||||||
|
else if Object.keys(userConceptsMap[a.id]).length < Object.keys(userConceptsMap[b.id]).length then return 1
|
||||||
|
if highestUserLevelCountMap[a.id] > highestUserLevelCountMap[b.id] then return -1
|
||||||
|
else if highestUserLevelCountMap[a.id] < highestUserLevelCountMap[b.id] then return 1
|
||||||
|
(b.get('name') or 'Anoner').localeCompare(a.get('name') or 'Anoner')
|
||||||
|
else
|
||||||
|
@members.comparator = (a, b) -> return (a.get('name') or 'Anoner').localeCompare(b.get('name') or 'Anoner')
|
||||||
|
@members.sort()
|
||||||
|
|
||||||
updateHeroIcons: ->
|
updateHeroIcons: ->
|
||||||
return unless @members?.models?
|
return unless @members?.models?
|
||||||
for member in @members.models
|
for member in @members.models
|
||||||
|
@ -284,6 +318,14 @@ module.exports = class ClanDetailsView extends RootView
|
||||||
success: (model, response, options) => @refreshData()
|
success: (model, response, options) => @refreshData()
|
||||||
@supermodel.addRequestResource( 'leave_clan', options).load()
|
@supermodel.addRequestResource( 'leave_clan', options).load()
|
||||||
|
|
||||||
|
onClickMemberHeader: (e) ->
|
||||||
|
@memberSort = if @memberSort is 'nameAsc' then 'nameDesc' else 'nameAsc'
|
||||||
|
@render?()
|
||||||
|
|
||||||
|
onClickProgressHeader: (e) ->
|
||||||
|
@memberSort = if @memberSort is 'progressAsc' then 'progressDesc' else 'progressAsc'
|
||||||
|
@render?()
|
||||||
|
|
||||||
onRemoveMember: (e) ->
|
onRemoveMember: (e) ->
|
||||||
return unless window.confirm("Remove Hero?")
|
return unless window.confirm("Remove Hero?")
|
||||||
if memberID = $(e.target).data('id')
|
if memberID = $(e.target).data('id')
|
||||||
|
|
Loading…
Reference in a new issue