Compare commits
No commits in common. "efcecf7b131d5ed21c919db747e7a8d6363c9d8d" and "be12e756a0d6b5ccab8b3e342c0b6982416865cb" have entirely different histories.
efcecf7b13
...
be12e756a0
|
@ -0,0 +1,69 @@
|
||||||
|
/** This module defines a express.Router() instance
|
||||||
|
* - supporting offset=<number> and limit=<number>*
|
||||||
|
* - calls next with error if a impossible offset and/or limit value is given
|
||||||
|
*
|
||||||
|
* Note: it expects to be called BEFORE any data fetched from DB
|
||||||
|
* Note: it sets an object { limit: 0, skip: 0 } with the proper number values in req.locals.limitskip
|
||||||
|
* Note: it sets an Error-Object to next with error.status set to HTTP status code 400
|
||||||
|
*
|
||||||
|
* @author Johannes Konert
|
||||||
|
* @licence CC BY-SA 4.0
|
||||||
|
*
|
||||||
|
* @module restapi/limitoffset-middleware-mongo
|
||||||
|
* @type {Router}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// remember: in modules you have 3 variables given by CommonJS
|
||||||
|
// 1.) require() function
|
||||||
|
// 2.) module.exports
|
||||||
|
// 3.) exports (which is module.exports)
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const router = require('express').Router();
|
||||||
|
const logger = require('debug')('me2:offsetlimit');
|
||||||
|
|
||||||
|
|
||||||
|
// the exported router with handler
|
||||||
|
router.use((req, res, next) => {
|
||||||
|
let offset = undefined;
|
||||||
|
let limit = undefined;
|
||||||
|
const offsetString = req.query.offset;
|
||||||
|
const limitString = req.query.limit;
|
||||||
|
let err = null;
|
||||||
|
|
||||||
|
|
||||||
|
if (offsetString) {
|
||||||
|
if (!isNaN(offsetString)) {
|
||||||
|
offset = parseInt(offsetString);
|
||||||
|
if (offset < 0) {
|
||||||
|
err = new Error('offset is negative')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
err = new Error('given offset is not a valid number ' + offsetString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (limitString) {
|
||||||
|
if (!isNaN(limitString)) {
|
||||||
|
limit = parseInt(limitString);
|
||||||
|
if (limit < 1) {
|
||||||
|
err = new Error('limit is zero or negative')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
err = new Error('given limit is not a valid number ' + limitString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (err) {
|
||||||
|
logger('problem occurred with limit/offset values');
|
||||||
|
err.status = 400;
|
||||||
|
next(err)
|
||||||
|
} else {
|
||||||
|
res.locals.limitskip = {}; // mongoDB uses parameter object for skip/limit
|
||||||
|
if (limit) res.locals.limitskip.limit = limit;
|
||||||
|
if (offset) res.locals.limitskip.skip = offset;
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
|
@ -93,9 +93,8 @@ describe('Users', () => {
|
||||||
res.should.have.status(codes.created);
|
res.should.have.status(codes.created);
|
||||||
res.body.should.be.a('object');
|
res.body.should.be.a('object');
|
||||||
res.body.should.have.property('username').eql(user.username);
|
res.body.should.have.property('username').eql(user.username);
|
||||||
res.body.should.have.property('squad').eql(null);
|
res.body.should.have.property('squadId').eql(null);
|
||||||
res.body.should.have.property('rank').property('level').eql(0);
|
res.body.should.have.property('rankLvl').eql(0);
|
||||||
res.body.should.have.property('awards').eql([]);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
div.decoration-list-entry, a.decoration-list-entry {
|
||||||
|
padding: 8px;
|
||||||
|
width: 475px;
|
||||||
|
border-radius: 2px;
|
||||||
|
border: lightgrey solid 1px;
|
||||||
|
cursor: cell;
|
||||||
|
margin-bottom: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.decoration-list-preview {
|
||||||
|
float: left;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marked {
|
||||||
|
background: lightgrey;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-size: x-large;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
color: grey;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trash {
|
||||||
|
float:right;
|
||||||
|
padding-top: 18px;
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected {
|
||||||
|
background-color: aliceblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-moz-keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-in {
|
||||||
|
opacity: 0; /* make things invisible upon start */
|
||||||
|
-webkit-animation: fadeIn ease-in 1; /* call our keyframe named fadeIn, use animattion ease-in and repeat it only 1 time */
|
||||||
|
-moz-animation: fadeIn ease-in 1;
|
||||||
|
animation: fadeIn ease-in 1;
|
||||||
|
|
||||||
|
-webkit-animation-fill-mode: forwards; /* this makes sure that after animation is done we remain at the last keyframe value (opacity: 1)*/
|
||||||
|
-moz-animation-fill-mode: forwards;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
|
||||||
|
-webkit-animation-duration: 0.5s;
|
||||||
|
-moz-animation-duration: 0.5s;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="fade-in 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-9">
|
<div class="col-xs-9">
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {Decoration} from "../../models/model-interfaces";
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'pjm-decoration-item',
|
selector: 'pjm-decoration-item',
|
||||||
templateUrl: './decoration-item.component.html',
|
templateUrl: './decoration-item.component.html',
|
||||||
styleUrls: ['./decoration-item.component.css', '../../style/list-entry.css'],
|
styleUrls: ['./decoration-item.component.css'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
inputs: ['decoration', 'selected'],
|
inputs: ['decoration', 'selected'],
|
||||||
outputs: ['decorationDelete','decorationSelected'],
|
outputs: ['decorationDelete','decorationSelected'],
|
||||||
|
@ -42,5 +42,9 @@ export class DecorationItemComponent {
|
||||||
this.decorationDelete.emit(this.decoration);
|
this.decorationDelete.emit(this.decoration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngAfterViewChecked() {
|
||||||
|
//var taskId = (this.task ? this.task.id : '');
|
||||||
|
// console.log(`Task ${taskId} checked ${++this.checkCounter} times`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {Routes} from "@angular/router";
|
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 {EditDecorationComponent} from "./edit-decoration/edit-decoration.component";
|
import {CreateDecorationComponent} from "./new-decoration/new-decoration.component";
|
||||||
|
|
||||||
export const decorationsRoutes: Routes = [{
|
export const decorationsRoutes: Routes = [{
|
||||||
path: '', component: DecorationComponent,
|
path: '', component: DecorationComponent,
|
||||||
|
@ -14,14 +14,14 @@ export const decorationsRoutes: Routes = [{
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'new',
|
path: 'new',
|
||||||
component: EditDecorationComponent,
|
component: CreateDecorationComponent,
|
||||||
outlet: 'right'
|
outlet: 'right'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'edit/:id',
|
path: 'edit/:id',
|
||||||
component: EditDecorationComponent,
|
component: CreateDecorationComponent,
|
||||||
outlet: 'right'
|
outlet: 'right'
|
||||||
}];
|
}];
|
||||||
|
|
||||||
export const decorationsRoutingComponents = [DecorationComponent, DecorationListComponent, EditDecorationComponent];
|
export const decorationsRoutingComponents = [DecorationComponent, DecorationListComponent, CreateDecorationComponent];
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
.preview-image {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
height: auto;
|
||||||
|
}
|
|
@ -6,10 +6,10 @@ import {DecorationService} from "../../services/decoration-service/decoration.se
|
||||||
import {Subscription} from "rxjs/Subscription";
|
import {Subscription} from "rxjs/Subscription";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './edit-decoration.component.html',
|
templateUrl: './new-decoration.component.html',
|
||||||
styleUrls: ['./edit-decoration.component.css', '../../style/entry-form.css']
|
styleUrls: ['./new-decoration.component.css', '../../style/new-entry-form.css']
|
||||||
})
|
})
|
||||||
export class EditDecorationComponent {
|
export class CreateDecorationComponent {
|
||||||
|
|
||||||
subscription: Subscription;
|
subscription: Subscription;
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@ export class EditDecorationComponent {
|
||||||
|
|
||||||
fileList: FileList;
|
fileList: FileList;
|
||||||
|
|
||||||
|
saved = false;
|
||||||
|
|
||||||
showImageError = false;
|
showImageError = false;
|
||||||
|
|
||||||
imagePreviewSrc;
|
imagePreviewSrc;
|
||||||
|
@ -62,6 +64,7 @@ export class EditDecorationComponent {
|
||||||
file = this.fileList[0];
|
file = this.fileList[0];
|
||||||
this.decorationService.submitDecoration(this.decoration, file)
|
this.decorationService.submitDecoration(this.decoration, file)
|
||||||
.subscribe(rank => {
|
.subscribe(rank => {
|
||||||
|
this.saved = true;
|
||||||
this.router.navigate(['..'], {relativeTo: this.route});
|
this.router.navigate(['..'], {relativeTo: this.route});
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
@ -91,4 +94,11 @@ export class EditDecorationComponent {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canDeactivate(): boolean {
|
||||||
|
if (this.saved || !this.form.dirty) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return window.confirm(`Ihr Formular besitzt ungespeicherte Änderungen, möchten Sie die Seite wirklich verlassen?`);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1 +0,0 @@
|
||||||
|
|
|
@ -1,5 +1,83 @@
|
||||||
|
div.rank-list-entry, a.rank-list-entry {
|
||||||
|
padding: 8px;
|
||||||
|
width: 475px;
|
||||||
|
border-radius: 2px;
|
||||||
|
border: lightgrey solid 1px;
|
||||||
|
cursor: cell;
|
||||||
|
margin-bottom: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
.rank-list-preview {
|
.rank-list-preview {
|
||||||
height: 54px;
|
height: 54px;
|
||||||
float: left;
|
float: left;
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.marked {
|
||||||
|
background: lightgrey;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-size: x-large;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
color: grey;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trash {
|
||||||
|
float:right;
|
||||||
|
padding-top: 18px;
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected {
|
||||||
|
background-color: aliceblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-moz-keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-in {
|
||||||
|
opacity: 0; /* make things invisible upon start */
|
||||||
|
-webkit-animation: fadeIn ease-in 1; /* call our keyframe named fadeIn, use animattion ease-in and repeat it only 1 time */
|
||||||
|
-moz-animation: fadeIn ease-in 1;
|
||||||
|
animation: fadeIn ease-in 1;
|
||||||
|
|
||||||
|
-webkit-animation-fill-mode: forwards; /* this makes sure that after animation is done we remain at the last keyframe value (opacity: 1)*/
|
||||||
|
-moz-animation-fill-mode: forwards;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
|
||||||
|
-webkit-animation-duration: 0.5s;
|
||||||
|
-moz-animation-duration: 0.5s;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="fade-in list-entry" [ngClass]="{selected : selected}" (click)="select()">
|
<div class="fade-in rank-list-entry" [ngClass]="{selected : selected}" (click)="select()">
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-9">
|
<div class="col-xs-9">
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {Rank} from "../../models/model-interfaces";
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'pjm-rank-item',
|
selector: 'pjm-rank-item',
|
||||||
templateUrl: './rank-item.component.html',
|
templateUrl: './rank-item.component.html',
|
||||||
styleUrls: ['./rank-item.component.css', '../../style/list-entry.css'],
|
styleUrls: ['./rank-item.component.css'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
inputs: ['rank', 'selected'],
|
inputs: ['rank', 'selected'],
|
||||||
outputs: ['rankSelected', 'rankDelete'],
|
outputs: ['rankSelected', 'rankDelete'],
|
||||||
|
@ -35,5 +35,9 @@ export class RankItemComponent {
|
||||||
this.rankDelete.emit(this.rank);
|
this.rankDelete.emit(this.rank);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngAfterViewChecked() {
|
||||||
|
//var taskId = (this.task ? this.task.id : '');
|
||||||
|
// console.log(`Task ${taskId} checked ${++this.checkCounter} times`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ export class RankListComponent implements OnInit {
|
||||||
|
|
||||||
selectRank(rankId: string | number) {
|
selectRank(rankId: string | number) {
|
||||||
this.selectedRankId = rankId;
|
this.selectedRankId = rankId;
|
||||||
this.router.navigate([{outlets: {'right': ['edit', rankId]}}], {relativeTo: this.route});
|
this.router.navigate([{outlets: {'right': ['new', rankId]}}], {relativeTo: this.route});
|
||||||
}
|
}
|
||||||
|
|
||||||
filterRanksByFraction(query = '', fractionFilter) {
|
filterRanksByFraction(query = '', fractionFilter) {
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
.preview-image {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
height: auto;
|
||||||
|
}
|
|
@ -7,10 +7,10 @@ import {Subscription} from "rxjs/Subscription";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './edit-rank.component.html',
|
templateUrl: './new-rank.component.html',
|
||||||
styleUrls: ['./edit-rank.component.css', '../../style/entry-form.css']
|
styleUrls: ['./new-rank.component.css', '../../style/new-entry-form.css']
|
||||||
})
|
})
|
||||||
export class EditRankComponent {
|
export class CreateRankComponent {
|
||||||
|
|
||||||
subscription: Subscription;
|
subscription: Subscription;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {Routes} from "@angular/router";
|
import {Routes} from "@angular/router";
|
||||||
import {RankComponent} from "./ranks.component";
|
import {RankComponent} from "./ranks.component";
|
||||||
import {RankListComponent} from "./rank-list/rank-list.component";
|
import {RankListComponent} from "./rank-list/rank-list.component";
|
||||||
import {EditRankComponent} from "./edit-rank/edit-rank.component";
|
import {CreateRankComponent} from "./rank-new/new-rank.component";
|
||||||
|
|
||||||
|
|
||||||
export const ranksRoutes: Routes = [{
|
export const ranksRoutes: Routes = [{
|
||||||
|
@ -15,14 +15,14 @@ export const ranksRoutes: Routes = [{
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'new',
|
path: 'new',
|
||||||
component: EditRankComponent,
|
component: CreateRankComponent,
|
||||||
outlet: 'right'
|
outlet: 'right'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'edit/:id',
|
path: 'new/:id',
|
||||||
component: EditRankComponent,
|
component: CreateRankComponent,
|
||||||
outlet: 'right'
|
outlet: 'right'
|
||||||
}];
|
}];
|
||||||
|
|
||||||
export const ranksRoutingComponents = [RankComponent, RankListComponent, EditRankComponent];
|
export const ranksRoutingComponents = [RankComponent, RankListComponent, CreateRankComponent];
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
.preview-image {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
height: auto;
|
||||||
|
}
|
|
@ -7,10 +7,10 @@ import {Subscription} from "rxjs/Subscription";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './edit-squad.component.html',
|
templateUrl: './new-squad.component.html',
|
||||||
styleUrls: ['./edit-squad.component.css', '../../style/entry-form.css']
|
styleUrls: ['./new-squad.component.css', '../../style/new-entry-form.css']
|
||||||
})
|
})
|
||||||
export class EditSquadComponent {
|
export class CreateSquadComponent {
|
||||||
|
|
||||||
subscription: Subscription;
|
subscription: Subscription;
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
div.squad-list-entry, a.squad-list-entry {
|
||||||
|
padding: 8px;
|
||||||
|
width: 475px;
|
||||||
|
border-radius: 2px;
|
||||||
|
border: lightgrey solid 1px;
|
||||||
|
cursor: cell;
|
||||||
|
margin-bottom: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marked {
|
||||||
|
background: lightgrey;
|
||||||
|
}
|
||||||
|
|
||||||
|
.squad-list-preview {
|
||||||
|
float: left;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-size: x-large;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
color: grey;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trash {
|
||||||
|
float:right;
|
||||||
|
padding-top: 18px;
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected {
|
||||||
|
background-color: aliceblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-moz-keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-in {
|
||||||
|
opacity: 0; /* make things invisible upon start */
|
||||||
|
-webkit-animation: fadeIn ease-in 1; /* call our keyframe named fadeIn, use animattion ease-in and repeat it only 1 time */
|
||||||
|
-moz-animation: fadeIn ease-in 1;
|
||||||
|
animation: fadeIn ease-in 1;
|
||||||
|
|
||||||
|
-webkit-animation-fill-mode: forwards; /* this makes sure that after animation is done we remain at the last keyframe value (opacity: 1)*/
|
||||||
|
-moz-animation-fill-mode: forwards;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
|
||||||
|
-webkit-animation-duration: 0.5s;
|
||||||
|
-moz-animation-duration: 0.5s;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="fade-in 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-9">
|
<div class="col-xs-9">
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {Squad} from "../../models/model-interfaces";
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'pjm-squad-item',
|
selector: 'pjm-squad-item',
|
||||||
templateUrl: './squad-item.component.html',
|
templateUrl: './squad-item.component.html',
|
||||||
styleUrls: ['./squad-item.component.css', '../../style/list-entry.css'],
|
styleUrls: ['./squad-item.component.css'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
inputs: ['squad', 'selected'],
|
inputs: ['squad', 'selected'],
|
||||||
outputs: ['squadSelected', 'squadDelete'],
|
outputs: ['squadSelected', 'squadDelete'],
|
||||||
|
@ -35,5 +35,9 @@ export class SquadItemComponent {
|
||||||
this.squadDelete.emit(this.squad);
|
this.squadDelete.emit(this.squad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngAfterViewChecked() {
|
||||||
|
//var taskId = (this.task ? this.task.id : '');
|
||||||
|
// console.log(`Task ${taskId} checked ${++this.checkCounter} times`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {Routes} from "@angular/router";
|
import {Routes} from "@angular/router";
|
||||||
import {SquadComponent} from "./squads.component";
|
import {SquadComponent} from "./squads.component";
|
||||||
import {SquadListComponent} from "./squad-list/squad-list.component";
|
import {SquadListComponent} from "./squad-list/squad-list.component";
|
||||||
import {EditSquadComponent} from "./edit-squad/edit-squad.component";
|
import {CreateSquadComponent} from "./new-squad/new-squad.component";
|
||||||
|
|
||||||
export const squadsRoutes: Routes = [{
|
export const squadsRoutes: Routes = [{
|
||||||
path: '', component: SquadComponent,
|
path: '', component: SquadComponent,
|
||||||
|
@ -14,14 +14,14 @@ export const squadsRoutes: Routes = [{
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'new',
|
path: 'new',
|
||||||
component: EditSquadComponent,
|
component: CreateSquadComponent,
|
||||||
outlet: 'right'
|
outlet: 'right'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'edit/:id',
|
path: 'edit/:id',
|
||||||
component: EditSquadComponent,
|
component: CreateSquadComponent,
|
||||||
outlet: 'right'
|
outlet: 'right'
|
||||||
}];
|
}];
|
||||||
|
|
||||||
export const squadsRoutingComponents = [SquadComponent, SquadListComponent, EditSquadComponent];
|
export const squadsRoutingComponents = [SquadComponent, SquadListComponent, CreateSquadComponent];
|
||||||
|
|
||||||
|
|
|
@ -1,93 +0,0 @@
|
||||||
div.list-entry, a.list-entry,
|
|
||||||
div.user-list-entry, a.user-list-entry {
|
|
||||||
padding: 8px;
|
|
||||||
width: 475px;
|
|
||||||
border-radius: 2px;
|
|
||||||
border: lightgrey solid 1px;
|
|
||||||
cursor: cell;
|
|
||||||
margin-bottom: -1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-list-entry a {
|
|
||||||
font-size: large;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-list-entry small {
|
|
||||||
color: grey;
|
|
||||||
font-size: x-small;
|
|
||||||
}
|
|
||||||
|
|
||||||
.decoration-list-preview, .squad-list-preview {
|
|
||||||
float: left;
|
|
||||||
margin-right: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.marked {
|
|
||||||
background: lightgrey;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-entry a {
|
|
||||||
font-size: x-large;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-entry small {
|
|
||||||
color: grey;
|
|
||||||
}
|
|
||||||
|
|
||||||
.trash {
|
|
||||||
float:right;
|
|
||||||
padding-top: 18px;
|
|
||||||
font-size: 17px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected {
|
|
||||||
background-color: aliceblue;
|
|
||||||
}
|
|
||||||
|
|
||||||
@-webkit-keyframes fadeIn {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@-moz-keyframes fadeIn {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fadeIn {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.fade-in {
|
|
||||||
opacity: 0; /* make things invisible upon start */
|
|
||||||
-webkit-animation: fadeIn ease-in 1; /* call our keyframe named fadeIn, use animattion ease-in and repeat it only 1 time */
|
|
||||||
-moz-animation: fadeIn ease-in 1;
|
|
||||||
animation: fadeIn ease-in 1;
|
|
||||||
|
|
||||||
-webkit-animation-fill-mode: forwards; /* this makes sure that after animation is done we remain at the last keyframe value (opacity: 1)*/
|
|
||||||
-moz-animation-fill-mode: forwards;
|
|
||||||
animation-fill-mode: forwards;
|
|
||||||
|
|
||||||
-webkit-animation-duration: 0.5s;
|
|
||||||
-moz-animation-duration: 0.5s;
|
|
||||||
animation-duration: 0.5s;
|
|
||||||
}
|
|
|
@ -19,11 +19,3 @@ label {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.preview-image {
|
|
||||||
margin: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-control {
|
|
||||||
height: auto;
|
|
||||||
}
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
h3 {
|
||||||
|
margin-left: 4%;
|
||||||
|
margin-top: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overview {
|
||||||
|
position:fixed;
|
||||||
|
overflow-y:scroll;
|
||||||
|
overflow-x:hidden;
|
||||||
|
bottom: 10px;
|
||||||
|
width: 100%;
|
||||||
|
border-left: thin solid lightgrey;
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-top: 20px;
|
||||||
|
margin-left: 10px;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fraction-blufor {
|
||||||
|
font-size: large;
|
||||||
|
color: mediumblue;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fraction-opfor {
|
||||||
|
font-size: large;
|
||||||
|
color: red;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.div-table {
|
||||||
|
display: table;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-left: 8%;
|
||||||
|
width: auto;
|
||||||
|
background-color: rgba(240, 248, 255, 0.29);
|
||||||
|
border-spacing: 5px; /* cellspacing:poor IE support for this */
|
||||||
|
}
|
||||||
|
|
||||||
|
.div-table-row {
|
||||||
|
display: table-row;
|
||||||
|
width: auto;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.div-table-col {
|
||||||
|
float: left; /* fix for buggy browsers */
|
||||||
|
display: table-column;
|
||||||
|
padding: 5px 15px 5px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.div-table-head {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
font-size: large;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-xs {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-s {
|
||||||
|
width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-m {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-m-flex {
|
||||||
|
min-width: 200px;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-l {
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-xl {
|
||||||
|
width: 350px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-xxl {
|
||||||
|
width: 500px;
|
||||||
|
}
|
|
@ -18,7 +18,6 @@
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* enable scrolling for long list of awardings */
|
|
||||||
.overview {
|
.overview {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
|
@ -7,8 +7,8 @@ import {DecorationService} from "../../services/decoration-service/decoration.se
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './award-user.component.html',
|
templateUrl: './user-award.component.html',
|
||||||
styleUrls: ['./award-user.component.css'],
|
styleUrls: ['./user-award.component.css'],
|
||||||
})
|
})
|
||||||
export class UserAwardComponent {
|
export class UserAwardComponent {
|
||||||
|
|
|
@ -1,3 +1,16 @@
|
||||||
|
div.user-list-entry, a.user-list-entry {
|
||||||
|
padding: 8px;
|
||||||
|
width: 475px;
|
||||||
|
border-radius: 2px;
|
||||||
|
border: lightgrey solid 1px;
|
||||||
|
cursor: cell;
|
||||||
|
margin-bottom: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marked {
|
||||||
|
background: lightgrey;
|
||||||
|
}
|
||||||
|
|
||||||
.icon-award {
|
.icon-award {
|
||||||
background: url(../../../assets/award.png);
|
background: url(../../../assets/award.png);
|
||||||
width: 27px;
|
width: 27px;
|
||||||
|
@ -5,3 +18,73 @@
|
||||||
display: block;
|
display: block;
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.trash {
|
||||||
|
font-size: 19px;
|
||||||
|
margin-left: 12px;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-size: large;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
color: grey;
|
||||||
|
font-size: x-small;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit {
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected {
|
||||||
|
background-color: aliceblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-moz-keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-in {
|
||||||
|
opacity: 0; /* make things invisible upon start */
|
||||||
|
-webkit-animation: fadeIn ease-in 1; /* call our keyframe named fadeIn, use animattion ease-in and repeat it only 1 time */
|
||||||
|
-moz-animation: fadeIn ease-in 1;
|
||||||
|
animation: fadeIn ease-in 1;
|
||||||
|
|
||||||
|
-webkit-animation-fill-mode: forwards; /* this makes sure that after animation is done we remain at the last keyframe value (opacity: 1)*/
|
||||||
|
-moz-animation-fill-mode: forwards;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
|
||||||
|
-webkit-animation-duration: 0.5s;
|
||||||
|
-moz-animation-duration: 0.5s;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {User} from "../../models/model-interfaces";
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'pjm-user-item',
|
selector: 'pjm-user-item',
|
||||||
templateUrl: './user-item.component.html',
|
templateUrl: './user-item.component.html',
|
||||||
styleUrls: ['./user-item.component.css', '../../style/list-entry.css'],
|
styleUrls: ['./user-item.component.css'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
inputs: ['user', 'selected'],
|
inputs: ['user', 'selected'],
|
||||||
outputs: ['userSelected', 'userAward', 'userDelete']
|
outputs: ['userSelected', 'userAward', 'userDelete']
|
||||||
|
@ -35,5 +35,9 @@ export class UserItemComponent {
|
||||||
this.userDelete.emit(this.user);
|
this.userDelete.emit(this.user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngAfterViewChecked() {
|
||||||
|
//var taskId = (this.task ? this.task.id : '');
|
||||||
|
// console.log(`Task ${taskId} checked ${++this.checkCounter} times`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,12 +49,12 @@ export class UserListComponent implements OnInit {
|
||||||
|
|
||||||
openNewUserForm() {
|
openNewUserForm() {
|
||||||
this.selectedUserId = null;
|
this.selectedUserId = null;
|
||||||
this.router.navigate([{outlets: {'right': ['new']}}], {relativeTo: this.route});
|
this.router.navigate([{outlets: {'right': ['overview']}}], {relativeTo: this.route});
|
||||||
}
|
}
|
||||||
|
|
||||||
selectUser(userId: string) {
|
selectUser(userId: string) {
|
||||||
this.selectedUserId = userId;
|
this.selectedUserId = userId;
|
||||||
this.router.navigate([{outlets: {'right': ['edit', userId]}}], {relativeTo: this.route});
|
this.router.navigate([{outlets: {'right': ['overview', userId]}}], {relativeTo: this.route});
|
||||||
}
|
}
|
||||||
|
|
||||||
awardUser(userId) {
|
awardUser(userId) {
|
||||||
|
|
|
@ -9,24 +9,26 @@ import {NgForm} from "@angular/forms";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './edit-user.component.html',
|
templateUrl: './user-overview.component.html',
|
||||||
styleUrls: ['./edit-user.component.css', '../../style/entry-form.css'],
|
styleUrls: ['./user-overview.component.css', '../../style/new-entry-form.css'],
|
||||||
})
|
})
|
||||||
export class EditUserComponent {
|
export class UserOverviewComponent {
|
||||||
|
|
||||||
@ViewChild(NgForm) form: NgForm;
|
@ViewChild(NgForm) form: NgForm;
|
||||||
|
|
||||||
subscription: Subscription;
|
subscription: Subscription;
|
||||||
|
|
||||||
|
showSuccessLabel = false;
|
||||||
|
|
||||||
|
ranksDisplay = 'none';
|
||||||
|
|
||||||
user: User = {username: '', squad: '0', rank: {level: 0}};
|
user: User = {username: '', squad: '0', rank: {level: 0}};
|
||||||
|
|
||||||
squads: Squad[] = [];
|
squads: Squad[] = [];
|
||||||
|
|
||||||
ranks: Rank[] = [];
|
ranks: Rank[] = [];
|
||||||
|
|
||||||
showSuccessLabel = false;
|
saved = false;
|
||||||
|
|
||||||
ranksDisplay = 'none';
|
|
||||||
|
|
||||||
constructor(private router: Router,
|
constructor(private router: Router,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
|
@ -59,6 +61,10 @@ export class EditUserComponent {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
toggleRanks() {
|
toggleRanks() {
|
||||||
if (this.user.squad != '0') {
|
if (this.user.squad != '0') {
|
||||||
this.rankService.findRanks('', this.user.squad.fraction).subscribe(
|
this.rankService.findRanks('', this.user.squad.fraction).subscribe(
|
||||||
|
@ -104,6 +110,7 @@ export class EditUserComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cancel() {
|
cancel() {
|
||||||
this.router.navigate([this.user._id ? '../..' : '..'], {relativeTo: this.route});
|
this.router.navigate([this.user._id ? '../..' : '..'], {relativeTo: this.route});
|
||||||
return false;
|
return false;
|
||||||
|
@ -118,4 +125,11 @@ export class EditUserComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canDeactivate(): boolean {
|
||||||
|
if (this.saved || !this.form.dirty) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return window.confirm(`Ihr Formular besitzt ungespeicherte Änderungen, möchten Sie die Seite wirklich verlassen?`);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
import {Routes} from "@angular/router";
|
import {Routes} from "@angular/router";
|
||||||
import {UsersComponent} from "./users.component";
|
import {UsersComponent} from "./users.component";
|
||||||
import {EditUserComponent} from "./edit-user/edit-user.component";
|
import {UserOverviewComponent} from "./user-overview/user-overview.component";
|
||||||
import {UserListComponent} from "./user-list/user-list.component";
|
import {UserListComponent} from "./user-list/user-list.component";
|
||||||
import {UserAwardComponent} from "./award-user/award-user.component";
|
import {UserAwardComponent} from "./user-award/user-award.component";
|
||||||
|
|
||||||
export const usersRoutes: Routes = [{
|
export const usersRoutes: Routes = [{
|
||||||
path: '', component: UsersComponent,
|
path: '', component: UsersComponent,
|
||||||
|
@ -14,13 +14,13 @@ export const usersRoutes: Routes = [{
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'new',
|
path: 'overview',
|
||||||
component: EditUserComponent,
|
component: UserOverviewComponent,
|
||||||
outlet: 'right'
|
outlet: 'right'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'edit/:id',
|
path: 'overview/:id',
|
||||||
component: EditUserComponent,
|
component: UserOverviewComponent,
|
||||||
outlet: 'right'
|
outlet: 'right'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -30,4 +30,4 @@ export const usersRoutes: Routes = [{
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
export const usersRoutingComponents = [UsersComponent, UserListComponent, EditUserComponent, UserAwardComponent];
|
export const usersRoutingComponents = [UsersComponent, UserListComponent, UserOverviewComponent, UserAwardComponent];
|
||||||
|
|
Loading…
Reference in New Issue