Skip to content

Commit

Permalink
feat(leaderboard): add top competitor by location
Browse files Browse the repository at this point in the history
  • Loading branch information
fabienvauchelles committed May 20, 2019
1 parent 62e5ad6 commit b06e0d8
Show file tree
Hide file tree
Showing 14 changed files with 81 additions and 44 deletions.
Expand Up @@ -101,8 +101,8 @@ export class InternalLeaderboardComponent implements OnInit, OnDestroy {
.getAllLeads$(this.competitionId, offset, this.itemsPerPage)
.subscribe({
next: (leadsPaginated) => {
this.totalItems = leadsPaginated.totalCount;
this.registerStrategyType = leadsPaginated.registerStrategyType;
this.totalItems = leadsPaginated.total_count;
this.registerStrategyType = leadsPaginated.register_strategy_type;
this.leads = leadsPaginated.leads;
},
error: (err) => {
Expand Down
Expand Up @@ -11,12 +11,13 @@ import {CompetitionsService} from '../model/competitions/competitions.service';


@Component({
template: '<leaderboard [competition]="competition" [leads]="leads" *ngIf="competition"></leaderboard>'
template: '<leaderboard [competition]="competition" [leads]="leads" [bestLocationsLeads]="bestLocationsLeads" *ngIf="competition"></leaderboard>'
})
export class LeaderboardContainerComponent implements OnInit, OnDestroy {

competition: Competition;
leads: Lead[] = [];
bestLocationsLeads: Lead[] = [];

private _competitionId: string;
private _subscription: Subscription = new Subscription();
Expand Down Expand Up @@ -88,6 +89,7 @@ export class LeaderboardContainerComponent implements OnInit, OnDestroy {
.subscribe({
next: (leadsPaginated) => {
this.leads = leadsPaginated.leads;
this.bestLocationsLeads = leadsPaginated.best_locations_leads;
},
error: (err) => {
console.error('Error:', err);
Expand Down
Expand Up @@ -44,6 +44,21 @@ export class LeaderboardComponent implements OnInit {
}


@Input('bestLocationsLeads')
set bestLocationsLeads(val: Lead[]) {
window.qscore = window.qscore || {};
window.qscore.bestLocationsLeads = val;
}

get bestLocationsLeads() {
if (!window.qscore) {
return;
}

return window.qscore.bestLocationsLeads;
}


private _templateHtml: string;
leaderboardHtml = '';

Expand Down
7 changes: 4 additions & 3 deletions gui/src/app/model/leads/lead.model.ts
Expand Up @@ -13,8 +13,9 @@ export class Lead {


export class LeadsPaginated {
constructor(public totalCount: number,
public registerStrategyType: number,
public leads: Lead[]) {
constructor(public total_count: number,
public register_strategy_type: number,
public leads: Lead[],
public best_locations_leads: Lead[]) {
}
}
12 changes: 2 additions & 10 deletions gui/src/app/model/leads/leads.service.ts
@@ -1,7 +1,7 @@
import {Observable} from 'rxjs/Rx';
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Lead, LeadsPaginated} from './lead.model';
import {LeadsPaginated} from './lead.model';



Expand All @@ -19,15 +19,7 @@ export class LeadsService {

return this
._http
.get<Lead[]>(`api/leads/${competitionId}`, {
params,
observe: 'response',
})
.map((resp) => new LeadsPaginated(
parseInt(resp.headers.get('total-count')),
parseInt(resp.headers.get('register-strategy-type')),
resp.body
))
.get<LeadsPaginated>(`api/leads/${competitionId}`, {params})
;
}
}
Expand Up @@ -209,7 +209,7 @@ describe('Competitions - Register strategy - Location', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;
expect(leadsFound).to.have.lengthOf(1);

const leadFound = leadsFound[0];
Expand Down Expand Up @@ -317,7 +317,7 @@ describe('Competitions - Register strategy - Location', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;
expect(leadsFound).to.have.lengthOf(1);

const leadFound = leadsFound[0];
Expand Down
Expand Up @@ -206,7 +206,7 @@ describe('Competitions - Register strategy - Password', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;
expect(leadsFound).to.have.lengthOf(1);

const leadFound = leadsFound[0];
Expand Down
12 changes: 7 additions & 5 deletions platform-engine/src/api/leads/leads.controller.js
Expand Up @@ -16,11 +16,13 @@ class LeadsController extends Controller {

return leadsController
.getAllLeads(competitionId, admin, offset, limit)
.spread((leads, totalCount, registerStrategyType) => {
res.set('total-count', totalCount);
res.set('register-strategy-type', registerStrategyType);

this.sendData(res, leads);
.spread((leads, best_locations_leads, total_count, register_strategy_type) => {
this.sendData(res, {
leads,
best_locations_leads,
total_count,
register_strategy_type
});
})
.catch(LeadNotFoundError, (err) => {
throw new ResourceNotFoundError(err.message);
Expand Down
Expand Up @@ -168,7 +168,7 @@ describe('Submissions - Allow leaderboard', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;
expect(leadsFound).to.have.lengthOf(1);

const leadFound = leadsFound[0];
Expand Down Expand Up @@ -227,7 +227,7 @@ describe('Submissions - Allow leaderboard', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;
expect(leadsFound).to.have.lengthOf(1);

const leadFound = leadsFound[0];
Expand Down Expand Up @@ -328,7 +328,7 @@ describe('Submissions - Allow leaderboard', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;

expect(leadsFound).to.be.an('array').that.is.empty;
})
Expand Down Expand Up @@ -401,7 +401,7 @@ describe('Submissions - Allow leaderboard', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;

expect(leadsFound).to.be.an('array').that.is.empty;
})
Expand Down Expand Up @@ -486,7 +486,7 @@ describe('Submissions - Allow leaderboard', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;
expect(leadsFound).to.have.lengthOf(1);

const leadFound = leadsFound[0];
Expand Down
Expand Up @@ -122,7 +122,7 @@ describe('Submissions - Hide leaderboard', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

expect(res.body[0].score).to.be.eql(0.1);
expect(res.body.leads[0].score).to.be.eql(0.1);
})
;
});
Expand All @@ -140,7 +140,7 @@ describe('Submissions - Hide leaderboard', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

expect(res.body[0].score).to.be.eql(0.1);
expect(res.body.leads[0].score).to.be.eql(0.1);
})
;
});
Expand Down Expand Up @@ -195,7 +195,7 @@ describe('Submissions - Hide leaderboard', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

expect(res.body[0].score).to.be.eql(0.1);
expect(res.body.leads[0].score).to.be.eql(0.1);
})
;
});
Expand Down Expand Up @@ -234,7 +234,7 @@ describe('Submissions - Hide leaderboard', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

expect(res.body[0].score).to.be.eql(0.1);
expect(res.body.leads[0].score).to.be.eql(0.1);
})
;
});
Expand Down
Expand Up @@ -198,7 +198,7 @@ describe('Submissions - 1 player', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;

expect(leadsFound).to.be.an('array').that.is.empty;
})
Expand Down Expand Up @@ -339,7 +339,7 @@ describe('Submissions - 1 player', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;
expect(leadsFound).to.have.lengthOf(1);

const leadFound = leadsFound[0];
Expand Down Expand Up @@ -457,7 +457,7 @@ describe('Submissions - 1 player', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;
expect(leadsFound).to.have.lengthOf(1);

const leadFound = leadsFound[0];
Expand Down Expand Up @@ -571,7 +571,7 @@ describe('Submissions - 1 player', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;
expect(leadsFound).to.have.lengthOf(1);

const leadFound = leadsFound[0];
Expand Down Expand Up @@ -665,7 +665,7 @@ describe('Submissions - 1 player', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;
expect(leadsFound).to.have.lengthOf(1);

const leadFound = leadsFound[0];
Expand Down
Expand Up @@ -206,7 +206,7 @@ describe('Submissions - score reverse order', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;
expect(leadsFound).to.have.lengthOf(2);

const lead1found = leadsFound[0];
Expand Down Expand Up @@ -287,7 +287,7 @@ describe('Submissions - score reverse order', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;
expect(leadsFound).to.have.lengthOf(2);

const lead1found = leadsFound[0];
Expand Down
Expand Up @@ -233,7 +233,7 @@ describe('Submissions - 2 players', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;

expect(leadsFound).to.be.an('array').that.is.empty;
})
Expand Down Expand Up @@ -426,7 +426,7 @@ describe('Submissions - 2 players', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;
expect(leadsFound).to.have.lengthOf(2);

const lead1found = leadsFound[0];
Expand Down Expand Up @@ -489,7 +489,7 @@ describe('Submissions - 2 players', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;
expect(leadsFound).to.have.lengthOf(2);

const lead1found = leadsFound[0];
Expand Down Expand Up @@ -552,7 +552,7 @@ describe('Submissions - 2 players', function test() {
.then((res) => {
expect(res.statusCode).to.eql(200);

const leadsFound = res.body;
const leadsFound = res.body.leads;
expect(leadsFound).to.have.lengthOf(2);

const lead1found = leadsFound[0];
Expand Down
25 changes: 25 additions & 0 deletions platform-engine/src/model/leads/leads.controller.js
Expand Up @@ -73,6 +73,7 @@ class LeadsController {

return Promise.join(
getPaginatedLeads(competitionId, attributes.score_order, offset, limit),
getBestLocations(competitionId, attributes.score_order),
getLeadsCount(competitionId),
attributes.register_strategy_type
);
Expand Down Expand Up @@ -144,6 +145,30 @@ class LeadsController {
},
});
}

function getBestLocations(cId, order) {
return database.query(`
SELECT DISTINCT ON (player_location)
id, player_sub, player_location, score, score_updated_at, submissions_count, name as player_name, picture_url as player_picture_url,
rank() over (order by score ${order ? 'DESC' : 'ASC'}, score_updated_at ) as rank
FROM leads, players
WHERE competition_id=:competitionId AND leads.player_sub = players.sub
ORDER BY player_location, score ${order ? 'DESC' : 'ASC'}, score_updated_at ASC
`,
{
replacements: {
competitionId: cId,
},
type: Sequelize.QueryTypes.SELECT,
})
.then((results) => results.map((lObj) => {
lObj.hash = createHash(lObj.player_sub);
delete lObj.player_sub;

return lObj;
}))
;
}
}


Expand Down

0 comments on commit b06e0d8

Please sign in to comment.