Sort and limit clan lists

Clan lists sorted by member count, then created date.
Public clans lists limited to 100.
Member lists sorted by slug.
This commit is contained in:
Matt Lott 2015-04-03 12:22:44 -07:00
parent dfff871c58
commit 39990ee151
7 changed files with 26 additions and 14 deletions

View file

@ -4,7 +4,6 @@ ClanSchema = c.object {title: 'Clan', required: ['name', 'type']}
c.extendNamedProperties ClanSchema # name first c.extendNamedProperties ClanSchema # name first
_.extend ClanSchema.properties, _.extend ClanSchema.properties,
name: c.shortString()
type: {type: 'string', 'enum': ['public']} type: {type: 'string', 'enum': ['public']}
ownerID: c.objectId() ownerID: c.objectId()
members: c.array {title: 'Members'}, c.objectId() members: c.array {title: 'Members'}, c.objectId()

View file

@ -42,5 +42,3 @@ block content
td td
if isOwner && member.id !== clan.get('ownerID') if isOwner && member.id !== clan.get('ownerID')
button.btn.btn-sm.btn-warning.remove-member-btn(data-id="#{member.id}") Remove Member button.btn.btn-sm.btn-warning.remove-member-btn(data-id="#{member.id}") Remove Member
button.btn.btn-sm Load More

View file

@ -45,8 +45,6 @@ block content
else if clan.get('ownerID') !== me.id else if clan.get('ownerID') !== me.id
button.btn.btn-sm.btn-warning.leave-clan-btn(data-id="#{clan.id}") Leave Clan button.btn.btn-sm.btn-warning.leave-clan-btn(data-id="#{clan.id}") Leave Clan
button.btn.btn-sm Load More
.tab-pane#my-clans(role='tabpanel') .tab-pane#my-clans(role='tabpanel')
table.table.table-striped.table-condensed table.table.table-striped.table-condensed
thead thead
@ -73,5 +71,3 @@ block content
td td
if clan.get('ownerID') !== me.id if clan.get('ownerID') !== me.id
button.btn.btn-sm.btn-warning.leave-clan-btn(data-id="#{clan.id}") Leave Clan button.btn.btn-sm.btn-warning.leave-clan-btn(data-id="#{clan.id}") Leave Clan
button.btn.btn-sm Load More

View file

@ -49,7 +49,7 @@ module.exports = class ClanDetailsView extends RootView
@supermodel.loadModel @owner, 'owner', cache: false @supermodel.loadModel @owner, 'owner', cache: false
@supermodel.loadModel @clan, 'clan', cache: false @supermodel.loadModel @clan, 'clan', cache: false
@members = new CocoCollection([], { url: "/db/clan/#{@clanID}/members", model: User, comparator:'_id' }) @members = new CocoCollection([], { url: "/db/clan/#{@clanID}/members", model: User, comparator:'slug' })
@listenTo @members, 'sync', => @listenTo @members, 'sync', =>
@stats.averageLevel = Math.round(@members.reduce(((sum, member) -> sum + member.level()), 0) / @members.length) @stats.averageLevel = Math.round(@members.reduce(((sum, member) -> sum + member.level()), 0) / @members.length)
@render?() @render?()

View file

@ -35,12 +35,20 @@ module.exports = class MainAdminView extends RootView
initData: -> initData: ->
@idNameMap = {} @idNameMap = {}
@publicClans = new CocoCollection([], { url: '/db/clan', model: Clan, comparator:'_id' })
sortClanList = (a, b) ->
if a.get('members').length isnt b.get('members').length
a.get('members').length < b.get('members').length
else
b.id.localeCompare(a.id)
@publicClans = new CocoCollection([], { url: '/db/clan/-/public', model: Clan, comparator: sortClanList })
@listenTo @publicClans, 'sync', => @listenTo @publicClans, 'sync', =>
for clan in @publicClans.models
console.log clan.get('name')
@refreshNames @publicClans.models @refreshNames @publicClans.models
@render?() @render?()
@supermodel.loadCollection(@publicClans, 'public_clans', {cache: false}) @supermodel.loadCollection(@publicClans, 'public_clans', {cache: false})
@myClans = new CocoCollection([], { url: '/db/user/-/clans', model: Clan, comparator:'_id' }) @myClans = new CocoCollection([], { url: '/db/user/-/clans', model: Clan, comparator: sortClanList })
@listenTo @myClans, 'sync', => @listenTo @myClans, 'sync', =>
@refreshNames @myClans.models @refreshNames @myClans.models
@render?() @render?()

View file

@ -47,6 +47,7 @@ ClanHandler = class ClanHandler extends Handler
return @leaveClan(req, res, args[0]) if args[1] is 'leave' return @leaveClan(req, res, args[0]) if args[1] is 'leave'
return @getMemberAchievements(req, res, args[0]) if args[1] is 'member_achievements' return @getMemberAchievements(req, res, args[0]) if args[1] is 'member_achievements'
return @getMembers(req, res, args[0]) if args[1] is 'members' return @getMembers(req, res, args[0]) if args[1] is 'members'
return @getPublicClans(req, res) if args[1] is 'public'
return @removeMember(req, res, args[0], args[2]) if args.length is 3 and args[1] is 'remove' return @removeMember(req, res, args[0], args[2]) if args.length is 3 and args[1] is 'remove'
super(arguments...) super(arguments...)
@ -101,6 +102,16 @@ ClanHandler = class ClanHandler extends Handler
cleandocs = (UserHandler.formatEntity(req, doc) for doc in users) cleandocs = (UserHandler.formatEntity(req, doc) for doc in users)
@sendSuccess(res, cleandocs) @sendSuccess(res, cleandocs)
getPublicClans: (req, res) ->
# Return 100 public clans, sorted by member count, created date
query = [{ $match : {type : 'public'} }]
query.push {$project : {_id: 1, name: 1, slug: 1, type: 1, members: 1, memberCount: {$size: "$members"}, ownerID: 1}}
query.push {$sort: { memberCount: -1, _id: -1 }}
query.push {$limit: 100}
Clan.aggregate(query).exec (err, documents) =>
return @sendDatabaseError(res, err) if err
@sendSuccess(res, documents)
removeMember: (req, res, clanID, memberID) -> removeMember: (req, res, clanID, memberID) ->
return @sendForbiddenError(res) unless req.user? and not req.user.isAnonymous() return @sendForbiddenError(res) unless req.user? and not req.user.isAnonymous()
try try

View file

@ -69,22 +69,22 @@ describe 'Clans', ->
expect(res.statusCode).toBe(422) expect(res.statusCode).toBe(422)
done() done()
it 'Get clans', (done) -> it 'Get public clans', (done) ->
loginNewUser (user1) -> loginNewUser (user1) ->
createClan user1, 'public', (clan1) -> createClan user1, 'public', (clan1) ->
createClan user1, 'public', (clan2) -> createClan user1, 'public', (clan2) ->
request.get {uri: clanURL }, (err, res, body) -> request.get {uri: "#{clanURL}/-/public" }, (err, res, body) ->
expect(err).toBeNull() expect(err).toBeNull()
expect(res.statusCode).toBe(200) expect(res.statusCode).toBe(200)
expect(body.length).toBeGreaterThan(1) expect(body.length).toBeGreaterThan(1)
done() done()
it 'Get clans anonymous', (done) -> it 'Get public clans anonymous', (done) ->
loginNewUser (user1) -> loginNewUser (user1) ->
createClan user1, 'public', (clan1) -> createClan user1, 'public', (clan1) ->
createClan user1, 'public', (clan2) -> createClan user1, 'public', (clan2) ->
logoutUser -> logoutUser ->
request.get {uri: clanURL }, (err, res, body) -> request.get {uri: "#{clanURL}/-/public" }, (err, res, body) ->
expect(err).toBeNull() expect(err).toBeNull()
expect(res.statusCode).toBe(200) expect(res.statusCode).toBe(200)
expect(body.length).toBeGreaterThan(1) expect(body.length).toBeGreaterThan(1)