Add war detail view

pull/1/head
Florian Hartwich 2017-07-08 21:56:11 +02:00
parent eab910d505
commit ee61271550
9 changed files with 242 additions and 2 deletions

View File

@ -113,7 +113,7 @@ wars.route('/:id')
err.status = codes.notfound;
return next(err);
}
PlayerModel.find({warId: item._id}, (err, items) => {
PlayerModel.find({warId: item._id}, {}, {sort: {kill: 'desc'}}, (err, items) => {
if (err) {
return next(err);
}

View File

@ -14,5 +14,6 @@ export class AppConfig {
public readonly apiOverviewPath = '/overview';
public readonly apiRequestAwardPath = '/request/award';
public readonly apiPromotionPath = '/request/promotion';
public readonly apiWarPath = '/wars';
}

View File

@ -31,6 +31,7 @@ import {AppUserService} from "./services/app-user-service/app-user.service";
import {AppUserStore} from "./services/stores/app-user.store";
import {PromotionService} from "./services/promotion-service/promotion.service";
import {FilterRankPipe} from "./filter/filter.pipe";
import {WarService} from "./services/war-service/war.service";
@NgModule({
imports: [BrowserModule, FormsModule, ReactiveFormsModule, appRouting, HttpModule, ClipboardModule],
@ -53,6 +54,7 @@ import {FilterRankPipe} from "./filter/filter.pipe";
RankStore,
AwardingService,
PromotionService,
WarService,
AppConfig,
Title,
routingProviders,

View File

@ -13,6 +13,7 @@ import {RequestAwardComponent} from "./request/award/req-award.component";
import {RequestPromotionComponent} from "./request/promotion/req-promotion.component";
import {ConfirmPromotionComponent} from "./request/confirm-promotion/confirm-promotion.component";
import {ConfirmAwardComponent} from "./request/confirm-award/confirm-award.component";
import {WarDetailComponent} from "./wars/war-detail.component";
export const appRoutes: Routes = [
@ -20,6 +21,8 @@ export const appRoutes: Routes = [
{path: 'cc-overview', children: armyRoutes},
{path: '', redirectTo: '/cc-overview', pathMatch: 'full'},
{path: 'cc-wars/:id', component: WarDetailComponent},
{path: 'login', component: LoginComponent},
{path: 'signup', component: SignupComponent},
@ -44,6 +47,6 @@ export const appRouting = RouterModule.forRoot(appRoutes);
export const routingComponents = [LoginComponent, SignupComponent, RequestAwardComponent, RequestPromotionComponent, ConfirmAwardComponent,
ConfirmPromotionComponent, AdminComponent, ...armyRoutingComponents, NotFoundComponent, ...usersRoutingComponents,
...squadsRoutingComponents, ...decorationsRoutingComponents, ...ranksRoutingComponents];
...squadsRoutingComponents, ...decorationsRoutingComponents, ...ranksRoutingComponents, WarDetailComponent];
export const routingProviders = [LoginGuardHL];

View File

@ -16,6 +16,26 @@ export interface User {
awards?: Award[];
}
export interface Player {
_id?: string;
fraction?: string;
name?: string;
warId?: War;
kill?: number;
death?: number;
friendlyFire?: number;
respawn?: number;
flagTouch?: number;
}
export interface War {
_id?: string;
date?: Date;
ptBlufor?: number;
ptOpfor?: number;
bestPlayerId?: Player;
players: Player[];
}
export interface Squad {
_id?: string;
name?: string;

View File

@ -0,0 +1,45 @@
import {Injectable} from "@angular/core";
import {War} from "../../models/model-interfaces";
import {AppConfig} from "../../app.config";
import {HttpClient} from "../http-client";
@Injectable()
export class WarService {
constructor(private http: HttpClient,
private config: AppConfig) {
}
getAllWars() {
return this.http.get(this.config.apiUrl + this.config.apiWarPath)
.map(res => res.json())
}
getWar(warId: string) {
return this.http.get(this.config.apiUrl + this.config.apiWarPath + '/' + warId)
.map(res => res.json())
}
submitDecoration(war: War, logFile?) {
let body;
if (logFile) {
body = new FormData();
Object.keys(war).map((objectKey) => {
if (war[objectKey] !== undefined) {
body.append(objectKey, war[objectKey]);
}
});
body.append('log', logFile, logFile.name);
}
return this.http.post(this.config.apiUrl + this.config.apiDecorationPath, body)
.map(res => res.json())
.do(savedDecoration => {
console.log('saved successfully')
});
}
}

View File

@ -0,0 +1,43 @@
.overview {
position: fixed;
overflow-y: scroll;
overflow-x: hidden;
bottom: 20px;
width: 100%;
padding-left: 50px;
padding-top: 70px;
margin-left: 10px;
height: 100vh;
}
.trash {
cursor: pointer;
}
.table {
overflow-wrap: break-word;
table-layout: fixed;
}
.table-container {
margin-top: 10px;
overflow-x: auto;
}
.table-head {
background: #222222;
color: white;
}
.cell-outline {
outline: 1px solid #D4D4D4;
}
.text-opfor {
color: firebrick;
}
.text-blufor {
color: blue;
}

View File

@ -0,0 +1,80 @@
<div class="overview" xmlns="http://www.w3.org/1999/html">
<div style="margin-left: 5%">
<h2>Schlacht vom {{war.date | date: 'dd.MM.yyyy'}}</h2>
<h3 class="pull-left">
<h4>Endpunktestand:</h4>
<span class="text-blufor" style="font-weight: bold; margin-right: 10px">NATO {{war.ptBlufor}}</span>
<span style="font-size: x-large">|</span>
<span class="text-opfor" style="font-weight: bold; margin-left: 10px;">{{war.ptOpfor}} CSAT</span>
</h3>
<div style="margin-left: 50%; margin-top:5%">
<form class="form-group">
<label class="radio-inline">
<input type="radio" name="fractSelect"
[checked]="(fractionRadioSelect == undefined) ? 'true' : 'false'"
[(ngModel)]="fractionRadioSelect"
(change)="filterPlayersByFraction()">Alle
</label>
<label class="radio-inline">
<input type="radio" name="fractSelect" value="BLUFOR"
[(ngModel)]="fractionRadioSelect"
#fractRadioBufor
(change)="filterPlayersByFraction(fractRadioBufor.value)">NATO
</label>
<label class="radio-inline">
<input type="radio" name="fractSelect" value="OPFOR"
[(ngModel)]="fractionRadioSelect"
#fractRadioOpfor
(change)="filterPlayersByFraction(fractRadioOpfor.value)">CSAT
</label>
<br>
</form>
</div>
</div>
<div class="pull-left" style="margin-top:20px;">
<div class="table-container" style="width: 75%; min-width: 500px">
<table class="table table-hover">
<thead>
<tr class="table-head">
<th class="col-sm-2" style="border-radius: 10px 0 0 0;">Spieler</th>
<th class="col-sm-1">Fraktion</th>
<th class="col-sm-1">Kills</th>
<th class="col-sm-1">FriendlyFire</th>
<th class="col-sm-1">Eroberungen</th>
<th class="col-sm-1">Tode</th>
<th class="col-sm-1" style="border-radius: 0 10px 0 0;">Respawn</th>
</tr>
</thead>
<tbody *ngFor="let player of players">
<tr class="cell-outline">
<td style="font-weight: bold" [ngClass]="player.fraction === 'BLUFOR' ? 'text-blufor' : 'text-opfor'">
{{player.name}}
</td>
<td>
{{player.fraction === 'BLUFOR' ? 'NATO' : 'CSAT'}}
</td>
<td>
{{player.kill}}
</td>
<td>
{{player.friendlyFire}}
</td>
<td>
{{player.flagTouch}}
</td>
<td>
{{player.death}}
</td>
<td>
{{player.respawn}}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>

View File

@ -0,0 +1,46 @@
import {Component} from "@angular/core";
import {Player, War} from "../models/model-interfaces";
import {WarService} from "../services/war-service/war.service";
import {ActivatedRoute} from "@angular/router";
@Component({
selector: 'war-detail',
templateUrl: './war-detail.component.html',
styleUrls: ['./war-detail.component.css']
})
export class WarDetailComponent {
war: War = {players: []};
players: Player[] = [];
fractionRadioSelect: string;
constructor(private route: ActivatedRoute,
private warService: WarService) {
}
ngOnInit() {
this.route.params
.map(params => params['id'])
.filter(id => id != undefined)
.flatMap(id => this.warService.getWar(id))
.subscribe(war => {
this.war = war;
this.players = war.players;
});
}
filterPlayersByFraction(fraction: string) {
if (fraction) {
this.players = this.war.players.filter((player) => {
console.log(player.fraction + " .... " + fraction);
return player.fraction === fraction;
})
} else {
this.players = this.war.players;
}
}
}