Add war detail view
parent
eab910d505
commit
ee61271550
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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')
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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>
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue