Add scoreboard table sorting
parent
9a0cd3544e
commit
99482625a2
|
@ -8,13 +8,13 @@ import {CampaignService} from '../services/logs/campaign.service';
|
||||||
import {NgxDatatableModule} from '@swimlane/ngx-datatable';
|
import {NgxDatatableModule} from '@swimlane/ngx-datatable';
|
||||||
import {PlayerService} from '../services/logs/player.service';
|
import {PlayerService} from '../services/logs/player.service';
|
||||||
import {LogsService} from '../services/logs/logs.service';
|
import {LogsService} from '../services/logs/logs.service';
|
||||||
import {MatButtonModule, MatButtonToggleModule, MatExpansionModule, MatTableModule} from '@angular/material';
|
import {MatButtonModule, MatButtonToggleModule, MatExpansionModule, MatTableModule, MatSortModule} from '@angular/material';
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: statsRoutingComponents,
|
declarations: statsRoutingComponents,
|
||||||
imports: [CommonModule, SharedModule, statsRouterModule, NgxChartsModule, NgxDatatableModule,
|
imports: [CommonModule, SharedModule, statsRouterModule, NgxChartsModule, NgxDatatableModule,
|
||||||
MatButtonModule, MatExpansionModule, MatButtonToggleModule, MatTableModule],
|
MatButtonModule, MatExpansionModule, MatButtonToggleModule, MatTableModule, MatSortModule],
|
||||||
providers: [WarService, CampaignService, PlayerService, LogsService]
|
providers: [WarService, CampaignService, PlayerService, LogsService]
|
||||||
})
|
})
|
||||||
export class StatsModule {
|
export class StatsModule {
|
||||||
|
|
|
@ -75,6 +75,10 @@ table.mat-table {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table.mat-table img {
|
||||||
|
filter: invert(60%);
|
||||||
|
}
|
||||||
|
|
||||||
.mat-column-name {
|
.mat-column-name {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
|
@ -84,6 +88,20 @@ table.mat-table {
|
||||||
|
|
||||||
.mat-column-kill, .mat-column-friendlyFire, .mat-column-revive, .mat-column-flagTouch,
|
.mat-column-kill, .mat-column-friendlyFire, .mat-column-revive, .mat-column-flagTouch,
|
||||||
.mat-column-vehicleLight, .mat-column-vehicleHeavy, .mat-column-vehicleAir, .mat-column-death, .mat-column-respawn {
|
.mat-column-vehicleLight, .mat-column-vehicleHeavy, .mat-column-vehicleAir, .mat-column-death, .mat-column-respawn {
|
||||||
width: 62px;
|
width: 67px;
|
||||||
text-align: center;
|
text-indent: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MAT FAB BUTTON */
|
||||||
|
|
||||||
|
button.mat-mini-fab {
|
||||||
|
color: #7b7b7b;
|
||||||
|
background: #ffffff;
|
||||||
|
width: 60px;
|
||||||
|
height: 35px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host/deep/span.mat-button-wrapper {
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
<div class="fade-in" style="overflow-x: auto">
|
<div class="fade-in" style="overflow-x: auto">
|
||||||
|
|
||||||
<table mat-table [dataSource]="rows" class="mat-elevation-z8">
|
<table mat-table matSort
|
||||||
|
[dataSource]="sortedRows"
|
||||||
|
matSortActive="{{tableHead[2].prop}}" matSortDirection="desc" matSortDisableClear (matSortChange)="sortData($event)"
|
||||||
|
class="mat-elevation-z8">
|
||||||
|
|
||||||
<ng-container matColumnDef="{{tableHead[0].prop}}">
|
<ng-container matColumnDef="{{tableHead[0].prop}}">
|
||||||
<th mat-header-cell *matHeaderCellDef> {{tableHead[0].head}} </th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header="{{tableHead[0].prop}}">{{tableHead[0].head}}</th>
|
||||||
<td mat-cell *matCellDef="let element"
|
<td mat-cell *matCellDef="let element"
|
||||||
[style.color]="element['fraction'] === 'BLUFOR' ? fraction.COLOR_BLUFOR : fraction.COLOR_OPFOR">
|
[style.color]="element['fraction'] === 'BLUFOR' ? fraction.COLOR_BLUFOR : fraction.COLOR_OPFOR">
|
||||||
{{element.name}}
|
{{element.name}}
|
||||||
|
@ -11,15 +14,30 @@
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="{{tableHead[1].prop}}">
|
<ng-container matColumnDef="{{tableHead[1].prop}}">
|
||||||
<th mat-header-cell *matHeaderCellDef> {{tableHead[1].head}} </th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header="{{tableHead[1].prop}}">{{tableHead[1].head}}</th>
|
||||||
<td mat-cell *matCellDef="let element"> {{element.fraction}}</td>
|
<td mat-cell *matCellDef="let element"> {{element.fraction}}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container *ngFor="let column of tableHead.slice(2, tableHead.length)" matColumnDef="{{column.prop}}">
|
<ng-container *ngFor="let column of tableHead.slice(2, tableHead.length)" matColumnDef="{{column.prop}}">
|
||||||
<th mat-header-cell *matHeaderCellDef> <img src="../../../../assets/scoreboard/{{column.prop}}.png" alt="{{column.head}}"> </th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header="{{column.prop}}">
|
||||||
|
<img src="../../../../assets/scoreboard/{{column.prop}}.png"
|
||||||
|
matTooltip="{{column.head}}"
|
||||||
|
alt="{{column.head}}">
|
||||||
|
</th>
|
||||||
<td mat-cell *matCellDef="let element"> {{element[column.prop]}}</td>
|
<td mat-cell *matCellDef="let element"> {{element[column.prop]}}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="interact">
|
||||||
|
<th mat-header-cell *matHeaderCellDef></th>
|
||||||
|
<td mat-cell *matCellDef="let element">
|
||||||
|
<button mat-mini-fab color="primary"
|
||||||
|
(click)="selectPlayerDetail(1, isSteamUUID(element['steamUUID']) ?
|
||||||
|
element['steamUUID'] : element['name'])">
|
||||||
|
Gesamt
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -3,6 +3,7 @@ import {War} from '../../../models/model-interfaces';
|
||||||
import {Fraction} from '../../../utils/fraction.enum';
|
import {Fraction} from '../../../utils/fraction.enum';
|
||||||
import {PlayerUtils} from '../../../utils/player-utils';
|
import {PlayerUtils} from '../../../utils/player-utils';
|
||||||
import {saveAs} from 'file-saver/FileSaver';
|
import {saveAs} from 'file-saver/FileSaver';
|
||||||
|
import {Sort} from '@angular/material';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'cc-scoreboard',
|
selector: 'cc-scoreboard',
|
||||||
|
@ -29,8 +30,9 @@ export class ScoreboardComponent implements OnChanges {
|
||||||
|
|
||||||
rows = [];
|
rows = [];
|
||||||
|
|
||||||
displayedColumns = //['name', 'fraction', 'kill', 'friendlyFire', 'revive', 'flagTouch', 'vehicleLight', 'vehicleHeavy', 'vehicleAir'];
|
sortedRows = [];
|
||||||
this.tableHead.map(head => head.prop);
|
|
||||||
|
displayedColumns = this.tableHead.map(head => head.prop);
|
||||||
|
|
||||||
reorderable = false;
|
reorderable = false;
|
||||||
|
|
||||||
|
@ -40,7 +42,7 @@ export class ScoreboardComponent implements OnChanges {
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(private elRef: ElementRef) {
|
constructor(private elRef: ElementRef) {
|
||||||
console.log(this.displayedColumns)
|
this.displayedColumns.push('interact');
|
||||||
}
|
}
|
||||||
|
|
||||||
selectPlayerDetail(view: number, player) {
|
selectPlayerDetail(view: number, player) {
|
||||||
|
@ -53,6 +55,7 @@ export class ScoreboardComponent implements OnChanges {
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
if (changes.war) {
|
if (changes.war) {
|
||||||
this.rows = changes.war.currentValue.players;
|
this.rows = changes.war.currentValue.players;
|
||||||
|
this.sortedRows = this.rows.slice();
|
||||||
// this.elRef.nativeElement
|
// this.elRef.nativeElement
|
||||||
// .querySelector('.datatable-body')
|
// .querySelector('.datatable-body')
|
||||||
// .scrollTo(0, 0);
|
// .scrollTo(0, 0);
|
||||||
|
@ -72,6 +75,24 @@ export class ScoreboardComponent implements OnChanges {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sortData(sort: Sort) {
|
||||||
|
const data = this.rows.slice();
|
||||||
|
if (!sort.active || sort.direction === '') {
|
||||||
|
this.sortedRows = data;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sortedRows = data.sort((a, b) => {
|
||||||
|
const isAsc = sort.direction === 'desc';
|
||||||
|
const sortProperty = sort.active;
|
||||||
|
return this.compare(a[sortProperty], b[sortProperty], isAsc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
compare(a, b, isAsc) {
|
||||||
|
return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
exportCSV() {
|
exportCSV() {
|
||||||
let csvOut = '';
|
let csvOut = '';
|
||||||
for (let i = 0; i < this.tableHead.length; i++) {
|
for (let i = 0; i < this.tableHead.length; i++) {
|
||||||
|
@ -100,5 +121,4 @@ export class ScoreboardComponent implements OnChanges {
|
||||||
const blob = new Blob([csvOut], {type: 'text/plain'});
|
const blob = new Blob([csvOut], {type: 'text/plain'});
|
||||||
saveAs(blob, this.war.title.toLowerCase().replace(' ', '_').concat('.csv'));
|
saveAs(blob, this.war.title.toLowerCase().replace(' ', '_').concat('.csv'));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue