Modify input forms to new layout - decoration and squad; Fix api rank level range

pull/1/head
Florian Hartwich 2017-05-16 20:06:00 +02:00
parent fdb7105e1b
commit f582bc5fce
30 changed files with 216 additions and 497 deletions

View File

@ -17,8 +17,6 @@ const RankSchema = new Schema({
type: Number, type: Number,
get: v => Math.round(v), get: v => Math.round(v),
set: v => Math.round(v), set: v => Math.round(v),
min: 0,
max: 22,
required: true required: true
} }
}, { }, {

View File

@ -12,11 +12,4 @@ export class AppConfig {
public readonly apiUserPath = '/users/'; public readonly apiUserPath = '/users/';
public readonly apiOverviewPath = '/overview'; public readonly apiOverviewPath = '/overview';
public getAuthenticationHeader() :Headers {
let currentUser = JSON.parse(localStorage.getItem('currentUser'));
let headers = new Headers();
headers.append('x-access-token', currentUser.token);
return headers;
}
} }

View File

@ -1,4 +1,4 @@
div.squad-list-entry, a.squad-list-entry { div.decoration-list-entry, a.decoration-list-entry {
padding: 8px; padding: 8px;
width: 475px; width: 475px;
border-radius: 2px; border-radius: 2px;
@ -7,6 +7,11 @@ div.squad-list-entry, a.squad-list-entry {
margin-bottom: -1px; margin-bottom: -1px;
} }
.decoration-list-preview {
float: left;
margin-right: 12px;
}
.marked { .marked {
background: lightgrey; background: lightgrey;
} }
@ -25,9 +30,9 @@ small {
} }
.trash { .trash {
float:right;
padding-top: 18px; padding-top: 18px;
font-size: 17px; font-size: 17px;
margin-left: -10px;
} }
.selected { .selected {

View File

@ -1,7 +1,7 @@
<div class="fade-in squad-list-entry" [ngClass]="{selected : selected}" (click)="select()"> <div class="fade-in decoration-list-entry" [ngClass]="{selected : selected}" (click)="select()">
<div class="row"> <div class="row">
<div class="col-xs-11"> <div class="col-xs-9">
<span> <span>
<a>{{decoration.name}}</a> <a>{{decoration.name}}</a>
</span> </span>
@ -11,5 +11,10 @@
<small *ngIf="decoration.fraction == 'GLOBAL'">Global</small> <small *ngIf="decoration.fraction == 'GLOBAL'">Global</small>
<small> - Sortierung: {{decoration.sortingNumber}}</small> <small> - Sortierung: {{decoration.sortingNumber}}</small>
</div> </div>
<div class="col-xs-3">
<img src="{{imageSrc}}" height="{{decoration.isMedal ? 50 : 20}}" [style.margin-top]="previewMargin" class="decoration-list-preview">
<span (click)="delete(); $event.stopPropagation()" title="Löschen" class="glyphicon glyphicon-trash trash"></span>
</div>
</div> </div>
</div> </div>

View File

@ -8,24 +8,36 @@ import {Decoration} from "../../models/model-interfaces";
styleUrls: ['./decoration-item.component.css'], styleUrls: ['./decoration-item.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
inputs: ['decoration', 'selected'], inputs: ['decoration', 'selected'],
outputs: ['decorationSelected'], outputs: ['decorationDelete','decorationSelected'],
}) })
export class DecorationItemComponent { export class DecorationItemComponent {
selected: boolean; selected: boolean;
decoration: Decoration; decoration: Decoration;
imageSrc;
previewMargin;
decorationSelected = new EventEmitter(); decorationSelected = new EventEmitter();
decorationDelete = new EventEmitter();
constructor(private router: Router) { constructor(private router: Router) {
}
ngOnInit() {
this.imageSrc = 'resource/decoration/' + this.decoration._id + '.png?' + Date.now();
if (!this.decoration.isMedal) {
this.previewMargin = '17px'
}
} }
select() { select() {
this.decorationSelected.emit(this.decoration._id) this.decorationSelected.emit(this.decoration._id)
} }
delete() {
this.decorationDelete.emit(this.decoration);
}
ngAfterViewChecked() { ngAfterViewChecked() {
//var taskId = (this.task ? this.task.id : ''); //var taskId = (this.task ? this.task.id : '');
// console.log(`Task ${taskId} checked ${++this.checkCounter} times`) // console.log(`Task ${taskId} checked ${++this.checkCounter} times`)

View File

@ -42,6 +42,7 @@
<div> <div>
<pjm-decoration-item *ngFor="let decoration of decorations$ | async" <pjm-decoration-item *ngFor="let decoration of decorations$ | async"
[decoration]="decoration" [decoration]="decoration"
(decorationDelete)="deleteDecoration(decoration)"
(decorationSelected)="selectDecoration($event)" (decorationSelected)="selectDecoration($event)"
[selected]="decoration._id == selectedDecorationId"> [selected]="decoration._id == selectedDecorationId">
</pjm-decoration-item> </pjm-decoration-item>

View File

@ -48,12 +48,25 @@ export class DecorationListComponent implements OnInit {
} }
openNewSquadForm() { openNewSquadForm() {
this.selectedDecorationId = null;
this.router.navigate([{outlets: {'right': ['new']}}], {relativeTo: this.route}); this.router.navigate([{outlets: {'right': ['new']}}], {relativeTo: this.route});
} }
selectDecoration(decorationId: string | number) { selectDecoration(decorationId: string | number) {
this.selectedDecorationId = decorationId; this.selectedDecorationId = decorationId;
this.router.navigate([{outlets: {'right': ['overview', decorationId]}}], {relativeTo: this.route}); this.router.navigate([{outlets: {'right': ['edit', decorationId]}}], {relativeTo: this.route});
}
deleteDecoration(decoration) {
let fraction = 'GLOBAL';
if (decoration.fraction === 'BLUFOR') fraction = 'NATO';
else if (decoration.fraction === 'OPFOR') fraction = 'CSAT';
if (confirm('Soll die Auszeichnung "' + decoration.name + '" (' + fraction + ') wirklich gelöscht werden?')) {
this.decorationService.deleteDecoration(decoration)
.subscribe((res) => {
})
}
} }
filterSquadsByFraction(query = '', fractionFilter) { filterSquadsByFraction(query = '', fractionFilter) {

View File

@ -1,134 +0,0 @@
<div class="overview">
<h3 style="margin-bottom: 25px">Auszeichnung-Details
<span *ngIf="showSuccessLabel"
class="label label-success label-small"
style="margin-left: inherit">
Erfolgreich gespeichert
</span>
</h3>
<div *ngIf="decoration">
<div class="col-xs-12">
<div class="div-table">
<div class="div-table-row">
<div class="div-table-col content-s">
<label>Name:</label>
</div>
<div class="div-table-col content content-m">
{{decoration.name}}
</div>
<div class="div-table-col content-l">
<input class="form-control" type="text" width="250px" placeholder="Neuer Name" #newNameInput>
</div>
<div class="div-table-col content-s">
<a class="pull-right btn btn-sm btn-block btn-default" (click)="update('name', newNameInput)">Bestätigen</a>
</div>
</div>
<div class="div-table-row">
<div class="div-table-col content-s">
<label>Fraktion:</label>
</div>
<div class="div-table-col fraction-opfor content-m" *ngIf="decoration.fraction == 'OPFOR'">
CSAT
</div>
<div class="div-table-col fraction-blufor content-m" *ngIf="decoration.fraction == 'BLUFOR'">
NATO
</div>
<div class="div-table-col">
</div>
</div>
<div class="div-table-row">
<div class="div-table-col content-s">
<label>Art:</label>
</div>
<div class="div-table-col content content-m" *ngIf="decoration.isMedal">
Orden
</div>
<div class="div-table-col content content-m" *ngIf="!decoration.isMedal">
Ribbon
</div>
<div class="div-table-col">
</div>
</div>
</div>
<hr>
<div class="div-table">
<div class="div-table-row">
<div class="div-table-col content-s">
<label>Sortierung:</label>
</div>
<div class="div-table-col content content-m">
{{decoration.sortingNumber}}
</div>
<div class="div-table-col content-l">
<input type="number" class="form-control" width="250px" placeholder="Neue Sortierung" #sortingNumberInput>
</div>
<div class="div-table-col content-s">
<a class="pull-right btn btn-sm btn-block btn-default" (click)="update('sortingNumber', sortingNumberInput)">Bestätigen</a>
</div>
</div>
</div>
<hr>
<div class="div-table">
<div class="div-table-row">
<div class="div-table-col content-s">
<label>Beschreibung:</label>
</div>
<div class="div-table-col" style="width: 500px;">
<textarea #inputDescription [(ngModel)]="decoration.description" class="form-control" rows="2" cols="53">{{decoration.description}}</textarea>
</div>
<div class="div-table-col content-s">
<a class="pull-right btn btn-sm btn-block btn-default" (click)="update('description', inputDescription)">Bestätigen</a>
</div>
</div>
</div>
<hr>
<div class="div-table">
<div class="div-table-row">
<div class="div-table-col content-s">
<label>Bild:</label>
</div>
<div class="div-table-col content-m-flex">
<img src="{{previewImage}}">
</div>
<div class="div-table-col content-l">
<label class="control-label">Neues Bild</label>
<input class="form-control" type="file"
accept="image/png"
#newLogoInput
(change)="fileChange($event)">
<span class="label label-bg label-danger center-block" style="font-size:small" *ngIf="showImageError">
Bild muss im PNG Format vorliegen
</span>
</div>
<div class="div-table-col content-s">
<label>&nbsp;</label>
<a class="pull-right btn btn-sm btn-block btn-default"(click)="updateGraphic(newLogoInput)">Bestätigen</a>
</div>
</div>
</div>
<hr>
<div class="div-table">
<div class="div-table-row">
<div class="div-table-col content-s">
<label>Löschen:</label>
</div>
<div class="div-table-col content-xl">
<input class="form-control" #confirmInput placeholder="Auszeichnungsnamen zur Bestätigung eingeben" style="width:330px">
</div>
<div class="div-table-col content-l">
<a class="pull-right btn btn-sm btn-block btn-default" (click)="deleteDecoration(confirmInput.value)">Auszeichnung Löschen</a>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -1,94 +0,0 @@
import {Component} from "@angular/core";
import {ActivatedRoute, Router} from "@angular/router";
import {Decoration} from "../../models/model-interfaces";
import {DecorationService} from "../../services/decoration-service/decoration.service";
@Component({
templateUrl: './decoration-overview.component.html',
styleUrls: ['./decoration-overview.component.css', '../../style/overview.css'],
})
export class DecorationOverviewComponent {
id: string;
showSuccessLabel = false;
showImageError = false;
decoration: Decoration;
fileList: FileList;
previewImage;
constructor(private router: Router,
private route: ActivatedRoute,
private decorationService: DecorationService) {
}
ngOnInit() {
this.route.params.subscribe((params) => {
this.decorationService.getDecoration(params['id']).subscribe(decoration => {
this.decoration = decoration;
this.previewImage = 'resource/decoration/' + this.decoration._id + '.png?' + Date.now();
})
})
}
// register file change and save to fileList
fileChange(event) {
if (!event.target.files[0].name.endsWith('.png')) {
this.showImageError = true;
this.fileList = undefined;
} else {
this.showImageError = false;
this.fileList = event.target.files;
}
}
update(attrName, inputField) {
const inputValue = inputField.value;
if (inputValue.length > 0 && (this.decoration[attrName] !== inputValue || attrName === 'description')) {
const updateObject = {_id: this.decoration._id};
updateObject[attrName] = inputValue;
this.decorationService.submitDecoration(updateObject)
.subscribe(decoration => {
this.decoration = decoration;
if (attrName != 'description') {
inputField.value = '';
}
this.showSuccessLabel = true;
setTimeout(() => {
this.showSuccessLabel = false;
}, 2000)
})
}
}
updateGraphic(fileInput) {
if (this.fileList && this.fileList.length > 0) {
let file: File = this.fileList[0];
this.decorationService.submitDecoration({_id: this.decoration._id}, file)
.subscribe((res) => {
setTimeout(() => {
this.previewImage = 'resource/decoration/' + this.decoration._id + '.png?' + Date.now();
}, 300);
fileInput.value = '';
this.showSuccessLabel = true;
setTimeout(() => {
this.showSuccessLabel = false;
}, 2000)
})
}
}
deleteDecoration(confirm) {
if (confirm.toLowerCase() === this.decoration.name.toLocaleLowerCase()) {
this.decorationService.deleteDecoration(this.decoration)
.subscribe((res) => {
this.router.navigate(['../..'], {relativeTo: this.route});
})
}
}
}

View File

@ -2,7 +2,6 @@ import {Routes} from "@angular/router";
import {DecorationComponent} from "./decoration.component"; import {DecorationComponent} from "./decoration.component";
import {DecorationListComponent} from "./decoration-list/decoration-list.component"; import {DecorationListComponent} from "./decoration-list/decoration-list.component";
import {CreateDecorationComponent} from "./new-decoration/new-decoration.component"; import {CreateDecorationComponent} from "./new-decoration/new-decoration.component";
import {DecorationOverviewComponent} from "./decoration-overview/decoration-overview.component";
export const decorationsRoutes: Routes = [{ export const decorationsRoutes: Routes = [{
path: '', component: DecorationComponent, path: '', component: DecorationComponent,
@ -19,10 +18,10 @@ export const decorationsRoutes: Routes = [{
outlet: 'right' outlet: 'right'
}, },
{ {
path: 'overview/:id', path: 'edit/:id',
component: DecorationOverviewComponent, component: CreateDecorationComponent,
outlet: 'right' outlet: 'right'
}]; }];
export const decorationsRoutingComponents = [DecorationComponent, DecorationListComponent, DecorationOverviewComponent, CreateDecorationComponent]; export const decorationsRoutingComponents = [DecorationComponent, DecorationListComponent, CreateDecorationComponent];

View File

@ -1,3 +1,7 @@
.preview-image {
margin: 10px;
}
.form-control { .form-control {
height: auto; height: auto;
} }

View File

@ -1,5 +1,6 @@
<form #form="ngForm" class="overview"> <form #form="ngForm" class="overview">
<h3 >Neue Auszeichnung hinzufügen</h3> <h3 *ngIf="decoration._id">Auszeichnung editieren</h3>
<h3 *ngIf="!decoration._id">Neuen Auszeichnung hinzufügen</h3>
<div class="form-group"> <div class="form-group">
<label for="title">Name</label> <label for="title">Name</label>
@ -45,18 +46,21 @@
<label for="description">Beschreibung</label> <label for="description">Beschreibung</label>
<textarea id="description" name="description" class="form-control" rows="5" <textarea id="description" name="description" class="form-control" rows="5"
required required
[(ngModel)]="decoration.description">></textarea> [(ngModel)]="decoration.description"></textarea>
<show-error text="Beschreibung" path="description"></show-error> <show-error text="Beschreibung" path="description"></show-error>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="graphic">Bild</label> <label for="graphic">Bild</label>
<input id="graphic" name="graphic" class="ui-button form-control" type="file" <input id="graphic" name="graphic" class="ui-button form-control" type="file"
#fileInput
accept="image/png" accept="image/png"
(change)="fileChange($event)"> (change)="fileChange($event)">
<span class="label label-bg label-danger center-block" style="font-size:small" *ngIf="showImageError"> <span class="label label-bg label-danger center-block" style="font-size:small" *ngIf="showImageError">
Bild muss im PNG Format vorliegen Bild muss im PNG Format vorliegen
</span> </span>
<img class="preview-image" src="{{imagePreviewSrc}}">
</div> </div>
<button id="cancel" <button id="cancel"
@ -64,10 +68,18 @@
class="btn btn-default"> class="btn btn-default">
Abbrechen Abbrechen
</button> </button>
<button id="save" <button id="save"
(click)="saveDecoration()" (click)="saveDecoration(fileInput)"
class="btn btn-default" class="btn btn-default"
[disabled]="!form.valid"> [disabled]="!form.valid">
Auszeichnung speichern Bestätigen
</button> </button>
<span *ngIf="showSuccessLabel"
class="label label-success label-small"
style="margin-left: inherit">
Erfolgreich gespeichert
</span>
</form> </form>

View File

@ -1,9 +1,9 @@
import {Component, ViewChild} from "@angular/core"; import {Component, ViewChild} from "@angular/core";
import {ActivatedRoute, Router} from "@angular/router"; import {ActivatedRoute, Router} from "@angular/router";
import {NgForm} from "@angular/forms"; import {NgForm} from "@angular/forms";
import * as model from "../../models/model-interfaces";
import {Decoration} from "../../models/model-interfaces"; import {Decoration} from "../../models/model-interfaces";
import {DecorationService} from "../../services/decoration-service/decoration.service"; import {DecorationService} from "../../services/decoration-service/decoration.service";
import {Subscription} from "rxjs/Subscription";
@Component({ @Component({
templateUrl: './new-decoration.component.html', templateUrl: './new-decoration.component.html',
@ -11,6 +11,8 @@ import {DecorationService} from "../../services/decoration-service/decoration.se
}) })
export class CreateDecorationComponent { export class CreateDecorationComponent {
subscription: Subscription;
decoration: Decoration = {name: '', fraction: '', sortingNumber: 0}; decoration: Decoration = {name: '', fraction: '', sortingNumber: 0};
fileList: FileList; fileList: FileList;
@ -19,6 +21,10 @@ export class CreateDecorationComponent {
showImageError = false; showImageError = false;
imagePreviewSrc;
showSuccessLabel = false;
@ViewChild(NgForm) form: NgForm; @ViewChild(NgForm) form: NgForm;
constructor(private route: ActivatedRoute, constructor(private route: ActivatedRoute,
@ -27,7 +33,18 @@ export class CreateDecorationComponent {
} }
ngOnInit() { ngOnInit() {
this.subscription = this.route.params
.map(params => params['id'])
.filter(id => id != undefined)
.flatMap(id => this.decorationService.getDecoration(id))
.subscribe(decoration => {
this.decoration = decoration;
this.imagePreviewSrc = 'resource/decoration/' + this.decoration._id + '.png?' + Date.now();
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
} }
fileChange(event) { fileChange(event) {
@ -40,22 +57,40 @@ export class CreateDecorationComponent {
} }
} }
saveDecoration() { saveDecoration(fileInput) {
if (this.fileList) { let file: File;
let file: File = this.fileList[0]; if (!this.decoration._id) {
this.decorationService.submitDecoration(this.decoration, file) if (this.fileList) {
.subscribe(decoration => { file = this.fileList[0];
this.saved = true; this.decorationService.submitDecoration(this.decoration, file)
this.router.navigate(['../overview', decoration._id], {relativeTo: this.route}); .subscribe(rank => {
}) this.saved = true;
this.router.navigate(['..'], {relativeTo: this.route});
})
} else {
return window.alert(`Bild ist ein Pflichtfeld`);
}
} else { } else {
return window.alert(`Bild ist ein Pflichtfeld`); if (this.fileList) {
file = this.fileList[0];
}
delete this.decoration['__v'];
this.decorationService.submitDecoration(this.decoration, file)
.subscribe(rank => {
setTimeout(() => {
this.imagePreviewSrc = 'resource/decoration/' + this.decoration._id + '.png?' + Date.now();
}, 300);
fileInput.value = '';
this.showSuccessLabel = true;
setTimeout(() => {
this.showSuccessLabel = false;
}, 2000)
})
} }
} }
cancel() { cancel() {
//this.location.back(); this.router.navigate([this.decoration._id ? '../..' : '..'], {relativeTo: this.route});
this.router.navigate(['/cc-decorations']);
return false; return false;
} }

View File

@ -16,6 +16,5 @@
<span (click)="delete(); $event.stopPropagation()" title="Löschen" class="glyphicon glyphicon-trash trash"></span> <span (click)="delete(); $event.stopPropagation()" title="Löschen" class="glyphicon glyphicon-trash trash"></span>
</div> </div>
</div> </div>
</div> </div>

View File

@ -63,7 +63,7 @@ export class DecorationService {
if (imageFile) { if (imageFile) {
body = new FormData(); body = new FormData();
Object.keys(decoration).map((objectKey) => { Object.keys(decoration).map((objectKey) => {
if (decoration[objectKey]) { if (decoration[objectKey] !== undefined) {
body.append(objectKey, decoration[objectKey]); body.append(objectKey, decoration[objectKey]);
} }
}); });

View File

@ -62,7 +62,7 @@ export class SquadService {
if (imageFile) { if (imageFile) {
body = new FormData(); body = new FormData();
Object.keys(squad).map((objectKey) => { Object.keys(squad).map((objectKey) => {
if (squad[objectKey]) { if (squad[objectKey] !== undefined) {
body.append(objectKey, squad[objectKey]); body.append(objectKey, squad[objectKey]);
} }
}); });

View File

@ -1,3 +1,7 @@
.preview-image {
margin: 10px;
}
.form-control { .form-control {
height: auto; height: auto;
} }

View File

@ -1,5 +1,6 @@
<form #form="ngForm" class="overview"> <form #form="ngForm" class="overview">
<h3>Neues Squad hinzufügen</h3> <h3 *ngIf="squad._id">Squad editieren</h3>
<h3 *ngIf="!squad._id">Neues Squad hinzufügen</h3>
<div class="form-group"> <div class="form-group">
<label for="title">Name</label> <label for="title">Name</label>
@ -33,11 +34,14 @@
<div class="form-group"> <div class="form-group">
<label for="logo">Logo</label> <label for="logo">Logo</label>
<input id="logo" name="logo" class="ui-button form-control" type="file" <input id="logo" name="logo" class="ui-button form-control" type="file"
#fileInput
accept="image/png" accept="image/png"
(change)="fileChange($event)"> (change)="fileChange($event)">
<span class="label label-bg label-danger center-block" style="font-size:small" *ngIf="showImageError"> <span class="label label-bg label-danger center-block" style="font-size:small" *ngIf="showImageError">
Bild muss im PNG Format vorliegen Bild muss im PNG Format vorliegen
</span> </span>
<img class="preview-image" src="{{imagePreviewSrc}}">
</div> </div>
<button id="cancel" <button id="cancel"
@ -45,16 +49,18 @@
class="btn btn-default"> class="btn btn-default">
Abbrechen Abbrechen
</button> </button>
<!--
<a class="btn btn-default"
[routerLink]="task.id ? '../..' : '../'">
Abbrechen
</a>
-->
<button id="save" <button id="save"
(click)="saveSquad()" (click)="saveSquad(fileInput)"
class="btn btn-default" class="btn btn-default"
[disabled]="!form.valid"> [disabled]="!form.valid">
Squad speichern Bestätigen
</button> </button>
<span *ngIf="showSuccessLabel"
class="label label-success label-small"
style="margin-left: inherit">
Erfolgreich gespeichert
</span>
</form> </form>

View File

@ -3,6 +3,7 @@ import {ActivatedRoute, Router} from "@angular/router";
import {NgForm} from "@angular/forms"; import {NgForm} from "@angular/forms";
import {Squad} from "../../models/model-interfaces"; import {Squad} from "../../models/model-interfaces";
import {SquadService} from "../../services/squad-service/squad.service"; import {SquadService} from "../../services/squad-service/squad.service";
import {Subscription} from "rxjs/Subscription";
@Component({ @Component({
@ -11,6 +12,8 @@ import {SquadService} from "../../services/squad-service/squad.service";
}) })
export class CreateSquadComponent { export class CreateSquadComponent {
subscription: Subscription;
squad: Squad = {name: '', fraction: '', sortingNumber: 0}; squad: Squad = {name: '', fraction: '', sortingNumber: 0};
fileList: FileList; fileList: FileList;
@ -19,6 +22,10 @@ export class CreateSquadComponent {
showImageError = false; showImageError = false;
showSuccessLabel = false;
imagePreviewSrc;
@ViewChild(NgForm) form: NgForm; @ViewChild(NgForm) form: NgForm;
constructor(private route: ActivatedRoute, constructor(private route: ActivatedRoute,
@ -27,7 +34,18 @@ export class CreateSquadComponent {
} }
ngOnInit() { ngOnInit() {
this.subscription = this.route.params
.map(params => params['id'])
.filter(id => id != undefined)
.flatMap(id => this.squadService.getSquad(id))
.subscribe(squad => {
this.squad = squad;
this.imagePreviewSrc = 'resource/squad/' + this.squad._id + '.png?' + Date.now();
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
} }
fileChange(event) { fileChange(event) {
@ -40,22 +58,40 @@ export class CreateSquadComponent {
} }
} }
saveSquad() { saveSquad(fileInput) {
if (this.fileList) { let file: File;
let file: File = this.fileList[0]; if (!this.squad._id) {
this.squadService.submitSquad(this.squad, file) if (this.fileList) {
.subscribe(squad => { file = this.fileList[0];
this.saved = true; this.squadService.submitSquad(this.squad, file)
this.router.navigate(['../overview', squad._id], {relativeTo: this.route}); .subscribe(rank => {
}) this.saved = true;
this.router.navigate(['..'], {relativeTo: this.route});
})
} else {
return window.alert(`Bild ist ein Pflichtfeld`);
}
} else { } else {
return window.alert(`Bild ist ein Pflichtfeld`); if (this.fileList) {
file = this.fileList[0];
}
delete this.squad['__v'];
this.squadService.submitSquad(this.squad, file)
.subscribe(rank => {
setTimeout(() => {
this.imagePreviewSrc = 'resource/squad/' + this.squad._id + '.png?' + Date.now();
}, 300);
fileInput.value = '';
this.showSuccessLabel = true;
setTimeout(() => {
this.showSuccessLabel = false;
}, 2000)
})
} }
} }
cancel() { cancel() {
//this.location.back(); this.router.navigate([this.squad._id ? '../..' : '..'], {relativeTo: this.route});
this.router.navigate(['/cc-squads']);
return false; return false;
} }

View File

@ -11,6 +11,11 @@ div.squad-list-entry, a.squad-list-entry {
background: lightgrey; background: lightgrey;
} }
.squad-list-preview {
float: left;
margin-right: 12px;
}
span { span {
cursor: pointer; cursor: pointer;
} }
@ -25,9 +30,9 @@ small {
} }
.trash { .trash {
float:right;
padding-top: 18px; padding-top: 18px;
font-size: 17px; font-size: 17px;
margin-left: -10px;
} }
.selected { .selected {

View File

@ -1,7 +1,7 @@
<div class="fade-in squad-list-entry" [ngClass]="{selected : selected}" (click)="select()"> <div class="fade-in squad-list-entry" [ngClass]="{selected : selected}" (click)="select()">
<div class="row"> <div class="row">
<div class="col-xs-11"> <div class="col-xs-9">
<span> <span>
<a>{{squad.name}}</a> <a>{{squad.name}}</a>
</span> </span>
@ -9,5 +9,10 @@
<small *ngIf="squad.fraction == 'OPFOR'">CSAT</small> <small *ngIf="squad.fraction == 'OPFOR'">CSAT</small>
<small *ngIf="squad.fraction == 'BLUFOR'">NATO</small> <small *ngIf="squad.fraction == 'BLUFOR'">NATO</small>
</div> </div>
<div class="col-xs-3">
<img src="{{imageSrc}}" height="50px" class="squad-list-preview">
<span (click)="delete(); $event.stopPropagation()" title="Löschen" class="glyphicon glyphicon-trash trash"></span>
</div>
</div> </div>
</div> </div>

View File

@ -1,6 +1,6 @@
import {ChangeDetectionStrategy, Component, EventEmitter} from "@angular/core"; import {ChangeDetectionStrategy, Component, EventEmitter} from "@angular/core";
import {Router} from "@angular/router"; import {Router} from "@angular/router";
import {Squad, User} from "../../models/model-interfaces"; import {Squad} from "../../models/model-interfaces";
@Component({ @Component({
selector: 'pjm-squad-item', selector: 'pjm-squad-item',
@ -18,8 +18,13 @@ export class SquadItemComponent {
squadSelected = new EventEmitter(); squadSelected = new EventEmitter();
squadDelete = new EventEmitter(); squadDelete = new EventEmitter();
constructor(private router: Router) { imageSrc;
constructor(private router: Router) {
}
ngOnInit() {
this.imageSrc = 'resource/squad/' + this.squad._id + '.png?' + Date.now();
} }
select() { select() {

View File

@ -42,7 +42,7 @@
<div> <div>
<pjm-squad-item *ngFor="let squad of squads$ | async" <pjm-squad-item *ngFor="let squad of squads$ | async"
[squad]="squad" [squad]="squad"
(squadDelete)="deleteUser(squad)" (squadDelete)="deleteSquad(squad)"
(squadSelected)="selectSquad($event)" (squadSelected)="selectSquad($event)"
[selected]="squad._id == selectedSquadId"> [selected]="squad._id == selectedSquadId">
</pjm-squad-item> </pjm-squad-item>

View File

@ -48,12 +48,22 @@ export class SquadListComponent implements OnInit {
} }
openNewSquadForm() { openNewSquadForm() {
this.selectedSquadId = null;
this.router.navigate([{outlets: {'right': ['new']}}], {relativeTo: this.route}); this.router.navigate([{outlets: {'right': ['new']}}], {relativeTo: this.route});
} }
selectSquad(squadId: string | number) { selectSquad(squadId: string | number) {
this.selectedSquadId = squadId; this.selectedSquadId = squadId;
this.router.navigate([{outlets: {'right': ['overview', squadId]}}], {relativeTo: this.route}); this.router.navigate([{outlets: {'right': ['edit', squadId]}}], {relativeTo: this.route});
}
deleteSquad(squad) {
const fraction = squad.fraction === 'OPFOR' ? 'CSAT' : 'NATO';
if (confirm('Soll das Squad "' + squad.name + '" (' + fraction + ') wirklich gelöscht werden?')) {
this.squadService.deleteSquad(squad)
.subscribe((res) => {
})
}
} }
filterSquadsByFraction(query = '', fractionFilter) { filterSquadsByFraction(query = '', fractionFilter) {

View File

@ -1,107 +0,0 @@
<div class="overview">
<h3 style="margin-bottom: 25px">Squad-Details
<span *ngIf="showSuccessLabel"
class="label label-success label-small"
style="margin-left: inherit">
Erfolgreich gespeichert
</span>
</h3>
<div *ngIf="squad">
<div class="col-xs-12">
<div class="div-table">
<div class="div-table-row">
<div class="div-table-col content-s">
<label>Name:</label>
</div>
<div class="div-table-col content content-m">
{{squad.name}}
</div>
<div class="div-table-col content-l">
<input class="form-control" width="250px" placeholder="Neuer Name" #newNameInput>
</div>
<div class="div-table-col content-s">
<a class="pull-right btn btn-sm btn-block btn-default" (click)="update('name',newNameInput)">Bestätigen</a>
</div>
</div>
<div class="div-table-col content-s">
<label>Fraktion:</label>
</div>
<div class="div-table-col fraction-opfor content-m" *ngIf="squad.fraction == 'OPFOR'">
CSAT
</div>
<div class="div-table-col fraction-blufor content-m" *ngIf="squad.fraction == 'BLUFOR'">
NATO
</div>
<div class="div-table-col">
</div>
</div>
<hr>
<div class="div-table">
<div class="div-table-row">
<div class="div-table-col content-s">
<label>Sortierung:</label>
</div>
<div class="div-table-col content content-m">
{{squad.sortingNumber}}
</div>
<div class="div-table-col content-l">
<input type="number" class="form-control" width="250px" placeholder="Neue Sortierung" #sortingNumberInput>
</div>
<div class="div-table-col content-s">
<a class="pull-right btn btn-sm btn-block btn-default"
(click)="update('sortingNumber', sortingNumberInput)">Bestätigen</a>
</div>
</div>
</div>
<hr>
<div class="div-table">
<div class="div-table-row">
<div class="div-table-col content-s">
<label>Logo:</label>
</div>
<div class="div-table-col content-m-flex">
<img src="{{imagePreview}}">
</div>
<div class="div-table-col content-l">
<label class="control-label">Neues Logo</label>
<input class="form-control" type="file" accept="image/png" #newLogoInput (change)="fileChange($event)">
<span class="label label-bg label-danger center-block" style="font-size:small" *ngIf="showImageError">
Bild muss im PNG Format vorliegen
</span>
</div>
<div class="div-table-col content-s">
<a class="pull-right btn btn-sm btn-block btn-default"
(click)="updateGraphic(newLogoInput)">Bestätigen</a>
</div>
</div>
</div>
<hr>
<div class="div-table">
<div class="div-table-row">
<div class="div-table-col content-s">
<label>Löschen:</label>
</div>
<div class="div-table-col content-l" align="center">
<input class="form-control" #confirmInput placeholder="Squadnamen zur Bestätigung eingeben"
style="width:290px">
</div>
<div class="div-table-col content-m">
&nbsp;
</div>
<div class="div-table-col content-s">
<a class="pull-right btn btn-sm btn-block btn-default" (click)="deleteSquad(confirmInput.value)">Squad
Löschen</a>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -1,92 +0,0 @@
import {Component} from "@angular/core";
import {ActivatedRoute, Router} from "@angular/router";
import {Squad} from "../../models/model-interfaces";
import {SquadService} from "../../services/squad-service/squad.service";
@Component({
templateUrl: './squad-overview.component.html',
styleUrls: ['./squad-overview.component.css', '../../style/overview.css'],
})
export class SquadOverviewComponent {
showSuccessLabel = false;
showImageError = false;
squad: Squad;
fileList: FileList;
imagePreview;
constructor(private router: Router,
private route: ActivatedRoute,
private squadService: SquadService) {
}
ngOnInit() {
this.route.params.subscribe((params) => {
this.squadService.getSquad(params['id']).subscribe(squad => {
this.squad = squad;
this.imagePreview = 'resource/squad/' + squad._id + '.png?' + Date.now();
})
})
}
/**
* register file change and save to fileList
*/
fileChange(event) {
if (!event.target.files[0].name.endsWith('.png')) {
this.showImageError = true;
this.fileList = undefined;
} else {
this.showImageError = false;
this.fileList = event.target.files;
}
}
update(attrName, inputField) {
const inputValue = inputField.value;
if (inputValue.length > 0 && this.squad[attrName] !== inputValue) {
const updateObject = {_id: this.squad._id};
updateObject[attrName] = inputValue;
this.squadService.submitSquad(updateObject)
.subscribe(squad => {
this.squad = squad;
inputField.value = '';
this.showSuccessLabel = true;
setTimeout(() => {
this.showSuccessLabel = false;
}, 2000)
})
}
}
updateGraphic(fileInput) {
if (this.fileList && this.fileList.length > 0) {
let file: File = this.fileList[0];
this.squadService.submitSquad({_id: this.squad._id}, file)
.subscribe((res) => {
setTimeout(() => {
this.imagePreview = 'resource/squad/' + this.squad._id + '.png?' + Date.now();
}, 300);
fileInput.value = '';
this.showSuccessLabel = true;
setTimeout(() => {
this.showSuccessLabel = false;
}, 2000)
})
}
}
deleteSquad(confirm) {
if (confirm.toLowerCase() === this.squad.name.toLocaleLowerCase()) {
this.squadService.deleteSquad(this.squad)
.subscribe((res) => {
this.router.navigate(['../..'], {relativeTo: this.route});
})
}
}
}

View File

@ -1,6 +1,5 @@
import {Routes} from "@angular/router"; import {Routes} from "@angular/router";
import {SquadComponent} from "./squads.component"; import {SquadComponent} from "./squads.component";
import {SquadOverviewComponent} from "./squad-overview/squad-overview.component";
import {SquadListComponent} from "./squad-list/squad-list.component"; import {SquadListComponent} from "./squad-list/squad-list.component";
import {CreateSquadComponent} from "./new-squad/new-squad.component"; import {CreateSquadComponent} from "./new-squad/new-squad.component";
@ -19,10 +18,10 @@ export const squadsRoutes: Routes = [{
outlet: 'right' outlet: 'right'
}, },
{ {
path: 'overview/:id', path: 'edit/:id',
component: SquadOverviewComponent, component: CreateSquadComponent,
outlet: 'right' outlet: 'right'
}]; }];
export const squadsRoutingComponents = [SquadComponent, SquadListComponent, SquadOverviewComponent, CreateSquadComponent]; export const squadsRoutingComponents = [SquadComponent, SquadListComponent, CreateSquadComponent];

View File

@ -63,7 +63,7 @@ export class UserListComponent implements OnInit {
} }
deleteUser(user: User) { deleteUser(user: User) {
if (confirm('Soll der Teilnehmer ' + user.username + ' wirklich gelöscht werden?')) { if (confirm('Soll der Teilnehmer "' + user.username + '" wirklich gelöscht werden?')) {
this.userService.deleteUser(user) this.userService.deleteUser(user)
.subscribe((res) => { .subscribe((res) => {
}) })