Add member sorting to premium clan dashboard

This commit is contained in:
Matt Lott 2015-07-02 15:17:31 -07:00
parent 8a4645ebc6
commit 6a53237e65
3 changed files with 63 additions and 6 deletions

View file

@ -55,8 +55,11 @@
vertical-align: middle
.member-header
cursor: pointer
.progress-header
margin-right: 14px
cursor: pointer
.progress-key
cursor: default
@ -74,6 +77,7 @@
.progress-key-complete
background-color: lightgray
margin-left: 14px
.expand-progress-checkbox
margin-left: 14px

View file

@ -83,10 +83,21 @@ block content
table.table.table-condensed
thead
tr
th(data-i18n="resources.hero") Hero
th
span.progress-header(data-i18n="clans.progress") Progress
span.progress-key.progress-key-complete(data-i18n="clans.complete_1") complete
span.member-header.spr(data-i18n="resources.hero") Hero
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(data-i18n="clans.not_started_1") not started
input.expand-progress-checkbox(type='checkbox')

View file

@ -27,6 +27,8 @@ module.exports = class ClanDetailsView extends RootView
'click .edit-name-save-btn': 'onEditNameSave'
'click .join-clan-btn': 'onJoinClan'
'click .leave-clan-btn': 'onLeaveClan'
'click .member-header': 'onClickMemberHeader'
'click .progress-header': 'onClickProgressHeader'
'click .progress-level-cell': 'onClickLevel'
'click .remove-member-btn': 'onRemoveMember'
'mouseenter .progress-level-cell': 'onMouseEnterPoint'
@ -41,6 +43,7 @@ module.exports = class ClanDetailsView extends RootView
initData: ->
@showExpandedProgress = false
@memberSort = 'nameAsc'
@stats = {}
@campaigns = new CocoCollection([], { url: "/db/campaign", model: Campaign, comparator:'_id' })
@ -77,22 +80,25 @@ module.exports = class ClanDetailsView extends RootView
context.memberLanguageMap = @memberLanguageMap
context.memberLevelStateMap = @memberLevelMap ? {}
context.memberMaxLevelCount = @memberMaxLevelCount
context.members = @members?.models
context.memberSort = @memberSort
context.isOwner = @clan.get('ownerID') is me.id
context.isMember = @clanID in (me.get('clans') ? [])
context.stats = @stats
# Find last campaign level for each user
# TODO: why do we do this for every render?
highestUserLevelCountMap = {}
lastUserCampaignLevelMap = {}
maxLastUserCampaignLevel = 0
userConceptsMap = {}
if @campaigns.loaded
levelCount = 0
for campaign in @campaigns.models
campaignID = campaign.id
lastLevelIndex = 0
for levelID, level of campaign.get('levels')
levelSlug = level.slug
for member in context.members
for member in @members?.models ? []
if context.memberLevelStateMap[member.id]?[levelSlug]
lastUserCampaignLevelMap[member.id] ?= {}
lastUserCampaignLevelMap[member.id][campaignID] ?= {}
@ -105,8 +111,12 @@ module.exports = class ClanDetailsView extends RootView
for concept in level.concepts
continue if userConceptsMap[member.id][concept] is 'complete'
userConceptsMap[member.id][concept] = context.memberLevelStateMap[member.id][levelSlug].state
highestUserLevelCountMap[member.id] = levelCount
lastLevelIndex++
levelCount++
@sortMembers(highestUserLevelCountMap, userConceptsMap) if @clan.get('dashboardType') is 'premium'
context.members = @members?.models ? []
context.lastUserCampaignLevelMap = lastUserCampaignLevelMap
context.showExpandedProgress = maxLastUserCampaignLevel <= 30 or @showExpandedProgress
context.userConceptsMap = userConceptsMap
@ -122,6 +132,30 @@ module.exports = class ClanDetailsView extends RootView
@memberAchievements.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: ->
return unless @members?.models?
for member in @members.models
@ -284,6 +318,14 @@ module.exports = class ClanDetailsView extends RootView
success: (model, response, options) => @refreshData()
@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) ->
return unless window.confirm("Remove Hero?")
if memberID = $(e.target).data('id')