Skip to content
This repository has been archived by the owner on Jul 6, 2020. It is now read-only.

Modify the challenge leaderboard page #155

Merged
merged 14 commits into from
Jul 24, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,35 +1,119 @@
<div class="challenge-leaderboard-container">
<div class="phase-select-div">
<app-selectphase [phases]="filteredPhaseSplits" [phaseSelected]="phaseSplitSelected()" #phasesplitselect></app-selectphase>
</div>
<div *ngIf="leaderboard.length <= 0" class="leaderboard-empty">
<!-- <img src="assets/images/sadcloud.png" /> -->
<i class="fas fa-clipboard" aria-hidden="true"></i> No Results..
</div>
<div class="leaderboard-table-div" *ngIf="leaderboard.length > 0">

<table class="table-light leaderboard-table">
<tr>
<th>
<div (click)="sortColumn!='rank' && reverseSort = false;sortColumn == 'rank' && reverseSort=!reverseSort;sortColumn='rank';sortLeaderboard();" class="fa-stack fa-1x"><span>Rank </span><i class="fas fa-sort-up fa-stack-1x" [class.dark]="reverseSort && sortColumn == 'rank'"></i><i class="fas fa-sort-down fa-stack-1x" [class.dark]="!reverseSort && sortColumn == 'rank'"></i></div>
</th>
<th>
<div (click)="sortColumn!='string' && reverseSort = false;sortColumn == 'string' && reverseSort=!reverseSort;sortColumn='string';sortLeaderboard();" class="fa-stack fa-1x fat"><span>Participant Team</span><i class="fas fa-sort-up fa-stack-1x" [class.dark]="reverseSort && sortColumn == 'string'"></i><i class="fas fa-sort-down fa-stack-1x" [class.dark]="!reverseSort && sortColumn == 'string'"></i></div>
</th>
<th *ngFor="let key of leaderboard[0].leaderboard__schema.labels;index as i" [attr.data-index]="i"><div href="#" (click)="sortColumn!='number' && columnIndexSort != i && reverseSort = false;sortColumn == 'number' && columnIndexSort == i && reverseSort=!reverseSort;sortColumn = 'number';columnIndexSort = i;sortLeaderboard();" class="fa-stack fa-1x"><span>{{key}}</span><i class="fas fa-sort-up fa-stack-1x" [class.dark]="reverseSort && sortColumn == 'number' && columnIndexSort == i"></i><i class="fas fa-sort-down fa-stack-1x" [class.dark]="!reverseSort && sortColumn == 'number' && columnIndexSort == i"></i></div>
</th>
<th>
<div (click)="sortColumn!='date' && reverseSort = false;sortColumn == 'date' && reverseSort=!reverseSort;sortColumn='date';sortLeaderboard();" class="fa-stack fa-1x fat"><span>Last Submission at</span><i class="fas fa-sort-up fa-stack-1x" [class.dark]="reverseSort && sortColumn == 'date'"></i>
<i class="fas fa-sort-down fa-stack-1x" [class.dark]="!reverseSort && sortColumn == 'date'"></i>
</div>
</th>
</tr>
<tr *ngFor="let key of leaderboard" [class.highlight]="key.is_highlighted" class="pointer" [routerLink]="routerPublic.url.split('/').length == 6 ? ['../' + key.submission__participant_team__team_name] : [key.submission__participant_team__team_name]">
<td><div>{{initial_ranking[key.submission__participant_team__team_name]}}</div></td>
<td><div class="fw-regular">{{key.submission__participant_team__team_name}}</div></td>
<td *ngFor="let score of key.result"><div>{{score | number : '1.2-2'}}</div></td>
<td><div>{{ key.submission__submitted_at_formatted }}</div></td>
</tr>
</table>
<div class="challenge-card">
<div class="ev-card-panel card-bt-margin">
<div class="ev-md-container ev-panel-title" *ngIf="challenge.leaderboard_description">
<div class="row row-lr-margin">
<div class="col-sm-12 col-xs-12 col-lr-pad">
<span class="fw-regular">Description</span>
</div>
<div class="col-sm-12 md-body-1 col-lr-pad" [innerHTML]="challenge.leaderboard_description"></div>
</div>
</div>
<div class="ev-md-container bottom-hr-line">
<div (click)="refreshLeaderboard()" class="pointer update-page" *ngIf="showLeaderboardUpdate">
<span class="text-white">Page is Outdated, Click to update&nbsp; <i class="fa fa-refresh text-highlight"></i></span>
</div>
<div class="row row-lr-margin phase-title">
<div class="col-sm-12">
<strong class="fw-semibold content fs-15">Please select from following phases!</strong>
</div>
</div>
<div class="row row-lr-margin">
<div class="col-sm-6 col-xs-12 col-lr-pad phase-select-box">
<app-selectphase [phases]="filteredPhaseSplits" [phaseSelectionType]="phaseSelectionType"
[phaseSelectionListType]="phaseSelectionListType" [phaseSplitSelected]="phaseSplitSelected()"
#phasesplitselect>
</app-selectphase>
</div>
</div>
</div>

<div class="ev-card-body exist-team-card">
<div class="row row-lr-margin">
<div class="horizontal-scroll">
<div class="col-sm-12 col-lr-pad">
<div *ngIf="leaderboard.length <= 0 && selectedPhaseSplit == null" class="fw-regular result-wrn">No phase selected.</div>
<div *ngIf="leaderboard.length > 0 && selectedPhaseSplit" class="result-wrn content">
<mat-chip-list>
<mat-chip>B</mat-chip> - Baseline submission
</mat-chip-list>
</div>

<table *ngIf="leaderboard.length > 0 && selectedPhaseSplit" class="centered highlight">
<thead>
<tr class="content">
<td data-field="rank" class="align-center">
<a (click)="sortColumn!='rank' && reverseSort = false;sortColumn == 'rank' &&
RishabhJain2018 marked this conversation as resolved.
Show resolved Hide resolved
reverseSort=!reverseSort;sortColumn='rank';sortLeaderboard();">
<span class="fw-regular fs-18">Rank </span>
<span class="fa-stack fa-1x">
<i class="fa fa-sort-asc fa-stack-1x" [ngClass]="reverseSort &&
sortColumn == 'rank'? 'text-med-black' : 'text-light-black fw-semibold'"></i>
<i class="fa fa-sort-desc fa-stack-1x" [ngClass]="!reverseSort &&
sortColumn == 'rank'? 'text-med-black' : 'text-light-black fw-semibold'"></i>
</span>
</a>
</td>
<td data-field="team" class="align-center">
<a (click)="sortColumn!='string' && reverseSort = false;sortColumn == 'string' &&
reverseSort=!reverseSort;sortColumn='string';sortLeaderboard();">
<span class="fw-regular fs-18">Participant Team</span>
<span class="fa-stack fa-1x">
<i class="fa fa-sort-asc fa-stack-1x" [ngClass]="reverseSort &&
sortColumn == 'string'? 'text-med-black' : 'text-light-black fw-semibold'"></i>
<i class="fa fa-sort-desc fa-stack-1x" [ngClass]="reverseSort &&
sortColumn == 'string'? 'text-med-black' : 'text-light-black fw-semibold'"></i>
</span>
</a>
</td>
<td *ngFor="let key of leaderboard[0].leaderboard__schema.labels;index as i" [attr.data-index]="i" class="align-center">
<a (click)="sortColumn!='number' && columnIndexSort != i &&
reverseSort = false;sortColumn == 'number' && columnIndexSort == i &&
reverseSort=!reverseSort;sortColumn = 'number';columnIndexSort = i;sortLeaderboard();">
<span class="fw-regular fs-18">{{key}}</span>
<span class="fa-stack fa-1x">
<i class="fa fa-sort-asc fa-stack-1x" [ngClass]="reverseSort &&
sortColumn == 'number'? 'text-med-black' : 'text-light-black fw-semibold'"></i>
<i class="fa fa-sort-desc fa-stack-1x" [ngClass]="!reverseSort &&
sortColumn == 'number'? 'text-med-black' : 'text-light-black fw-semibold'"></i>
</span>
</a>
</td>
<td data-field="submission_time" class="align-center">
<a (click)="sortColumn!='date' && reverseSort = false;sortColumn == 'date' &&
reverseSort=!reverseSort;sortColumn='date';sortLeaderboard();">
<span class="fs-18 fw-regular">Last submission at</span>
<span class="fa-stack fa-1x">
<i class="fa fa-sort-asc fa-stack-1x" [ngClass]="reverseSort &&
sortColumn == 'date'? 'text-med-black' : 'text-light-black w-500'"></i>
<i class="fa fa-sort-desc fa-stack-1x" [ngClass]="!reverseSort &&
sortColumn == 'date'? 'text-med-black' : 'text-light-black w-500'"></i>
</span>
</a>
</td>
</tr>
</thead>
<tbody>
<tr *ngFor="let key of leaderboard" class="content">
<td>{{initial_ranking[key.submission__participant_team__team_name]}}</td>
<td class="fw-regular">{{key.submission__participant_team__team_name}}
<span *ngIf="key.submission__is_baseline">
<mat-chip-list>
<mat-chip>B</mat-chip>
</mat-chip-list>
</span>
</td>
<td *ngFor="let score of key.result">{{score | number : '1.2-2'}}</td>
<td><div>{{ key.submission__submitted_at_formatted }}</div></td>
</tr>
</tbody>
</table>
<div *ngIf="leaderboard.length <= 0 && selectedPhaseSplit">
<p>No results to show!</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,14 @@
}
}
}

.ev-card-body {
.row-lr-margin {
margin-bottom: 20px;
}

.mat-standard-chip {
padding: 3px 5px;
font-size: 16px;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,26 @@ export class ChallengeleaderboardComponent implements OnInit, AfterViewInit {
*/
filteredPhaseSplits = [];

/**
* Phase selection type (radio button or select box)
*/
phaseSelectionType = 'selectBox';

/**
* Select box list type
*/
phaseSelectionListType = 'phaseSplit';

/**
* Leaderboard entries list
*/
leaderboard = [];

/**
* Show leaderboard updates
*/
showLeaderboardUpdate = false;

/**
* Currently selected phase split's id
*/
Expand Down Expand Up @@ -98,6 +113,15 @@ export class ChallengeleaderboardComponent implements OnInit, AfterViewInit {
*/
entryHighlighted: any = null;

/**
* Challenge phase visibility
*/
challengePhaseVisibility = {
owner_and_host: 1,
host: 2,
public: 3,
RishabhJain2018 marked this conversation as resolved.
Show resolved Hide resolved
};

/**
* Constructor.
* @param route ActivatedRoute Injection.
Expand Down Expand Up @@ -146,21 +170,12 @@ export class ChallengeleaderboardComponent implements OnInit, AfterViewInit {
*/
filterPhases() {
if (this.phases.length > 0 && this.phaseSplits.length > 0) {
const TEMPSPLITS = [];
for (let i = 0; i < this.phases.length; i++) {
if (this.phases[i]['leaderboard_public']) {
const TEMP = this.phases[i];
TEMP['phase_split'] = null;
for (let j = 0; j < this.phaseSplits.length; j++) {
if (this.phaseSplits[j]['challenge_phase'] === TEMP['id'] && this.phaseSplits[j]['visibility'] === 3) {
const TEMP_COPY = Object.assign({}, TEMP);
TEMP_COPY['phase_split'] = this.phaseSplits[j];
TEMPSPLITS.push(TEMP_COPY);
}
}
for (let i = 0; i < this.phaseSplits.length; i++) {
if (this.phaseSplits[i].visibility !== this.challengePhaseVisibility.public) {
this.phaseSplits[i].showPrivate = true;
}
}
this.filteredPhaseSplits = TEMPSPLITS;
this.filteredPhaseSplits = this.phaseSplits;
setTimeout(() => {
this.checkUrlParams();
}, 100);
Expand All @@ -172,14 +187,9 @@ export class ChallengeleaderboardComponent implements OnInit, AfterViewInit {
*/
checkUrlParams() {
this.route.params.subscribe(params => {
console.log(params);
if (params['split']) {
this.selectedPhaseSplitId = params['split'];
this.selectPhaseSplitId(this.selectedPhaseSplitId, this);
} else {
if (this.filteredPhaseSplits.length > 0) {
this.router.navigate([this.filteredPhaseSplits[0]['phase_split']['id']], {relativeTo: this.route});
}
}
});
}
Expand All @@ -192,12 +202,12 @@ export class ChallengeleaderboardComponent implements OnInit, AfterViewInit {
selectPhaseSplitId(id, self) {
let i = 0;
for (i = 0; i < self.filteredPhaseSplits.length; i++) {
if (parseInt(id, 10) === self.filteredPhaseSplits[i]['phase_split']['id']) {
if (parseInt(id, 10) === self.filteredPhaseSplits[i]['id']) {
self.selectedPhaseSplit = self.filteredPhaseSplits[i];
const checkViewInit = () => {
if (self.viewInit) {
self.components.map((item) => {
item.selectPhase(self.selectedPhaseSplit);
item.selectPhaseSplit(self.selectedPhaseSplit, 'selectBox', 'phaseSplit');
});
} else {
setTimeout(() => {
Expand All @@ -221,18 +231,18 @@ export class ChallengeleaderboardComponent implements OnInit, AfterViewInit {
const SELF = this;
return (phaseSplit) => {
if (SELF.router.url.endsWith('leaderboard')) {
SELF.router.navigate(['../' + phaseSplit['phase_split']['id']], {relativeTo: this.route});
} else if (SELF.router.url.indexOf(phaseSplit['phase_split']['id']) < 0 && SELF.router.url.split('/').length === 5) {
SELF.router.navigate(['../' + phaseSplit['phase_split']['id']], {relativeTo: this.route});
} else if (SELF.router.url.indexOf(phaseSplit['phase_split']['id']) < 0 && SELF.router.url.split('/').length === 6) {
SELF.router.navigate(['../../' + phaseSplit['phase_split']['id']], {relativeTo: this.route});
} else {
SELF.selectedPhaseSplit = phaseSplit;
if (SELF.selectedPhaseSplit['phase_split']) {
SELF.fetchLeaderboard(SELF.selectedPhaseSplit['phase_split']['id']);
}
SELF.router.navigate([phaseSplit['id']], {relativeTo: this.route});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Sanji515 can you also refer this file in #171?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, thanks 👍

} else if (SELF.router.url.split('/').length === 5) {
SELF.router.navigate(['../' + phaseSplit['id']], {relativeTo: this.route});
} else if (SELF.router.url.split('/').length === 6) {
SELF.router.navigate(['../../' + phaseSplit['id']], {relativeTo: this.route});
}
SELF.selectedPhaseSplit = phaseSplit;
if (SELF.selectedPhaseSplit) {
SELF.fetchLeaderboard(SELF.selectedPhaseSplit['id']);
}
};

}

/**
Expand Down Expand Up @@ -261,14 +271,6 @@ export class ChallengeleaderboardComponent implements OnInit, AfterViewInit {
item['is_highlighted'] = true;
}
});
} else {
self.challengeService.currentParticipantTeams.subscribe((teams) => {
teams.map((item) => {
if (self.challenge && item['challenge'] && item['challenge']['id'] === self.challenge['id']) {
self.router.navigate([item['participant_team']['team_name']], {relativeTo: this.route});
}
});
});
}
});
}
Expand Down Expand Up @@ -319,7 +321,9 @@ export class ChallengeleaderboardComponent implements OnInit, AfterViewInit {
const SELF = this;
this.apiService.getUrl(API_PATH).subscribe(
data => {
console.log(data['results']);
RishabhJain2018 marked this conversation as resolved.
Show resolved Hide resolved
SELF.updateLeaderboardResults(data['results'], SELF);
SELF.startLeaderboard(phaseSplitId);
},
err => {
SELF.globalService.handleApiError(err);
Expand All @@ -329,4 +333,43 @@ export class ChallengeleaderboardComponent implements OnInit, AfterViewInit {
}
);
}

startLeaderboard(phaseSplitId) {
const API_PATH = this.endpointsService.challengeLeaderboardURL(phaseSplitId);
const SELF = this;
setInterval(function() {
SELF.apiService.getUrl(API_PATH, true, false).subscribe(
data => {
if (SELF.leaderboard.length !== data['results'].length) {
SELF.showLeaderboardUpdate = true;
}
},
err => {
SELF.globalService.handleApiError(err);
},
() => {
console.log('Fetched leaderboard for split:', phaseSplitId);
}
);
}, 5000);
}

refreshLeaderboard() {
const API_PATH = this.endpointsService.challengeLeaderboardURL(this.selectedPhaseSplit['id']);
const SELF = this;
SELF.leaderboard = [];
SELF.apiService.getUrl(API_PATH).subscribe(
data => {
SELF.leaderboard = data['results'];
SELF.showLeaderboardUpdate = false;
SELF.startLeaderboard(SELF.selectedPhaseSplit['id']);
},
err => {
SELF.globalService.handleApiError(err);
},
() => {
console.log('Fetched leaderboard for split:', SELF.selectedPhaseSplit['id']);
}
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<div class="row row-lr-margin">
<div class="col-sm-6 col-xs-12 col-lr-pad phase-select-box">
<app-selectphase [phases]="filteredPhases"
[phaseSelectionListType]="phaseSelectionListType"
[phaseSelectionType]="phaseSelectionType"
[phaseSelected]="phaseSelected()" #phaseselect></app-selectphase>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ export class ChallengesubmissionsComponent implements OnInit, AfterViewInit {
*/
phaseSelectionType = 'selectBox';

/**
* Select box list type
*/
phaseSelectionListType = 'phase';

/**
* @param showPagination Is pagination
* @param paginationMessage Pagination message
Expand Down
Loading