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

Commit 18b798e

Browse files
Merge branch 'master' into improve_coverage_ngx
2 parents 1dcad60 + 99b8f4d commit 18b798e

10 files changed

Lines changed: 219 additions & 27 deletions

src/app/components/challenge/challengeleaderboard/challengeleaderboard.component.html

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
<mat-chip-list>
4242
<mat-chip>B</mat-chip> - Baseline submission
4343
</mat-chip-list>
44+
<mat-chip-list class="leaderboard-description-span">
45+
<b><span class="leaderboard-description">*</span></b> - Private submission
46+
</mat-chip-list>
4447
<mat-chip-list class="pull-right" *ngIf="isChallengeHost">
4548
<div (click)="showLeaderboardByLatestOrBest()" class="btn-switch sort-leaderboard-switch" [ngClass]="{'btn-switch--on':showLeaderboardByLatest}"
4649
[(ngModel)]="showLeaderboardByLatest" ngDefaultControl>
@@ -49,6 +52,11 @@
4952
</div>
5053
<span class="w-400"> {{sortLeaderboardTextOption}}</span>
5154
</mat-chip-list>
55+
<mat-checkbox class="pull-right complete-leaderboard" *ngIf="isChallengeHost && showLeaderboardToggle"
56+
(change)="toggleLeaderboard(getAllEntries)"
57+
[(ngModel)]="getAllEntries">
58+
<label class="w-400 complete-leaderboard-text"> {{getAllEntriesTextOption}}</label>
59+
</mat-checkbox>
5260
</div>
5361

5462
<table *ngIf="leaderboard.length > 0 && selectedPhaseSplit" class="centered highlight">
@@ -58,9 +66,9 @@
5866
<a (click)="sortNonMetricsColumn('rank')">
5967
<span class="fw-regular fs-18">Rank </span>
6068
<span class="fa-stack fa-1x">
61-
<i class="fa fa-sort-asc fa-stack-1x" [ngClass]="reverseSort &&
69+
<i class="fa fa-sort-asc fa-stack-1x" [ngClass]="reverseSort &&
6270
sortColumn == 'rank' ? 'text-med-black' : 'text-light-black fw-semibold'"></i>
63-
<i class="fa fa-sort-desc fa-stack-1x" [ngClass]="!reverseSort &&
71+
<i class="fa fa-sort-desc fa-stack-1x" [ngClass]="!reverseSort &&
6472
sortColumn == 'rank' ? 'text-med-black' : 'text-light-black fw-semibold'"></i>
6573
</span>
6674
</a>
@@ -69,9 +77,9 @@
6977
<a (click)="sortNonMetricsColumn('string')">
7078
<span class="fw-regular fs-18">Participant Team</span>
7179
<span class="fa-stack fa-1x">
72-
<i class="fa fa-sort-asc fa-stack-1x" [ngClass]="reverseSort &&
80+
<i class="fa fa-sort-asc fa-stack-1x" [ngClass]="reverseSort &&
7381
sortColumn == 'string'? 'text-med-black' : 'text-light-black fw-semibold'"></i>
74-
<i class="fa fa-sort-desc fa-stack-1x" [ngClass]="reverseSort &&
82+
<i class="fa fa-sort-desc fa-stack-1x" [ngClass]="reverseSort &&
7583
sortColumn == 'string'? 'text-med-black' : 'text-light-black fw-semibold'"></i>
7684
</span>
7785
</a>
@@ -81,9 +89,9 @@
8189
<a (click)="sortMetricsColumn(i)">
8290
<span class="fw-regular fs-18">{{key}}</span>
8391
<span class="fa-stack fa-1x">
84-
<i class="fa fa-sort-asc fa-stack-1x" [ngClass]="reverseSort &&
92+
<i class="fa fa-sort-asc fa-stack-1x" [ngClass]="reverseSort &&
8593
sortColumn == 'number'? 'text-med-black' : 'text-light-black fw-semibold'"></i>
86-
<i class="fa fa-sort-desc fa-stack-1x" [ngClass]="!reverseSort &&
94+
<i class="fa fa-sort-desc fa-stack-1x" [ngClass]="!reverseSort &&
8795
sortColumn == 'number'? 'text-med-black' : 'text-light-black fw-semibold'"></i>
8896
</span>
8997
</a>
@@ -92,9 +100,9 @@
92100
<a (click)="sortNonMetricsColumn('date')">
93101
<span class="fs-18 fw-regular">Last submission at</span>
94102
<span class="fa-stack fa-1x">
95-
<i class="fa fa-sort-asc fa-stack-1x" [ngClass]="reverseSort &&
103+
<i class="fa fa-sort-asc fa-stack-1x" [ngClass]="reverseSort &&
96104
sortColumn == 'date'? 'text-med-black' : 'text-light-black w-500'"></i>
97-
<i class="fa fa-sort-desc fa-stack-1x" [ngClass]="!reverseSort &&
105+
<i class="fa fa-sort-desc fa-stack-1x" [ngClass]="!reverseSort &&
98106
sortColumn == 'date'? 'text-med-black' : 'text-light-black w-500'"></i>
99107
</span>
100108
</a>
@@ -105,6 +113,7 @@
105113
<tr *ngFor="let key of leaderboard" class="content">
106114
<td>{{initial_ranking[key.submission__participant_team__team_name]}}</td>
107115
<td class="fw-regular">{{key.submission__participant_team__team_name}}
116+
<b><span *ngIf="key.submission__is_public === false" class="orange-text">*</span></b>
108117
<span *ngIf="key.submission__is_baseline">
109118
<mat-chip-list>
110119
<mat-chip>B</mat-chip>

src/app/components/challenge/challengeleaderboard/challengeleaderboard.component.scss

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
background-color: rgb(167, 163, 163);
9393
border: 2px solid rgb(167, 163, 163);
9494
border-radius: 40px;
95-
95+
9696
.btn-switch-circle {
9797
position: absolute;
9898
top: 0;
@@ -108,7 +108,7 @@
108108
.btn-switch--on {
109109
background-color: #ffaf4b;
110110
border: 2px solid #ffaf4b;;
111-
111+
112112
.btn-switch-circle--on {
113113
left: auto;
114114
right: 0;
@@ -119,3 +119,22 @@
119119
vertical-align: middle;
120120
display: inline-block;
121121
}
122+
123+
.complete-leaderboard {
124+
margin-right: 2%;
125+
}
126+
127+
.leaderboard-description {
128+
color: $yellow !important;
129+
border-radius: 2px !important;
130+
min-height: 25px !important;
131+
}
132+
133+
.leaderboard-description-span {
134+
margin-left: 2%;
135+
}
136+
137+
.complete-leaderboard-text {
138+
font-size: $fs-16;
139+
color: $gray-darker;
140+
}

src/app/components/challenge/challengeleaderboard/challengeleaderboard.component.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ export class ChallengeleaderboardComponent implements OnInit, AfterViewInit {
5353
*/
5454
phases = [];
5555

56+
/**
57+
* Private phases list
58+
*/
59+
showPrivateIds = [];
60+
5661
/**
5762
* Phase split list
5863
*/
@@ -98,6 +103,16 @@ export class ChallengeleaderboardComponent implements OnInit, AfterViewInit {
98103
*/
99104
showLeaderboardByLatest = false;
100105

106+
/**
107+
* Current state of whether complete leaderboard
108+
*/
109+
getAllEntries = false;
110+
111+
/**
112+
* Current state of whether private leaderboard
113+
*/
114+
showLeaderboardToggle = true;
115+
101116
/**
102117
* Sort leaderboard based on this column
103118
*/
@@ -108,6 +123,11 @@ export class ChallengeleaderboardComponent implements OnInit, AfterViewInit {
108123
*/
109124
sortLeaderboardTextOption: string;
110125

126+
/**
127+
* Text option for complete leadeboard
128+
*/
129+
getAllEntriesTextOption = 'Include private submissions';
130+
111131
/**
112132
* Reverse sort flag
113133
*/
@@ -196,6 +216,7 @@ export class ChallengeleaderboardComponent implements OnInit, AfterViewInit {
196216
for (let i = 0; i < this.phaseSplits.length; i++) {
197217
if (this.phaseSplits[i].visibility !== this.challengePhaseVisibility.public) {
198218
this.phaseSplits[i].showPrivate = true;
219+
this.showPrivateIds.push(this.phaseSplits[i].id);
199220
}
200221
}
201222
this.filteredPhaseSplits = this.phaseSplits;
@@ -374,6 +395,31 @@ export class ChallengeleaderboardComponent implements OnInit, AfterViewInit {
374395
fetchLeaderboard(phaseSplitId) {
375396
const API_PATH = this.endpointsService.challengeLeaderboardURL(phaseSplitId);
376397
const SELF = this;
398+
SELF.showPrivateIds.forEach(id => {
399+
(id === phaseSplitId) ? ( SELF.showLeaderboardToggle = false) : (SELF.showLeaderboardToggle = true);
400+
});
401+
clearInterval(SELF.pollingInterval);
402+
SELF.leaderboard = [];
403+
SELF.showLeaderboardUpdate = false;
404+
this.apiService.getUrl(API_PATH).subscribe(
405+
data => {
406+
SELF.updateLeaderboardResults(data['results'], SELF);
407+
SELF.startLeaderboard(phaseSplitId);
408+
},
409+
err => {
410+
SELF.globalService.handleApiError(err);
411+
},
412+
() => {}
413+
);
414+
}
415+
416+
/**
417+
* Fetch complete leaderboard for a phase split public/private
418+
* @param phaseSplitId id of the phase split
419+
*/
420+
fetchAllEnteriesOnPublicLeaderboard(phaseSplitId) {
421+
const API_PATH = this.endpointsService.challengeCompleteLeaderboardURL(phaseSplitId);
422+
const SELF = this;
377423
clearInterval(SELF.pollingInterval);
378424
SELF.leaderboard = [];
379425
SELF.showLeaderboardUpdate = false;
@@ -389,6 +435,19 @@ export class ChallengeleaderboardComponent implements OnInit, AfterViewInit {
389435
);
390436
}
391437

438+
// function for toggeling between public leaderboard and complete leaderboard [public/private]
439+
toggleLeaderboard(getAllEntries) {
440+
console.log(getAllEntries);
441+
this.getAllEntries = getAllEntries;
442+
if (getAllEntries) {
443+
this.getAllEntriesTextOption = 'Exclude private submissions';
444+
this.fetchAllEnteriesOnPublicLeaderboard(this.selectedPhaseSplitId);
445+
} else {
446+
this.getAllEntriesTextOption = 'Include private submissions';
447+
this.fetchLeaderboard(this.selectedPhaseSplitId);
448+
}
449+
}
450+
392451
/**
393452
* Call leaderboard API in the interval of 5 seconds
394453
* @param phaseSplitId id of the phase split

src/app/components/publiclists/teamlist/teamcard/teamcard.component.html

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,17 @@
2929
</div>
3030
</div>
3131
<div class='team-members'>
32-
<div class="title">
33-
<h6><b>Team Members:</b></h6>
32+
<div class="title">
33+
<h6><b>Team Members:</b></h6>
34+
</div>
35+
<div class="col s12 m6" *ngFor="let member of memberArray; let i=index;" class="member-class">
36+
<span class="m1">{{member}}</span>
37+
<span class="trash-icon"><a (click)="deleteTeamMember($event, memberIdArray[i])"
38+
*ngIf="authState.username == teamView['created_by']">
39+
<i class="fa fa-trash list-icon text-highlight w-300 left grey-text" aria-hidden="true"></i>
40+
</a>
41+
</span>
42+
</div>
3443
</div>
35-
<div>
36-
{{teamView['members']}}
37-
</div>
38-
39-
</div>
40-
</div>
44+
</div>
4145
</div>

src/app/components/publiclists/teamlist/teamcard/teamcard.component.scss

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,12 @@
124124
height: unset !important;
125125
border-bottom-style: none !important;
126126
}
127+
128+
.member-class{
129+
display: flex;
130+
margin: 2% 0%;
131+
}
132+
.trash-icon {
133+
margin-left: 80%;
134+
position: absolute;
135+
}

src/app/components/publiclists/teamlist/teamcard/teamcard.component.spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { ApiService } from '../../../../services/api.service';
77
import { RouterTestingModule } from '@angular/router/testing';
88
import { HttpClientModule } from '@angular/common/http';
99
import { NO_ERRORS_SCHEMA } from '@angular/core';
10+
import { AuthService } from '../../../../services/auth.service';
11+
import { EndpointsService } from '../../../../services/endpoints.service';
1012

1113
describe('TeamcardComponent', () => {
1214
let component: TeamcardComponent;
@@ -15,7 +17,7 @@ describe('TeamcardComponent', () => {
1517
beforeEach(async(() => {
1618
TestBed.configureTestingModule({
1719
declarations: [ TeamcardComponent ],
18-
providers: [ GlobalService, ApiService ],
20+
providers: [ GlobalService, ApiService, AuthService, EndpointsService ],
1921
imports: [ RouterTestingModule, HttpClientModule ],
2022
schemas: [ NO_ERRORS_SCHEMA ]
2123
})
@@ -29,6 +31,7 @@ describe('TeamcardComponent', () => {
2931
component.selected = false;
3032
component.isOnChallengePage = false;
3133
component.deleteTeamCard = new EventEmitter<any>();
34+
component.deleteMemberCard = new EventEmitter<any>();
3235
component.selectTeamCard = new EventEmitter<any>();
3336
fixture.detectChanges();
3437
});

src/app/components/publiclists/teamlist/teamcard/teamcard.component.ts

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Component, OnInit, OnChanges, Input, Output, EventEmitter, SimpleChange
22
import { GlobalService } from '../../../../services/global.service';
33
import { ApiService } from '../../../../services/api.service';
44
import { Router, ActivatedRoute } from '@angular/router';
5+
import { AuthService } from '../../../../services/auth.service';
56

67
/**
78
* Component Class
@@ -13,6 +14,16 @@ import { Router, ActivatedRoute } from '@angular/router';
1314
})
1415
export class TeamcardComponent implements OnInit, OnChanges {
1516

17+
/**
18+
* Authentication Service subscription
19+
*/
20+
authServiceSubscription: any;
21+
22+
/**
23+
* Current Authentication state
24+
*/
25+
authState: any;
26+
1627
/**
1728
* Team object
1829
*/
@@ -33,6 +44,11 @@ export class TeamcardComponent implements OnInit, OnChanges {
3344
*/
3445
@Output() deleteTeamCard = new EventEmitter<any>();
3546

47+
/**
48+
* Delete member event
49+
*/
50+
@Output() deleteMemberCard = new EventEmitter<any>();
51+
3652
/**
3753
* Select team event
3854
*/
@@ -58,6 +74,16 @@ export class TeamcardComponent implements OnInit, OnChanges {
5874
*/
5975
teamView = {};
6076

77+
/**
78+
* Team Member Array
79+
*/
80+
memberArray = [];
81+
82+
/**
83+
* Team Member ID Array
84+
*/
85+
memberIdArray = [];
86+
6187
/**
6288
* Is currently selected
6389
*/
@@ -77,6 +103,7 @@ export class TeamcardComponent implements OnInit, OnChanges {
77103
*/
78104
constructor(private globalService: GlobalService,
79105
private apiService: ApiService,
106+
public authService: AuthService,
80107
private router: Router,
81108
private route: ActivatedRoute) { }
82109

@@ -85,6 +112,9 @@ export class TeamcardComponent implements OnInit, OnChanges {
85112
*/
86113
ngOnInit() {
87114
this.updateView();
115+
this.authServiceSubscription = this.authService.change.subscribe((authState) => {
116+
this.authState = authState;
117+
});
88118
}
89119

90120
/**
@@ -132,6 +162,14 @@ export class TeamcardComponent implements OnInit, OnChanges {
132162
this.deleteTeamCard.emit(this.team['id']);
133163
}
134164

165+
/**
166+
* Fires delete member event.
167+
*/
168+
deleteTeamMember(e, participantId) {
169+
e.stopPropagation();
170+
this.deleteMemberCard.emit({teamId: this.team['id'], participantId: participantId});
171+
}
172+
135173
/**
136174
* Fires slect team event.
137175
*/
@@ -155,18 +193,19 @@ export class TeamcardComponent implements OnInit, OnChanges {
155193
this.isSelected = false;
156194
}
157195
const temp = this.team['members'];
158-
let memberString = '';
196+
this.memberArray = [];
197+
this.memberIdArray = [];
159198
for (let i = 0; i < temp.length; i++) {
160199
if (temp[i]['member_name']) {
161-
memberString = memberString + ', ' + temp[i]['member_name'];
200+
this.memberArray.push(temp[i]['member_name']);
201+
this.memberIdArray.push(temp[i]['id']);
162202
} else {
163-
memberString = memberString + ', ' + temp[i]['user'];
203+
this.memberArray.push(temp[i]['user']);
204+
this.memberIdArray.push(temp[i]['id']);
164205
}
165206
}
166-
if (memberString !== '') {
167-
memberString = memberString.slice(2, memberString.length);
168-
}
169-
this.teamView['members'] = memberString;
207+
this.teamView['members'] = this.memberArray;
208+
this.teamView['member_ids'] = this.memberIdArray;
170209
}
171210

172211
}

0 commit comments

Comments
 (0)