Add award listing and modification for user
parent
5201463751
commit
af0dc65d5d
|
@ -13,9 +13,7 @@ const UserSchema = new Schema({
|
|||
type: Number,
|
||||
get: v => Math.round(v),
|
||||
set: v => Math.round(v),
|
||||
default: 0,
|
||||
min: 0,
|
||||
max: 22
|
||||
default: 0
|
||||
},
|
||||
squadId: {
|
||||
type: mongoose.Schema.Types.ObjectId,
|
||||
|
|
|
@ -29,7 +29,7 @@ squads.route('/')
|
|||
if (req.query.q) {
|
||||
filter.name = {$regex: req.query.q, $options: 'i'}
|
||||
}
|
||||
SquadModel.find(filter, {}, {sort: {sortingNumber: 'asc', fraction: 'asc'}}, (err, items) => {
|
||||
SquadModel.find(filter, {}, {sort: {fraction: 'asc', sortingNumber: 'asc'}}, (err, items) => {
|
||||
if (err) {
|
||||
err.status = codes.servererror;
|
||||
return next(err);
|
||||
|
|
|
@ -2,3 +2,22 @@
|
|||
background-color: white;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.trash {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.table {
|
||||
overflow-wrap: break-word;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
overflow-x: auto;
|
||||
width: 250%;
|
||||
margin-top: 50px
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
|
|
@ -2,46 +2,47 @@
|
|||
<h3>Teilnehmer auszeichnen</h3>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="title">Name</label>
|
||||
<input type="text" class="form-control"
|
||||
[(ngModel)]="user.username"
|
||||
name="title"
|
||||
id="title"
|
||||
required maxlength="50"/>
|
||||
|
||||
<show-error text="Name" path="title"></show-error>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="squad">Squad</label>
|
||||
<label for="decoration">Auszeichnung</label>
|
||||
<select class="form-control"
|
||||
name="squad"
|
||||
id="squad"
|
||||
[(ngModel)]="user.squad"
|
||||
[compareWith]="equals"
|
||||
(change)="toggleRanks()">
|
||||
<option [value]="0">Ohne Fraktion/ Squad</option>
|
||||
<option *ngFor="let squad of squads" [ngValue]="squad">
|
||||
{{squad.fraction == 'BLUFOR'? 'NATO' : 'CSAT'}}: {{squad.name}}
|
||||
name="decoration"
|
||||
id="decoration"
|
||||
#decorationField
|
||||
(change)="toggleDecoPreview(decoDescription, decorationField.value, decoPreview)"
|
||||
[ngModel]="undefined"
|
||||
required
|
||||
style="min-width: 200px;">
|
||||
<option *ngFor="let deco of decorations" [value]="deco._id">
|
||||
{{deco.fraction == 'BLUFOR'? 'NATO' : 'CSAT'}}: {{deco.name}}
|
||||
</option>
|
||||
</select>
|
||||
|
||||
<show-error text="Squad" path="squad"></show-error>
|
||||
<show-error text="Auszeichnung" path="decoration"></show-error>
|
||||
</div>
|
||||
|
||||
<div class="form-group" [style.display]="ranksDisplay">
|
||||
<label for="rank">Rang</label>
|
||||
<select class="form-control"
|
||||
name="rank"
|
||||
id="rank" [ngModel]="user.rank?.level"
|
||||
#rankLevel
|
||||
style="min-width: 200px;">
|
||||
<option *ngFor="let rank of ranks" [value]="rank.level">{{rank.name}}</option>
|
||||
</select>
|
||||
|
||||
<show-error text="Squad" path="squad"></show-error>
|
||||
<div class="div-table-row" [style.display]="decoPreviewDisplay" style="margin-top: 5px; margin-bottom:10px">
|
||||
<div class="div-table-col content-s">
|
||||
|
||||
</div>
|
||||
<div class="div-table-col content-m-flex decoration-preview" style="border-radius: 15px 0px 0px 15px;">
|
||||
<img class="center-block" #decoPreview>
|
||||
</div>
|
||||
<div class="div-table-col content-l decoration-preview"
|
||||
style="border-radius: 0px 15px 15px 0px; font-style: oblique" #decoDescription>
|
||||
|
||||
</div>
|
||||
<div class="div-table-col content-s">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="reason">Begründung</label>
|
||||
<textarea class="form-control center-block" name="reason" [ngModel]="undefined" required
|
||||
id="reason" placeholder="Begründung eingeben..." rows="3" #awardTextArea></textarea>
|
||||
<show-error text="Begründung" path="reason"></show-error>
|
||||
</div>
|
||||
|
||||
|
||||
<button id="cancel"
|
||||
(click)="cancel()"
|
||||
class="btn btn-default">
|
||||
|
@ -49,79 +50,46 @@
|
|||
</button>
|
||||
|
||||
<button id="save"
|
||||
(click)="saveUser(rankLevel.value)"
|
||||
(click)="addAwarding(decorationField, awardTextArea, decoPreview, decoDescription)"
|
||||
class="btn btn-default"
|
||||
[disabled]="!form.valid">
|
||||
Bestätigen
|
||||
</button>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<div class="section-content">
|
||||
<div class="container">
|
||||
<div class="table-responsive table-responsive-dropdowns">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-sm-2">Grafik</th>
|
||||
<th class="col-sm-3">Bezeichnung</th>
|
||||
<th class="col-sm-3">Begründung</th>
|
||||
<th class="col-sm-3 text-right">Datum</th>
|
||||
<th class="col-sm-2 text-center">LÖschen</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!--begin forEach-->
|
||||
<tr>
|
||||
<td class="table-cell-id">
|
||||
1
|
||||
</td>
|
||||
<td>
|
||||
<a class="small text-nowrap">2016-04-16 12:02:12</a>
|
||||
</td>
|
||||
<td>
|
||||
Herman
|
||||
Melville
|
||||
</td>
|
||||
<td class="text-right">
|
||||
222
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span class="label label-default">Paid online</span>
|
||||
</td>
|
||||
<td class="table-cell-actions">
|
||||
<a href="/orders/edit/1" class="item-action" title="Edit">
|
||||
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
|
||||
</a>
|
||||
<a href="#" class="item-action" title="Mark as delivered">
|
||||
<span class="glyphicon glyphicon-ok-sign" aria-hidden="true"></span>
|
||||
</a>
|
||||
<div class="btn-group">
|
||||
<button class="item-action" type="button" id="itemOptions1" data-toggle="dropdown" aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
<span class="glyphicon glyphicon-option-vertical" aria-hidden="true"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="itemOptions1">
|
||||
<li>
|
||||
<button type="button" class="btn btn-dropdown" data-toggle="confirm"
|
||||
data-confirm-message="Do you really want to cancel this order?" data-confirm-yes="Yes"
|
||||
data-confirm-no="No">
|
||||
<span class="glyphicon glyphicon-remove-sign offset-right" aria-hidden="true"></span>
|
||||
Cancel order
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<!--end forEach-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-container">
|
||||
<table class="table table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-sm-1">Bild</th>
|
||||
<th class="col-sm-2">Bezeichnung</th>
|
||||
<th class="col-sm-3">Begründung</th>
|
||||
<th class="col-sm-1 text-right">Datum</th>
|
||||
<th class="col-sm-1 text-center" style="width: 45px;"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody *ngFor="let award of user.awards">
|
||||
<tr>
|
||||
<td class="table-cell-id" *ngIf="award.decorationId.isMedal">
|
||||
<img height="40px" src="resource/decoration/{{award.decorationId._id}}.png">
|
||||
</td>
|
||||
<td class="table-cell-id" *ngIf="!award.decorationId.isMedal">
|
||||
<img width="60px" src="resource/decoration/{{award.decorationId._id}}.png">
|
||||
</td>
|
||||
<td>
|
||||
{{award.decorationId.name}}
|
||||
</td>
|
||||
<td>
|
||||
{{award.reason}}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<a class="small text-nowrap">{{award.date | date: 'dd.MM.yyyy'}}</a>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span class="glyphicon glyphicon-trash trash" title="Löschen" (click)="deleteAwarding(award._id)"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import {Component, ViewChild} from "@angular/core";
|
||||
import {ActivatedRoute, Router} from "@angular/router";
|
||||
import * as model from "../../models/model-interfaces";
|
||||
import {Rank, Squad, User} from "../../models/model-interfaces";
|
||||
import {Decoration, Squad, User} from "../../models/model-interfaces";
|
||||
import {UserService} from "../../services/user-service/user.service";
|
||||
import {SquadService} from "../../services/squad-service/squad.service";
|
||||
import {RankService} from "../../services/rank-service/rank.service";
|
||||
import {Subscription} from "rxjs";
|
||||
import {NgForm} from "@angular/forms";
|
||||
import {AwardingService} from "../../services/awarding-service/awarding.service";
|
||||
import {DecorationService} from "../../services/decoration-service/decoration.service";
|
||||
|
||||
|
||||
@Component({
|
||||
|
@ -19,68 +19,42 @@ export class UserAwardComponent {
|
|||
|
||||
subscription: Subscription;
|
||||
|
||||
id: string;
|
||||
|
||||
model = model;
|
||||
|
||||
showSuccessLabel = false;
|
||||
|
||||
ranksDisplay = 'none';
|
||||
user: User = {};
|
||||
|
||||
user: User = {squad: {}};
|
||||
decorations: Decoration[];
|
||||
|
||||
squads: Squad[] = [];
|
||||
|
||||
ranks: Rank[] = [];
|
||||
award: { decorationId: '', reason: '' };
|
||||
|
||||
saved = false;
|
||||
|
||||
decoPreviewDisplay = 'none';
|
||||
|
||||
constructor(private router: Router,
|
||||
private route: ActivatedRoute,
|
||||
private userService: UserService,
|
||||
private squadService: SquadService,
|
||||
private rankService: RankService) {
|
||||
private awardingService: AwardingService,
|
||||
private decorationService: DecorationService) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
// this.subscription = this.route.params
|
||||
// .map(params => params['id'])
|
||||
// .filter(id => id != undefined)
|
||||
// .flatMap(id => this.userService.getUser(id))
|
||||
// .subscribe(user => {
|
||||
// if (user.squad === null) {
|
||||
// user.squad = "0";
|
||||
// this.ranksDisplay = 'none';
|
||||
// } else {
|
||||
// this.rankService.findRanks('', user.squad.fraction).subscribe(ranks => {
|
||||
// this.ranks = ranks;
|
||||
// this.ranksDisplay = 'block';
|
||||
// });
|
||||
// }
|
||||
// this.user = user;
|
||||
// });
|
||||
//
|
||||
// this.squadService.findSquads().subscribe(squads => {
|
||||
// this.squads = squads;
|
||||
// });
|
||||
this.subscription = this.route.params
|
||||
.map(params => params['id'])
|
||||
.filter(id => id != undefined)
|
||||
.flatMap(id => this.userService.getUser(id))
|
||||
.subscribe(user => {
|
||||
this.user = user;
|
||||
});
|
||||
|
||||
this.decorationService.findDecorations().subscribe(decorations => {
|
||||
this.decorations = decorations;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
// this.subscription.unsubscribe();
|
||||
}
|
||||
|
||||
toggleRanks() {
|
||||
if (this.user.squad != '0') {
|
||||
this.rankService.findRanks('', this.user.squad.fraction).subscribe(
|
||||
ranks => {
|
||||
this.ranks = ranks;
|
||||
this.ranksDisplay = 'block';
|
||||
}
|
||||
);
|
||||
} else {
|
||||
this.ranksDisplay = 'none';
|
||||
}
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
|
||||
saveUser(rankLevel) {
|
||||
|
@ -124,6 +98,63 @@ export class UserAwardComponent {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
toggleDecoPreview(descriptionField, decorationId, image) {
|
||||
this.decoPreviewDisplay = 'flex'; // visible & keep same height for all children
|
||||
|
||||
const description = this.decorations.find(
|
||||
decoration => decoration._id === decorationId
|
||||
).description;
|
||||
|
||||
image.src = 'resource/decoration/' + decorationId + '.png';
|
||||
descriptionField.innerHTML = description;
|
||||
|
||||
}
|
||||
|
||||
deleteAwarding(awardingId) {
|
||||
this.awardingService.deleteAwarding(awardingId).subscribe((res) => {
|
||||
this.awardingService.getUserAwardings(this.user._id)
|
||||
.map((res) => res.json())
|
||||
.subscribe((awards) => {
|
||||
this.user.awards = awards;
|
||||
this.showSuccessLabel = true;
|
||||
setTimeout(() => {
|
||||
this.showSuccessLabel = false;
|
||||
}, 2000)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
addAwarding(decorationField, reasonField, previewImage, descriptionField) {
|
||||
const decorationId = decorationField.value;
|
||||
const reason = reasonField.value;
|
||||
if (decorationId && reason.length > 0) {
|
||||
const award = {
|
||||
"userId": this.user._id,
|
||||
"decorationId": decorationId,
|
||||
"reason": reason,
|
||||
"date": Date.now()
|
||||
};
|
||||
this.awardingService.addAwarding(award).subscribe(() => {
|
||||
this.awardingService.getUserAwardings(this.user._id)
|
||||
.map((res) => res.json())
|
||||
.subscribe(awards => {
|
||||
this.user.awards = awards;
|
||||
this.decoPreviewDisplay = 'none';
|
||||
decorationField.value = undefined;
|
||||
reasonField.value = '';
|
||||
previewImage.src = '';
|
||||
descriptionField.innerHTML = '';
|
||||
this.showSuccessLabel = true;
|
||||
setTimeout(() => {
|
||||
this.showSuccessLabel = false;
|
||||
}, 2000)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
canDeactivate(): boolean {
|
||||
if (this.saved || !this.form.dirty) {
|
||||
return true;
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
</div>
|
||||
|
||||
<div class="col-xs-3">
|
||||
<span (click)="select()" class="glyphicon glyphicon-pencil pull-left edit"></span>
|
||||
<span (click)="award()" class="icon-award pull-left"></span>
|
||||
<span (click)="delete(); $event.stopPropagation()" class="glyphicon glyphicon-trash trash"></span>
|
||||
<span (click)="select()" title="Bearbeiten" class="glyphicon glyphicon-pencil pull-left edit"></span>
|
||||
<span (click)="award()" title="Auszeichnungen" class="icon-award pull-left"></span>
|
||||
<span (click)="delete(); $event.stopPropagation()" title="Löschen" class="glyphicon glyphicon-trash trash"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -61,6 +61,13 @@ export class UserListComponent implements OnInit {
|
|||
this.router.navigate([{outlets: {'right': ['award', userId]}}], {relativeTo: this.route});
|
||||
}
|
||||
|
||||
deleteUser(user: User) {
|
||||
this.userService.deleteUser(user)
|
||||
.subscribe((res) => {
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
filterUsersByFraction(query = '', fractionFilter) {
|
||||
this.users$ = this.userService.findUsers(query, fractionFilter);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
[(ngModel)]="user.username"
|
||||
name="title"
|
||||
id="title"
|
||||
required maxlength="50"/>
|
||||
required
|
||||
maxlength="50"/>
|
||||
|
||||
<show-error text="Name" path="title"></show-error>
|
||||
</div>
|
||||
|
@ -54,4 +55,11 @@
|
|||
[disabled]="!form.valid">
|
||||
Bestätigen
|
||||
</button>
|
||||
|
||||
<span *ngIf="showSuccessLabel"
|
||||
class="label label-success label-small"
|
||||
style="margin-left: inherit">
|
||||
Erfolgreich gespeichert
|
||||
</span>
|
||||
|
||||
</form>
|
||||
|
|
|
@ -94,7 +94,6 @@ export class UserOverviewComponent {
|
|||
if (this.user.squad._id !== '0') {
|
||||
updateObject.squadId = this.user.squad._id
|
||||
}
|
||||
console.log(updateObject)
|
||||
this.userService.updateUser(updateObject)
|
||||
.subscribe(user => {
|
||||
if (!user.squad) {
|
||||
|
|
Loading…
Reference in New Issue