Merge branch 'release/1.6.7' of hardi/opt-cc into master
commit
3e78921372
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
// modules
|
// modules
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const logger = require('debug')('cc:wars');
|
const logger = require('debug')('cc:players');
|
||||||
|
|
||||||
// HTTP status codes by name
|
// HTTP status codes by name
|
||||||
const codes = require('./http-codes');
|
const codes = require('./http-codes');
|
||||||
|
@ -17,7 +17,65 @@ const WarModel = require('../models/war');
|
||||||
const campaignPlayer = express.Router();
|
const campaignPlayer = express.Router();
|
||||||
|
|
||||||
// routes **********************
|
// routes **********************
|
||||||
campaignPlayer.route('/:campaignId/:playerName')
|
campaignPlayer.route('/ranking/:campaignId')
|
||||||
|
.get((req, res, next) => {
|
||||||
|
WarModel.find({campaign: req.params.campaignId}, '_id', (err, wars) => {
|
||||||
|
if (err) return next(err);
|
||||||
|
const warIds = wars.map((obj) => {
|
||||||
|
return obj._id;
|
||||||
|
});
|
||||||
|
PlayerModel.find({warId: {"$in": warIds}}, (err, items) => {
|
||||||
|
if (err) return next(err);
|
||||||
|
if (!items || items.length === 0) {
|
||||||
|
const err = new Error('No players for given campaignId');
|
||||||
|
err.status = codes.notfound;
|
||||||
|
return next(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const rankingItems = [];
|
||||||
|
new Set(items.map(x => x.name)).forEach(playerName => {
|
||||||
|
const playerInstances = items.filter(p => p.name === playerName);
|
||||||
|
const resItem = {name: playerName, kill: 0, death: 0, friendlyFire: 0, revive: 0, respawn: 0, flagTouch: 0};
|
||||||
|
for (let i = 0; i < playerInstances.length; i++) {
|
||||||
|
resItem.kill += playerInstances[i].kill;
|
||||||
|
resItem.death += playerInstances[i].death;
|
||||||
|
resItem.friendlyFire += playerInstances[i].friendlyFire;
|
||||||
|
resItem.revive += playerInstances[i].revive;
|
||||||
|
resItem.respawn += playerInstances[i].respawn;
|
||||||
|
resItem.flagTouch += playerInstances[i].flagTouch;
|
||||||
|
}
|
||||||
|
resItem.fraction = playerInstances[playerInstances.length - 1].fraction;
|
||||||
|
rankingItems.push(resItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
function getSortedField(fieldName) {
|
||||||
|
let num = 1;
|
||||||
|
rankingItems.sort((a, b) => b[fieldName] - a[fieldName])
|
||||||
|
const res = JSON.parse(JSON.stringify(rankingItems));
|
||||||
|
for (const entity of res) {
|
||||||
|
entity.num = num++;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.locals.items = {
|
||||||
|
kill: getSortedField('kill'),
|
||||||
|
death: getSortedField('death'),
|
||||||
|
friendlyFire: getSortedField('friendlyFire'),
|
||||||
|
revive: getSortedField('revive'),
|
||||||
|
respawn: getSortedField('respawn'),
|
||||||
|
flagTouch: getSortedField('flagTouch')
|
||||||
|
};
|
||||||
|
next();
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
.all(
|
||||||
|
routerHandling.httpMethodNotAllowed
|
||||||
|
);
|
||||||
|
|
||||||
|
campaignPlayer.route('/single/:campaignId/:playerName')
|
||||||
.get((req, res, next) => {
|
.get((req, res, next) => {
|
||||||
CampaignModel.findById(req.params.campaignId, (err, campaign) => {
|
CampaignModel.findById(req.params.campaignId, (err, campaign) => {
|
||||||
if (err) return next(err);
|
if (err) return next(err);
|
||||||
|
@ -31,7 +89,7 @@ campaignPlayer.route('/:campaignId/:playerName')
|
||||||
.exec((err, items) => {
|
.exec((err, items) => {
|
||||||
if (err) return next(err);
|
if (err) return next(err);
|
||||||
if (!items || items.length === 0) {
|
if (!items || items.length === 0) {
|
||||||
const err = new Error('unknown player name');
|
const err = new Error('Unknown player name');
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
return next(err)
|
return next(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "opt-cc",
|
"name": "opt-cc",
|
||||||
"version": "1.6.3",
|
"version": "1.6.7",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "opt-cc",
|
"name": "opt-cc",
|
||||||
"version": "1.6.6",
|
"version": "1.6.7",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": "Florian Hartwich <hardi@noarch.de>",
|
"author": "Florian Hartwich <hardi@noarch.de>",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
"start": "npm run deploy-static-prod && npm start --prefix ./api",
|
"start": "npm run deploy-static-prod && npm start --prefix ./api",
|
||||||
"dev": "npm run deploy-static && npm run dev --prefix ./api",
|
"dev": "npm run deploy-static && npm run dev --prefix ./api",
|
||||||
"deploy-static": "cd ./static && $(npm bin)/ng build && ln -s ../api/resource/ ../public/resource",
|
"deploy-static": "cd ./static && $(npm bin)/ng build && ln -s ../api/resource/ ../public/resource",
|
||||||
"deploy-static-prod": "cd ./static && $(npm bin)/ng build --prod --aot && ln -s ../api/resource/ ../public/resource",
|
"deploy-static:prod": "cd ./static && $(npm bin)/ng build --prod --aot && ln -s ../api/resource/ ../public/resource",
|
||||||
"postinstall": "npm install --prefix ./static && npm install --prefix ./api",
|
"postinstall": "npm install --prefix ./static && npm install --prefix ./api",
|
||||||
"mongodb": "mkdir -p mongodb-data && mongod --dbpath ./mongodb-data",
|
"mongodb": "mkdir -p mongodb-data && mongod --dbpath ./mongodb-data",
|
||||||
"test": "npm test --prefix ./api",
|
"test": "npm test --prefix ./api",
|
||||||
|
|
|
@ -35,4 +35,4 @@ export const RouteConfig = {
|
||||||
requestPromotionPath: 'promotion',
|
requestPromotionPath: 'promotion',
|
||||||
confirmAwardPath: 'confirm-award',
|
confirmAwardPath: 'confirm-award',
|
||||||
confirmPromotionPath: 'confirm-promotion'
|
confirmPromotionPath: 'confirm-promotion'
|
||||||
}
|
};
|
||||||
|
|
|
@ -10,7 +10,12 @@ export class PlayerService {
|
||||||
}
|
}
|
||||||
|
|
||||||
getCampaignPlayer(campaignId: string, playerName: string) {
|
getCampaignPlayer(campaignId: string, playerName: string) {
|
||||||
return this.http.get(this.config.apiPlayersPath + '/' + campaignId + '/' + playerName)
|
return this.http.get(this.config.apiPlayersPath + '/single/' + campaignId + '/' + playerName)
|
||||||
|
.map(res => res.json())
|
||||||
|
}
|
||||||
|
|
||||||
|
getCampaignHighscore(campaignId: string) {
|
||||||
|
return this.http.get(this.config.apiPlayersPath + '/ranking/' + campaignId)
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
h2 {
|
||||||
|
margin-left: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player-name {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-field {
|
||||||
|
width: 30%;
|
||||||
|
margin: 20px 0 0 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx-datatable {
|
||||||
|
width: 345px;
|
||||||
|
margin: 3% 5% 0 5%;
|
||||||
|
height: 310px;
|
||||||
|
float: left;
|
||||||
|
border: solid #dfdfdf 1px;
|
||||||
|
border-radius: 10px 10px 2px 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host /deep/ .datatable-header {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 */
|
|
@ -0,0 +1,145 @@
|
||||||
|
<div class="highscore-container fade-in">
|
||||||
|
<h2>{{title}} ⟶ Highscore</h2>
|
||||||
|
|
||||||
|
<div class="input-group search-field">
|
||||||
|
<input id="search-tasks"
|
||||||
|
placeholder="Spielername (mehrere mit '&' trennen)"
|
||||||
|
type="text" #query class="form-control"
|
||||||
|
(keyup.enter)="filterPlayers()"
|
||||||
|
[formControl]="searchTerm">
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button class="btn btn-default" type="button"
|
||||||
|
(click)="filterPlayers()">
|
||||||
|
Filter
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ngx-datatable
|
||||||
|
[rows]="players.kill"
|
||||||
|
[messages]="emptyMessage"
|
||||||
|
[headerHeight]="cellHeight"
|
||||||
|
[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" name="Kills" prop="kill"></ngx-datatable-column>
|
||||||
|
</ngx-datatable>
|
||||||
|
|
||||||
|
<ngx-datatable
|
||||||
|
[rows]="players.death"
|
||||||
|
[messages]="emptyMessage"
|
||||||
|
[headerHeight]="cellHeight"
|
||||||
|
[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" name="Tode" prop="death"></ngx-datatable-column>
|
||||||
|
</ngx-datatable>
|
||||||
|
|
||||||
|
<ngx-datatable
|
||||||
|
[rows]="players.respawn"
|
||||||
|
[messages]="emptyMessage"
|
||||||
|
[headerHeight]="cellHeight"
|
||||||
|
[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" name="Respawn" prop="respawn"></ngx-datatable-column>
|
||||||
|
</ngx-datatable>
|
||||||
|
|
||||||
|
<ngx-datatable
|
||||||
|
[rows]="players.friendlyFire"
|
||||||
|
[messages]="emptyMessage"
|
||||||
|
[headerHeight]="cellHeight"
|
||||||
|
[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" name="FriendlyFire" prop="friendlyFire"></ngx-datatable-column>
|
||||||
|
</ngx-datatable>
|
||||||
|
|
||||||
|
<ngx-datatable
|
||||||
|
[rows]="players.revive"
|
||||||
|
[messages]="emptyMessage"
|
||||||
|
[headerHeight]="cellHeight"
|
||||||
|
[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" name="Revive" prop="revive"></ngx-datatable-column>
|
||||||
|
</ngx-datatable>
|
||||||
|
|
||||||
|
<ngx-datatable
|
||||||
|
[rows]="players.flagTouch"
|
||||||
|
[messages]="emptyMessage"
|
||||||
|
[headerHeight]="cellHeight"
|
||||||
|
[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" name="Eroberung" prop="flagTouch"></ngx-datatable-column>
|
||||||
|
</ngx-datatable>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
import {Component} from "@angular/core";
|
||||||
|
import {ActivatedRoute} from "@angular/router";
|
||||||
|
import {PlayerService} from "../../services/logs/player.service";
|
||||||
|
import {CampaignService} from "../../services/logs/campaign.service";
|
||||||
|
import {Fraction} from "../../utils/fraction.enum";
|
||||||
|
import {FormControl} from "@angular/forms";
|
||||||
|
import {Observable} from "rxjs/Observable";
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'stats-highscore',
|
||||||
|
templateUrl: './highscore.component.html',
|
||||||
|
styleUrls: ['./highscore.component.css', '../../style/list-entry.css', '../../style/overview.css'],
|
||||||
|
inputs: ['campaigns']
|
||||||
|
})
|
||||||
|
export class StatisticHighScoreComponent {
|
||||||
|
|
||||||
|
id = '';
|
||||||
|
|
||||||
|
title = '';
|
||||||
|
|
||||||
|
searchTerm = new FormControl();
|
||||||
|
|
||||||
|
players = {};
|
||||||
|
|
||||||
|
playersStored = {};
|
||||||
|
|
||||||
|
cellHeight = 40;
|
||||||
|
|
||||||
|
numberColWidth = 60;
|
||||||
|
|
||||||
|
nameColWidth = 210;
|
||||||
|
|
||||||
|
valueColWidth = 110;
|
||||||
|
|
||||||
|
emptyMessage = {emptyMessage: 'Keine Einträge'};
|
||||||
|
|
||||||
|
reorderable = false;
|
||||||
|
|
||||||
|
customClasses = {
|
||||||
|
sortAscending: 'glyphicon glyphicon-triangle-top',
|
||||||
|
sortDescending: 'glyphicon glyphicon-triangle-bottom',
|
||||||
|
};
|
||||||
|
|
||||||
|
readonly fraction = Fraction;
|
||||||
|
|
||||||
|
constructor(private route: ActivatedRoute,
|
||||||
|
private playerService: PlayerService,
|
||||||
|
private campaignService: CampaignService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.route.params
|
||||||
|
.map(params => params['id'])
|
||||||
|
.subscribe((id) => {
|
||||||
|
this.id = id;
|
||||||
|
if (this.campaignService.campaigns) {
|
||||||
|
this.initData();
|
||||||
|
} else {
|
||||||
|
this.campaignService.getAllCampaigns().subscribe(campaigns => {
|
||||||
|
this.initData()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const searchTermStream = this.searchTerm.valueChanges.debounceTime(400);
|
||||||
|
|
||||||
|
Observable.merge(searchTermStream)
|
||||||
|
.distinctUntilChanged().map(query => this.filterPlayers())
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
initData() {
|
||||||
|
this.title = this.campaignService.campaigns
|
||||||
|
.filter(camp => camp._id === this.id).pop().title;
|
||||||
|
|
||||||
|
this.playerService.getCampaignHighscore(this.id).subscribe(players => {
|
||||||
|
this.players = players;
|
||||||
|
this.playersStored = players;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
filterPlayers() {
|
||||||
|
if (!this.searchTerm.value || this.searchTerm.value === '') {
|
||||||
|
this.players = this.playersStored;
|
||||||
|
} else {
|
||||||
|
this.players = {
|
||||||
|
kill: this.filterPlayerAttribute('kill'),
|
||||||
|
friendlyFire: this.filterPlayerAttribute('friendlyFire'),
|
||||||
|
death: this.filterPlayerAttribute('death'),
|
||||||
|
respawn: this.filterPlayerAttribute('respawn'),
|
||||||
|
revive: this.filterPlayerAttribute('revive'),
|
||||||
|
flagTouch: this.filterPlayerAttribute('flagTouch')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private filterPlayerAttribute(attribute) {
|
||||||
|
const query = this.searchTerm.value.toLowerCase().split('&');
|
||||||
|
|
||||||
|
return this.playersStored[attribute].filter(player => {
|
||||||
|
for (let i = 0; i < query.length; i++) {
|
||||||
|
if (query[i].trim() != '' && player.name.toLowerCase().includes(query[i].trim())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
import {Component} from "@angular/core";
|
import {Component} from "@angular/core";
|
||||||
import {ActivatedRoute} from "@angular/router";
|
import {ActivatedRoute} from "@angular/router";
|
||||||
import {CarouselConfig} from "ngx-bootstrap";
|
|
||||||
import {CampaignService} from "../../services/logs/campaign.service";
|
import {CampaignService} from "../../services/logs/campaign.service";
|
||||||
import {ChartUtils} from "../../utils/chart-utils";
|
import {ChartUtils} from "../../utils/chart-utils";
|
||||||
import {Fraction} from "../../utils/fraction.enum";
|
import {Fraction} from "../../utils/fraction.enum";
|
||||||
|
@ -10,8 +9,7 @@ import {Fraction} from "../../utils/fraction.enum";
|
||||||
selector: 'stats-overview',
|
selector: 'stats-overview',
|
||||||
templateUrl: './stats-overview.component.html',
|
templateUrl: './stats-overview.component.html',
|
||||||
styleUrls: ['./stats-overview.component.css', '../../style/list-entry.css', '../../style/overview.css'],
|
styleUrls: ['./stats-overview.component.css', '../../style/list-entry.css', '../../style/overview.css'],
|
||||||
inputs: ['campaigns'],
|
inputs: ['campaigns']
|
||||||
providers: [{provide: CarouselConfig, useValue: {interval: false}}]
|
|
||||||
})
|
})
|
||||||
export class StatisticOverviewComponent {
|
export class StatisticOverviewComponent {
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {WarDetailComponent} from "./war-detail/war-detail.component";
|
||||||
import {ScoreboardComponent} from "./war-detail/scoreboard/scoreboard.component";
|
import {ScoreboardComponent} from "./war-detail/scoreboard/scoreboard.component";
|
||||||
import {WarSubmitComponent} from "./war-submit/war-submit.component";
|
import {WarSubmitComponent} from "./war-submit/war-submit.component";
|
||||||
import {FractionStatsComponent} from "./war-detail/fraction-stats/fraction-stats.component";
|
import {FractionStatsComponent} from "./war-detail/fraction-stats/fraction-stats.component";
|
||||||
|
import {StatisticHighScoreComponent} from "./highscore/highscore.component";
|
||||||
|
|
||||||
|
|
||||||
export const statsRoutes: Routes = [{
|
export const statsRoutes: Routes = [{
|
||||||
|
@ -26,6 +27,11 @@ export const statsRoutes: Routes = [{
|
||||||
component: StatisticOverviewComponent,
|
component: StatisticOverviewComponent,
|
||||||
outlet: 'right'
|
outlet: 'right'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'highscore/:id',
|
||||||
|
component: StatisticHighScoreComponent,
|
||||||
|
outlet: 'right'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'new-campaign',
|
path: 'new-campaign',
|
||||||
component: CampaignSubmitComponent,
|
component: CampaignSubmitComponent,
|
||||||
|
@ -49,7 +55,7 @@ export const statsRoutes: Routes = [{
|
||||||
|
|
||||||
export const statsRouterModule: ModuleWithProviders = RouterModule.forChild(statsRoutes);
|
export const statsRouterModule: ModuleWithProviders = RouterModule.forChild(statsRoutes);
|
||||||
|
|
||||||
export const statsRoutingComponents = [StatisticComponent, StatisticOverviewComponent, CampaignSubmitComponent,
|
export const statsRoutingComponents = [StatisticComponent, StatisticOverviewComponent, StatisticHighScoreComponent,
|
||||||
WarListComponent, WarSubmitComponent, WarDetailComponent, ScoreboardComponent, FractionStatsComponent,
|
CampaignSubmitComponent, WarListComponent, WarSubmitComponent, WarDetailComponent, ScoreboardComponent,
|
||||||
CampaignPlayerDetailComponent, WarItemComponent];
|
FractionStatsComponent, CampaignPlayerDetailComponent, WarItemComponent];
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,24 @@ ngx-datatable {
|
||||||
background-color: #f7f7f7;
|
background-color: #f7f7f7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
|
@ -39,18 +39,3 @@
|
||||||
.nav-tabs > li.deactivated > a.nav-link {
|
.nav-tabs > li.deactivated > a.nav-link {
|
||||||
cursor: not-allowed !important;
|
cursor: not-allowed !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
: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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,3 +5,10 @@
|
||||||
color: white;
|
color: white;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.top-list-entry {
|
||||||
|
margin-top: -16px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
width: 50%;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
|
@ -20,24 +20,33 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="fade-in list-entry" style="margin-top: -16px; margin-bottom: 10px;"
|
<div class="fade-in list-entry top-list-entry"
|
||||||
[ngClass]="{selected : selectedWarId == campaign._id}" (click)="selectOverview(campaign._id)">
|
[ngClass]="{selected : selectedWarId == campaign._id}" (click)="selectOverview(campaign._id)">
|
||||||
<div class="row">
|
<div style="margin: auto;">
|
||||||
<div class="col-xs-9">
|
<span style="margin:auto">
|
||||||
<span style="margin:auto">
|
<a style="font-size: 22px;">Übersicht</a>
|
||||||
<a style="font-size: 22px;">Kampagnenübersicht</a>
|
</span>
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngFor="let war of campaign.wars">
|
<div class="fade-in list-entry top-list-entry"
|
||||||
<pjm-war-item
|
[ngClass]="{selected : selectedWarId == campaign._id + highscore}" (click)="selectHighscore(campaign._id)">
|
||||||
[war]="war"
|
<div style="margin: auto">
|
||||||
(warDelete)="deleteWar(war)"
|
<span style="margin:auto">
|
||||||
(warSelected)="selectWar($event)"
|
<a style="font-size: 22px;">Highscore</a>
|
||||||
[selected]="war._id == selectedWarId">
|
</span>
|
||||||
</pjm-war-item>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="padding-top: 40px;">
|
||||||
|
<div *ngFor="let war of campaign.wars">
|
||||||
|
<pjm-war-item
|
||||||
|
[war]="war"
|
||||||
|
(warDelete)="deleteWar(war)"
|
||||||
|
(warSelected)="selectWar($event)"
|
||||||
|
[selected]="war._id == selectedWarId">
|
||||||
|
</pjm-war-item>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</accordion-group>
|
</accordion-group>
|
||||||
</accordion>
|
</accordion>
|
||||||
|
|
|
@ -17,6 +17,8 @@ export class WarListComponent implements OnInit {
|
||||||
|
|
||||||
campaigns: Campaign[] = [];
|
campaigns: Campaign[] = [];
|
||||||
|
|
||||||
|
public readonly highscore = 'HIGHSCORE';
|
||||||
|
|
||||||
constructor(private warService: WarService,
|
constructor(private warService: WarService,
|
||||||
private campaignService: CampaignService,
|
private campaignService: CampaignService,
|
||||||
public loginService: LoginService,
|
public loginService: LoginService,
|
||||||
|
@ -59,10 +61,17 @@ export class WarListComponent implements OnInit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
selectOverview(overviewId) {
|
selectOverview(campaignId) {
|
||||||
if (this.selectedWarId != overviewId) {
|
if (this.selectedWarId != campaignId) {
|
||||||
this.selectedWarId = overviewId;
|
this.selectedWarId = campaignId;
|
||||||
this.router.navigate([{outlets: {'right': ['overview', overviewId]}}], {relativeTo: this.route});
|
this.router.navigate([{outlets: {'right': ['overview', campaignId]}}], {relativeTo: this.route});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selectHighscore(campaignId) {
|
||||||
|
if (this.selectedWarId != campaignId + this.highscore) {
|
||||||
|
this.selectedWarId = campaignId + this.highscore;
|
||||||
|
this.router.navigate([{outlets: {'right': ['highscore', campaignId]}}], {relativeTo: this.route});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue