Merge branch 'task/1.8.0-material-scoreboard' of hardi/opt-cc into release/v1.8.0
commit
612c894e6a
|
@ -644,11 +644,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@swimlane/ngx-datatable": {
|
|
||||||
"version": "13.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@swimlane/ngx-datatable/-/ngx-datatable-13.0.1.tgz",
|
|
||||||
"integrity": "sha512-jjMEzQhXcdD+jfKNp+7U61lWx9ZzSGDn9QbpY6pJOJwz+E2CKeek6OouT5Qcc4MY4oFL9g/SZoPjLf90cbNIRw=="
|
|
||||||
},
|
|
||||||
"@types/jasmine": {
|
"@types/jasmine": {
|
||||||
"version": "2.5.38",
|
"version": "2.5.38",
|
||||||
"resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.5.38.tgz",
|
"resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.5.38.tgz",
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
"@angular/platform-browser-dynamic": "^6.0.7",
|
"@angular/platform-browser-dynamic": "^6.0.7",
|
||||||
"@angular/router": "^6.0.7",
|
"@angular/router": "^6.0.7",
|
||||||
"@swimlane/ngx-charts": "^8.1.0",
|
"@swimlane/ngx-charts": "^8.1.0",
|
||||||
"@swimlane/ngx-datatable": "^13.0.1",
|
|
||||||
"bootstrap": "^3.3.7",
|
"bootstrap": "^3.3.7",
|
||||||
"d3": "^4.11.0",
|
"d3": "^4.11.0",
|
||||||
"file-saver": "^1.3.8",
|
"file-saver": "^1.3.8",
|
||||||
|
|
|
@ -42,6 +42,8 @@ export class AppComponent implements OnInit {
|
||||||
sanitizer.bypassSecurityTrustResourceUrl('../assets/icon/twotone-edit-24px.svg'));
|
sanitizer.bypassSecurityTrustResourceUrl('../assets/icon/twotone-edit-24px.svg'));
|
||||||
this.iconRegistry.addSvgIcon('delete',
|
this.iconRegistry.addSvgIcon('delete',
|
||||||
sanitizer.bypassSecurityTrustResourceUrl('../assets/icon/twotone-delete-24px.svg'));
|
sanitizer.bypassSecurityTrustResourceUrl('../assets/icon/twotone-delete-24px.svg'));
|
||||||
|
this.iconRegistry.addSvgIcon('stats-detail',
|
||||||
|
sanitizer.bypassSecurityTrustResourceUrl('../assets/icon/round-assessment-24px.svg'));
|
||||||
|
|
||||||
router.events.subscribe(event => {
|
router.events.subscribe(event => {
|
||||||
if (event instanceof NavigationStart) {
|
if (event instanceof NavigationStart) {
|
||||||
|
|
|
@ -11,71 +11,53 @@ h2 {
|
||||||
margin: 20px 0 0 10%;
|
margin: 20px 0 0 10%;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx-datatable {
|
.highscore-table-container {
|
||||||
width: 345px;
|
width: 320px;
|
||||||
margin: 3% 5% 0 5%;
|
max-height: 394px;
|
||||||
height: 310px;
|
margin: 100px 0 0 8%;
|
||||||
float: left;
|
float: left;
|
||||||
border: solid #dfdfdf 1px;
|
|
||||||
border-radius: 10px 10px 2px 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host /deep/ .datatable-header {
|
|
||||||
width: 350px !important;
|
|
||||||
background: #222222;
|
|
||||||
font-weight: 700;
|
|
||||||
border-radius: 10px 10px 0 0;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host /deep/ span.datatable-header-cell-label, :host /deep/ div.datatable-body-cell-label {
|
|
||||||
padding-left: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host /deep/ .ngx-datatable .datatable-header {
|
|
||||||
/*vertical center alignment*/
|
|
||||||
display: table-cell;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host /deep/ .ngx-datatable .datatable-body .datatable-body-row > div {
|
|
||||||
/*vertical alignment*/
|
|
||||||
position: relative;
|
|
||||||
top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host /deep/ .datatable-body {
|
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
border: solid #dfdfdf 1px;
|
||||||
|
box-shadow: 3px 3px 1px -2px rgba(0,0,0,.2), 0 2px 2px 0 rgba(0,0,0,.14), 0 1px 5px 0 rgba(0,0,0,.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
:host /deep/ .datatable-body-row {
|
.highscore-table {
|
||||||
color: #222222;
|
width: 100%;
|
||||||
border-bottom: 1px solid grey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:host /deep/ .datatable-body-row:hover {
|
table.mat-table img {
|
||||||
background-color: #f7f7f7;
|
filter: invert(60%);
|
||||||
|
margin-left: -15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host /deep/ .ngx-datatable.fixed-header .datatable-header .datatable-header-inner .datatable-header-cell {
|
:host /deep/ table.mat-table > thead {
|
||||||
margin: auto;
|
position: absolute;
|
||||||
|
width: 320px;
|
||||||
|
display: inherit;
|
||||||
|
margin-left: -1px;
|
||||||
|
margin-top: -57px;
|
||||||
|
border: 1px solid #dadada;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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 {
|
||||||
|
width: 67px;
|
||||||
|
text-indent: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Table Scrollbar BEGIN */
|
/* Table Scrollbar BEGIN */
|
||||||
|
|
||||||
:host /deep/ .ngx-datatable.scroll-vertical .datatable-body::-webkit-scrollbar {
|
.highscore-table-container::-webkit-scrollbar {
|
||||||
width: 12px;
|
width: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host /deep/ .ngx-datatable.scroll-vertical .datatable-body::-webkit-scrollbar-track {
|
.highscore-table-container::-webkit-scrollbar-track {
|
||||||
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
|
border-left: 1px solid #f1f1f1;
|
||||||
border-radius: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:host /deep/ .ngx-datatable.scroll-vertical .datatable-body::-webkit-scrollbar-thumb {
|
.highscore-table-container::-webkit-scrollbar-thumb {
|
||||||
border-radius: 10px;
|
background: rgb(234, 234, 234);
|
||||||
background: #4b4b4b;
|
|
||||||
-webkit-box-shadow: inset 0 0 6px rgba(255, 255, 255, 0.5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Table Scrollbar END */
|
/* Table Scrollbar END */
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
<div class="input-group search-field">
|
<div class="input-group search-field">
|
||||||
<input id="search-tasks"
|
<input id="search-tasks"
|
||||||
|
markForCheck
|
||||||
placeholder="Spielername (mehrere mit '&' trennen)"
|
placeholder="Spielername (mehrere mit '&' trennen)"
|
||||||
type="text" #query class="form-control"
|
type="text" #query class="form-control"
|
||||||
(keyup.enter)="filterPlayers()"
|
(keyup.enter)="filterPlayers()"
|
||||||
|
@ -16,41 +17,37 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngFor="let attributeMap of playerAttributeDisplayNames">
|
<div *ngFor="let attributeMap of playerAttributeDisplayNames">
|
||||||
<ngx-datatable
|
<div class="highscore-table-container">
|
||||||
[rows]="players[attributeMap.prop]"
|
<table mat-table matSort
|
||||||
[messages]="emptyMessage"
|
[dataSource]="players[attributeMap.prop]"
|
||||||
[headerHeight]="cellHeight"
|
class="mat-elevation-z8 highscore-table">
|
||||||
[rowHeight]="cellHeight"
|
|
||||||
[cssClasses]='customClasses'
|
|
||||||
[columnMode]="'force'"
|
|
||||||
[scrollbarV]="true"
|
|
||||||
[selectionType]="'single'">
|
|
||||||
<ngx-datatable-column [width]="numberColWidth" name="#" prop="num"></ngx-datatable-column>
|
|
||||||
<ngx-datatable-column name="Spieler" prop="name" [width]="nameColWidth" style="padding-left:10px">
|
|
||||||
<ng-template ngx-datatable-cell-template let-row="row" let-value="value">
|
|
||||||
<span class="player-name"
|
|
||||||
[style.color]="row['fraction'] === 'BLUFOR' ? fraction.COLOR_BLUFOR : fraction.COLOR_OPFOR">
|
|
||||||
{{value}}
|
|
||||||
</span>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
|
|
||||||
<ngx-datatable-column [width]="valueColWidth" prop="{{attributeMap.prop}}">
|
<ng-container matColumnDef="num">
|
||||||
<ng-template ngx-datatable-header-template let-sort="sortFn">
|
<th mat-header-cell *matHeaderCellDef>#</th>
|
||||||
<span class="datatable-header-cell-wrapper">
|
<td mat-cell *matCellDef="let element">{{element.num}}</td>
|
||||||
<span class="datatable-header-cell-label text-truncate" matTooltip="{{attributeMap.head}}" (click)="sort()">
|
</ng-container>
|
||||||
<img src="../../../../assets/scoreboard/{{attributeMap.prop}}.png" alt="{{attributeMap.head}}">
|
|
||||||
</span>
|
<ng-container matColumnDef="name">
|
||||||
</span>
|
<th mat-header-cell *matHeaderCellDef>Name</th>
|
||||||
</ng-template>
|
<td mat-cell *matCellDef="let element"
|
||||||
<ng-template ngx-datatable-cell-template let-row="row" let-value="value">
|
[style.color]="element['fraction'] === 'BLUFOR' ? fraction.COLOR_BLUFOR : fraction.COLOR_OPFOR">
|
||||||
<span style="padding-left: 7px;">
|
{{element.name}}
|
||||||
{{value}}
|
</td>
|
||||||
</span>
|
</ng-container>
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
<ng-container matColumnDef="{{attributeMap.prop}}">
|
||||||
</ngx-datatable>
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
|
<img src="../../../../assets/scoreboard/{{attributeMap.prop}}.png"
|
||||||
|
matTooltip="{{attributeMap.head}}"
|
||||||
|
alt="{{attributeMap.head}}">
|
||||||
|
</th>
|
||||||
|
<td mat-cell *matCellDef="let element"> {{element[attributeMap.prop]}}</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<tr mat-header-row *matHeaderRowDef="['num', 'name', attributeMap.prop];"></tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: ['num', 'name', attributeMap.prop];"></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -30,21 +30,6 @@ export class StatisticHighScoreComponent implements OnInit {
|
||||||
|
|
||||||
playerAttributeDisplayNames = PlayerUtils.attributeDisplayNames.slice(2, PlayerUtils.attributeDisplayNames.length);
|
playerAttributeDisplayNames = PlayerUtils.attributeDisplayNames.slice(2, PlayerUtils.attributeDisplayNames.length);
|
||||||
|
|
||||||
cellHeight = 40;
|
|
||||||
|
|
||||||
numberColWidth = 60;
|
|
||||||
|
|
||||||
nameColWidth = 210;
|
|
||||||
|
|
||||||
valueColWidth = 55;
|
|
||||||
|
|
||||||
emptyMessage = {emptyMessage: 'Keine Einträge'};
|
|
||||||
|
|
||||||
customClasses = {
|
|
||||||
sortAscending: 'glyphicon glyphicon-triangle-top',
|
|
||||||
sortDescending: 'glyphicon glyphicon-triangle-bottom',
|
|
||||||
};
|
|
||||||
|
|
||||||
readonly fraction = Fraction;
|
readonly fraction = Fraction;
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute,
|
constructor(private route: ActivatedRoute,
|
||||||
|
@ -97,7 +82,6 @@ export class StatisticHighScoreComponent implements OnInit {
|
||||||
|
|
||||||
private filterPlayerAttribute(attribute) {
|
private filterPlayerAttribute(attribute) {
|
||||||
const query = this.searchTerm.value.toLowerCase().split('&');
|
const query = this.searchTerm.value.toLowerCase().split('&');
|
||||||
|
|
||||||
return this.playersStored[attribute].filter(player => {
|
return this.playersStored[attribute].filter(player => {
|
||||||
for (let i = 0; i < query.length; i++) {
|
for (let i = 0; i < query.length; i++) {
|
||||||
if (query[i].trim() !== '' && player.name.toLowerCase().includes(query[i].trim())) {
|
if (query[i].trim() !== '' && player.name.toLowerCase().includes(query[i].trim())) {
|
||||||
|
@ -107,5 +91,4 @@ export class StatisticHighScoreComponent implements OnInit {
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,15 +5,15 @@ import {statsRouterModule, statsRoutingComponents} from './stats.routing';
|
||||||
import {WarService} from '../services/logs/war.service';
|
import {WarService} from '../services/logs/war.service';
|
||||||
import {NgxChartsModule} from '@swimlane/ngx-charts';
|
import {NgxChartsModule} from '@swimlane/ngx-charts';
|
||||||
import {CampaignService} from '../services/logs/campaign.service';
|
import {CampaignService} from '../services/logs/campaign.service';
|
||||||
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} 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, MatButtonModule, MatExpansionModule,
|
||||||
MatButtonModule, MatExpansionModule, MatButtonToggleModule],
|
MatButtonToggleModule, MatTableModule, MatSortModule],
|
||||||
providers: [WarService, CampaignService, PlayerService, LogsService]
|
providers: [WarService, CampaignService, PlayerService, LogsService]
|
||||||
})
|
})
|
||||||
export class StatsModule {
|
export class StatsModule {
|
||||||
|
|
|
@ -1,32 +1,30 @@
|
||||||
.chart-select-group {
|
.chart-select-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 945px;
|
width: fit-content;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chart-select-group > mat-button-toggle {
|
:host /deep/ mat-button-toggle {
|
||||||
background: #4b4b4b;
|
color: #666666;
|
||||||
color: #f5f5f5;
|
background: #e7e7e7;
|
||||||
border: 1px solid #000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chart-select-group > mat-button-toggle:hover {
|
:host /deep/ mat-button-toggle:hover {
|
||||||
background: #afafaf;
|
background: #afafaf;
|
||||||
color: #f5f5f5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mat-button-toggle.mat-button-toggle-checked {
|
:host /deep/ mat-button-toggle.mat-button-toggle-checked {
|
||||||
background: #222222 !important;
|
background: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host /deep/ label.mat-button-toggle-label {
|
:host /deep/ label.mat-button-toggle-label {
|
||||||
margin: 2px 0 !important;
|
margin: 2px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host /deep/ div.mat-button-toggle-label-content {
|
:host /deep/ div.mat-button-toggle-label-content {
|
||||||
line-height: 25px !important;
|
line-height: 25px;
|
||||||
margin-bottom: 0 !important;
|
margin-bottom: 0;
|
||||||
font-weight: normal !important;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chart-container {
|
.chart-container {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="fade-in" xmlns="http://www.w3.org/1999/html">
|
<div class="fade-in" style="border-top: 1px solid #dadada; padding-top:25px;" xmlns="http://www.w3.org/1999/html">
|
||||||
|
|
||||||
<mat-button-toggle-group class="chart-select-group"
|
<mat-button-toggle-group class="chart-select-group"
|
||||||
#group="matButtonToggleGroup"
|
#group="matButtonToggleGroup"
|
||||||
|
|
|
@ -1,71 +1,62 @@
|
||||||
.player-name {
|
.scoreboard-table {
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ########### DATATABLE ########### */
|
|
||||||
|
|
||||||
ngx-datatable {
|
|
||||||
width: 940px;
|
|
||||||
margin: auto;
|
|
||||||
height: 68vh;
|
height: 68vh;
|
||||||
|
width:fit-content;
|
||||||
|
border: 1px solid #dadada;
|
||||||
|
overflow-x: auto;
|
||||||
|
margin:auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host /deep/ .datatable-header {
|
|
||||||
width: 1100px !important;
|
|
||||||
background: #222222;
|
|
||||||
font-weight: 700;
|
|
||||||
border-radius: 10px 10px 0 0;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host /deep/ span.datatable-header-cell-label, :host /deep/ div.datatable-body-cell-label {
|
|
||||||
padding-left: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host /deep/ .ngx-datatable .datatable-header {
|
|
||||||
/*vertical center alignment*/
|
|
||||||
display: table-cell;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host /deep/ .ngx-datatable .datatable-body .datatable-body-row > div {
|
|
||||||
/*vertical alignment*/
|
|
||||||
position: relative;
|
|
||||||
top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host /deep/ .datatable-body-row {
|
|
||||||
color: #222222;
|
|
||||||
border-bottom: 1px solid grey;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host /deep/ .datatable-body-row:hover {
|
|
||||||
background-color: #f7f7f7;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host /deep/ .ngx-datatable.fixed-header .datatable-header .datatable-header-inner .datatable-header-cell {
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Table Scrollbar BEGIN */
|
|
||||||
:host /deep/ .ngx-datatable.scroll-vertical .datatable-body::-webkit-scrollbar {
|
|
||||||
width: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host /deep/ .ngx-datatable.scroll-vertical .datatable-body::-webkit-scrollbar-track {
|
|
||||||
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host /deep/ .ngx-datatable.scroll-vertical .datatable-body::-webkit-scrollbar-thumb {
|
|
||||||
border-radius: 10px;
|
|
||||||
background: #4b4b4b;
|
|
||||||
-webkit-box-shadow: inset 0 0 6px rgba(255, 255, 255, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Table Scrollbar END */
|
|
||||||
|
|
||||||
.in-table-btn {
|
.in-table-btn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
margin-top: -5px;
|
margin-top: -5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* MATERIAL TABLE */
|
||||||
|
table.mat-table {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.mat-table img {
|
||||||
|
filter: invert(60%);
|
||||||
|
}
|
||||||
|
|
||||||
|
:host /deep/ table.mat-table > thead {
|
||||||
|
position: absolute;
|
||||||
|
display: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host /deep/ table.mat-table > tbody {
|
||||||
|
margin-top: 60px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-column-name {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
.mat-column-fraction {
|
||||||
|
width: 90px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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 {
|
||||||
|
width: 67px;
|
||||||
|
text-indent: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
th.mat-column-interact {
|
||||||
|
padding-left: 36px;
|
||||||
|
background: white;
|
||||||
|
position: relative;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TABLE SCROLLBAR */
|
||||||
|
div::-webkit-scrollbar-thumb {
|
||||||
|
border-top: solid white 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MAT ICON BUTTON */
|
||||||
|
|
||||||
|
:host/deep/.mat-table .mat-icon {
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
|
@ -1,47 +1,47 @@
|
||||||
<div class="fade-in" style="overflow-x: auto" xmlns="http://www.w3.org/1999/html">
|
<div class="fade-in scoreboard-table">
|
||||||
<ngx-datatable
|
|
||||||
[rows]="rows"
|
|
||||||
[sorts]="[{prop: 'kill', dir: 'desc'}]"
|
|
||||||
[reorderable]="reorderable"
|
|
||||||
[messages]="{emptyMessage: 'Loading...'}"
|
|
||||||
[headerHeight]="cellHeight"
|
|
||||||
[rowHeight]="cellHeight"
|
|
||||||
[cssClasses]='customClasses'
|
|
||||||
[columnMode]="'force'"
|
|
||||||
[scrollbarV]="true"
|
|
||||||
[selectionType]="'single'">
|
|
||||||
<ngx-datatable-column name="{{tableHead[0].head}}" prop="name" [width]="210" style="padding-left:10px">
|
|
||||||
<ng-template ngx-datatable-cell-template let-row="row" let-value="value">
|
|
||||||
<span class="player-name"
|
|
||||||
[style.color]="row['fraction'] === 'BLUFOR' ? fraction.COLOR_BLUFOR : fraction.COLOR_OPFOR">
|
|
||||||
{{value}}
|
|
||||||
</span>
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
<ngx-datatable-column name="{{tableHead[1].head}}" prop="fraction" [width]="90">
|
|
||||||
<ng-template ngx-datatable-cell-template let-value="value">
|
|
||||||
{{value === 'BLUFOR' ? fraction.BLUFOR : fraction.OPFOR}}
|
|
||||||
</ng-template>
|
|
||||||
</ngx-datatable-column>
|
|
||||||
|
|
||||||
<div *ngFor="let column of tableHead.slice(2, tableHead.length) ">
|
<table mat-table matSort
|
||||||
<ngx-datatable-column [width]="columnWidth" prop="{{column.prop}}">
|
[dataSource]="sortedRows"
|
||||||
<ng-template ngx-datatable-header-template let-sort="sortFn">
|
matSortActive="{{tableHead[2].prop}}" matSortDirection="asc" matSortDisableClear
|
||||||
<span class="datatable-header-cell-wrapper">
|
(matSortChange)="sortScoreboardData($event)"
|
||||||
<span class="datatable-header-cell-label text-truncate" title="{{column.head}}" (click)="sort()">
|
class="mat-elevation-z8">
|
||||||
<img src="../../../../assets/scoreboard/{{column.prop}}.png" alt="{{column.head}}">
|
|
||||||
</span>
|
<ng-container matColumnDef="{{tableHead[0].prop}}">
|
||||||
</span>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header="{{tableHead[0].prop}}">{{tableHead[0].head}}</th>
|
||||||
</ng-template>
|
<td mat-cell *matCellDef="let element"
|
||||||
</ngx-datatable-column>
|
[style.color]="element['fraction'] === 'BLUFOR' ? fraction.COLOR_BLUFOR : fraction.COLOR_OPFOR">
|
||||||
</div>
|
{{element.name}}
|
||||||
<ngx-datatable-column [width]="80">
|
</td>
|
||||||
<ng-template ngx-datatable-cell-template let-row="row">
|
</ng-container>
|
||||||
<span class="btn btn-sm btn-default in-table-btn"
|
|
||||||
(click)="selectPlayerDetail(1, isSteamUUID(row['steamUUID']) ? row['steamUUID'] : row['name'])">
|
<ng-container matColumnDef="{{tableHead[1].prop}}">
|
||||||
Gesamt
|
<th mat-header-cell *matHeaderCellDef mat-sort-header="{{tableHead[1].prop}}">{{tableHead[1].head}}</th>
|
||||||
</span>
|
<td mat-cell *matCellDef="let element"> {{element.fraction}}</td>
|
||||||
</ng-template>
|
</ng-container>
|
||||||
</ngx-datatable-column>
|
|
||||||
</ngx-datatable>
|
<ng-container *ngFor="let column of tableHead.slice(2, tableHead.length)" matColumnDef="{{column.prop}}">
|
||||||
|
<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>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="interact">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> </th>
|
||||||
|
<td mat-cell *matCellDef="let element">
|
||||||
|
<button mat-icon-button
|
||||||
|
matTooltip="Kampagnenstatistik für {{element.name}}"
|
||||||
|
(click)="selectPlayerDetail(1, isSteamUUID(element['steamUUID']) ?
|
||||||
|
element['steamUUID'] : element['name'])">
|
||||||
|
<mat-icon svgIcon="stats-detail">
|
||||||
|
</mat-icon>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,6 +3,8 @@ 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 {MatSort, Sort} from '@angular/material';
|
||||||
|
import {SortUtils} from '../../../utils/sort-utils';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'cc-scoreboard',
|
selector: 'cc-scoreboard',
|
||||||
|
@ -29,6 +31,12 @@ export class ScoreboardComponent implements OnChanges {
|
||||||
|
|
||||||
rows = [];
|
rows = [];
|
||||||
|
|
||||||
|
sortedRows = [];
|
||||||
|
|
||||||
|
currentSort = new MatSort();
|
||||||
|
|
||||||
|
displayedColumns = this.tableHead.map(head => head.prop);
|
||||||
|
|
||||||
reorderable = false;
|
reorderable = false;
|
||||||
|
|
||||||
customClasses = {
|
customClasses = {
|
||||||
|
@ -37,6 +45,7 @@ export class ScoreboardComponent implements OnChanges {
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(private elRef: ElementRef) {
|
constructor(private elRef: ElementRef) {
|
||||||
|
this.displayedColumns.push('interact');
|
||||||
}
|
}
|
||||||
|
|
||||||
selectPlayerDetail(view: number, player) {
|
selectPlayerDetail(view: number, player) {
|
||||||
|
@ -49,9 +58,11 @@ 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.elRef.nativeElement
|
this.currentSort.active = 'kill';
|
||||||
.querySelector('.datatable-body')
|
this.sortScoreboardData(this.currentSort);
|
||||||
.scrollTo(0, 0);
|
// this.elRef.nativeElement
|
||||||
|
// .querySelector('.datatable-body')
|
||||||
|
// .scrollTo(0, 0);
|
||||||
}
|
}
|
||||||
if (changes.fractionFilterSelected) {
|
if (changes.fractionFilterSelected) {
|
||||||
this.filterPlayersByFraction(this.fractionFilterSelected);
|
this.filterPlayersByFraction(this.fractionFilterSelected);
|
||||||
|
@ -66,6 +77,24 @@ export class ScoreboardComponent implements OnChanges {
|
||||||
} else {
|
} else {
|
||||||
this.rows = this.war.players;
|
this.rows = this.war.players;
|
||||||
}
|
}
|
||||||
|
this.sortScoreboardData(this.currentSort);
|
||||||
|
}
|
||||||
|
|
||||||
|
sortScoreboardData(sort: MatSort) {
|
||||||
|
if (sort) {
|
||||||
|
this.currentSort = 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 SortUtils.compare(a[sortProperty], b[sortProperty], isAsc);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
exportCSV() {
|
exportCSV() {
|
||||||
|
@ -96,5 +125,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'));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,12 +19,19 @@ span.tab-control {
|
||||||
padding: 4px 16px;
|
padding: 4px 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.war-header {
|
.nav-tabs > li.active > a {
|
||||||
border-bottom: thin solid lightgrey;
|
background: #ffffff;
|
||||||
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs > li.active > a {
|
.nav-tabs > li.active {
|
||||||
background: #222222;
|
position: relative;
|
||||||
|
top: 1px;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs > li img {
|
||||||
|
filter: invert(50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs {
|
.nav-tabs {
|
||||||
|
@ -35,12 +42,12 @@ span.tab-control {
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs > li > a {
|
.nav-tabs > li > a {
|
||||||
background: #4b4b4b;
|
background: #e7e7e7;
|
||||||
|
border: 1px solid #dadada;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs > li:not(.active) > a:hover {
|
.nav-tabs > li:not(.active) > a:hover {
|
||||||
background: #afafaf;
|
background: #afafaf;
|
||||||
color: #f5f5f5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs > li:last-child {
|
.nav-tabs > li:last-child {
|
||||||
|
@ -49,7 +56,7 @@ span.tab-control {
|
||||||
|
|
||||||
.nav-link {
|
.nav-link {
|
||||||
cursor: pointer !important;
|
cursor: pointer !important;
|
||||||
color: #FFF !important;
|
color: #666666 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs > li.deactivated > a.nav-link {
|
.nav-tabs > li.deactivated > a.nav-link {
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
export class SortUtils {
|
||||||
|
|
||||||
|
public static compare(a, b, isAsc) {
|
||||||
|
return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="24px"
|
||||||
|
height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
||||||
|
<g id="Header_x2F_BG" display="none">
|
||||||
|
<rect x="-50" y="-138" display="inline" fill="#F1F1F2" width="520" height="520"/>
|
||||||
|
</g>
|
||||||
|
<g id="Bounding_Boxes">
|
||||||
|
<g id="ui_x5F_spec_x5F_header_copy_3">
|
||||||
|
</g>
|
||||||
|
<path fill="none" d="M0,0h24v24H0V0z"/>
|
||||||
|
</g>
|
||||||
|
<g id="Rounded">
|
||||||
|
<g id="ui_x5F_spec_x5F_header_copy_5">
|
||||||
|
</g>
|
||||||
|
<path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M8,17L8,17c-0.55,0-1-0.45-1-1v-5
|
||||||
|
c0-0.55,0.45-1,1-1h0c0.55,0,1,0.45,1,1v5C9,16.55,8.55,17,8,17z M12,17L12,17c-0.55,0-1-0.45-1-1V8c0-0.55,0.45-1,1-1h0
|
||||||
|
c0.55,0,1,0.45,1,1v8C13,16.55,12.55,17,12,17z M16,17L16,17c-0.55,0-1-0.45-1-1v-2c0-0.55,0.45-1,1-1h0c0.55,0,1,0.45,1,1v2
|
||||||
|
C17,16.55,16.55,17,16,17z"/>
|
||||||
|
</g>
|
||||||
|
<g id="Sharp" display="none">
|
||||||
|
<g id="ui_x5F_spec_x5F_header_copy_4" display="inline">
|
||||||
|
</g>
|
||||||
|
<path display="inline" d="M21,3H3v18h18V3z M9,17H7v-7h2V17z M13,17h-2V7h2V17z M17,17h-2v-4h2V17z"/>
|
||||||
|
</g>
|
||||||
|
<g id="Outline" display="none">
|
||||||
|
<g id="ui_x5F_spec_x5F_header" display="inline">
|
||||||
|
</g>
|
||||||
|
<g display="inline">
|
||||||
|
<path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M19,19H5V5h14V19z"/>
|
||||||
|
<rect x="7" y="10" width="2" height="7"/>
|
||||||
|
<rect x="11" y="7" width="2" height="10"/>
|
||||||
|
<rect x="15" y="13" width="2" height="4"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g id="Duotone" display="none">
|
||||||
|
<g id="ui_x5F_spec_x5F_header_copy_2" display="inline">
|
||||||
|
</g>
|
||||||
|
<g display="inline">
|
||||||
|
<path opacity="0.3" d="M5,5v14h14V5H5z M9,17H7v-7h2V17z M13,17h-2V7h2V17z M17,17h-2v-4h2V17z"/>
|
||||||
|
<g>
|
||||||
|
<path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M19,19H5V5h14V19z"/>
|
||||||
|
<rect x="7" y="10" width="2" height="7"/>
|
||||||
|
<rect x="11" y="7" width="2" height="10"/>
|
||||||
|
<rect x="15" y="13" width="2" height="4"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g id="Fill" display="none">
|
||||||
|
<g id="ui_x5F_spec_x5F_header_copy" display="inline">
|
||||||
|
</g>
|
||||||
|
<path display="inline" d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M9,17H7v-7h2V17z
|
||||||
|
M13,17h-2V7h2V17z M17,17h-2v-4h2V17z"/>
|
||||||
|
</g>
|
||||||
|
<g id="nyt_x5F_exporter_x5F_info" display="none">
|
||||||
|
<g display="inline">
|
||||||
|
<path d="M20-7.4l1.27,3.43c0.13,0.38,0.28,0.84,0.37,1.19h0.02C21.78-3.14,21.9-3.58,22.04-4l1.15-3.41h1.12l-1.58,4.14
|
||||||
|
c-0.76,1.99-1.27,3.01-1.99,3.63C20.22,0.82,19.7,1,19.44,1.05l-0.26-0.89c0.26-0.08,0.61-0.25,0.92-0.52
|
||||||
|
c0.29-0.23,0.65-0.64,0.89-1.18c0.05-0.11,0.08-0.19,0.08-0.25c0-0.06-0.02-0.14-0.07-0.28L18.85-7.4H20z"/>
|
||||||
|
<path d="M5.88,9.29l5.56-2.87v0.83L6.75,9.6v0.02l4.69,2.35v0.83L5.88,9.93V9.29z"/>
|
||||||
|
<path d="M13.12,8.57c0-0.6-0.01-1.09-0.05-1.57H14l0.06,0.96h0.02c0.29-0.55,0.96-1.09,1.92-1.09c0.8,0,2.05,0.48,2.05,2.47v3.47
|
||||||
|
H17V9.45c0-0.94-0.35-1.71-1.34-1.71c-0.7,0-1.24,0.49-1.42,1.08c-0.05,0.13-0.07,0.31-0.07,0.49v3.49h-1.06V8.57z"/>
|
||||||
|
<path d="M20,7l1.27,3.43c0.13,0.38,0.28,0.84,0.37,1.19h0.02c0.11-0.35,0.23-0.79,0.37-1.21L23.19,7h1.12l-1.58,4.14
|
||||||
|
c-0.76,1.99-1.27,3.01-1.99,3.63c-0.52,0.46-1.03,0.64-1.29,0.68l-0.26-0.89c0.26-0.08,0.61-0.25,0.92-0.52
|
||||||
|
c0.29-0.23,0.65-0.64,0.89-1.18c0.05-0.11,0.08-0.19,0.08-0.25c0-0.06-0.02-0.14-0.07-0.28L18.85,7H20z"/>
|
||||||
|
<path d="M0.79,23.69l5.56-2.87v0.83L1.67,24v0.02l4.69,2.35v0.83l-5.56-2.87V23.69z"/>
|
||||||
|
<path d="M7.14,27.68l3.35-8.69h0.82l-3.36,8.69H7.14z"/>
|
||||||
|
<path d="M12.14,22.97c0-0.6-0.01-1.09-0.05-1.57h0.94l0.06,0.96h0.02c0.29-0.55,0.96-1.09,1.92-1.09c0.8,0,2.05,0.48,2.05,2.47
|
||||||
|
v3.47h-1.06v-3.35c0-0.94-0.35-1.71-1.34-1.71c-0.7,0-1.24,0.49-1.42,1.08c-0.05,0.13-0.07,0.31-0.07,0.49v3.49h-1.06V22.97z"/>
|
||||||
|
<path d="M19.03,21.4l1.27,3.43c0.13,0.38,0.28,0.84,0.37,1.19h0.02c0.11-0.35,0.23-0.79,0.37-1.21l1.15-3.41h1.12l-1.58,4.14
|
||||||
|
c-0.76,1.99-1.27,3.01-1.99,3.63c-0.52,0.46-1.03,0.64-1.29,0.68l-0.26-0.89c0.26-0.08,0.61-0.25,0.92-0.52
|
||||||
|
c0.29-0.23,0.65-0.64,0.89-1.18c0.05-0.11,0.08-0.19,0.08-0.25c0-0.06-0.02-0.14-0.07-0.28l-2.15-5.35H19.03z"/>
|
||||||
|
<path d="M25.57,19.73v1.67h1.51v0.8h-1.51v3.13c0,0.72,0.2,1.13,0.79,1.13c0.28,0,0.48-0.04,0.61-0.07l0.05,0.79
|
||||||
|
c-0.2,0.08-0.53,0.14-0.94,0.14c-0.49,0-0.89-0.16-1.14-0.44c-0.3-0.31-0.41-0.83-0.41-1.51V22.2h-0.9v-0.8h0.9V20L25.57,19.73z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.4 KiB |
Loading…
Reference in New Issue