commit
						3adc751ac8
					
				|  | @ -1,4 +1,4 @@ | ||||||
| ### Get Awardings [GET /awardings{?userId,inProgress,fractFilter}] | ### Get Awardings [GET /awardings{?userId,inProgress,fractFilter,squadId}] | ||||||
| 
 | 
 | ||||||
| List all awardings | List all awardings | ||||||
| 
 | 
 | ||||||
|  | @ -19,6 +19,9 @@ List all awardings | ||||||
|             + `OPFOR` |             + `OPFOR` | ||||||
|             + `GLOBAL` |             + `GLOBAL` | ||||||
| 
 | 
 | ||||||
|  |     + squadId: `5aba54eaeadcce6332c6a774` (string, optional) | ||||||
|  |         unique id of the squad | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| + Response 200 (application/json; charset=utf-8) | + Response 200 (application/json; charset=utf-8) | ||||||
| 
 | 
 | ||||||
|  | @ -58,16 +61,3 @@ Create a new awarding proposal, that needs to be approved by higher permission l | ||||||
| + Response 201 (application/json; charset=utf-8) | + Response 201 (application/json; charset=utf-8) | ||||||
| 
 | 
 | ||||||
|     + Attributes (Awarding, fixed-type) |     + Attributes (Awarding, fixed-type) | ||||||
| 
 |  | ||||||
| ### Get Unprocessed Squad Awardings [GET /awardings/unprocessed/{squadId}] |  | ||||||
| 
 |  | ||||||
| List all awardings that are requested and in pending decision status |  | ||||||
| 
 |  | ||||||
| **Permission: 1** |  | ||||||
| 
 |  | ||||||
| + Parameters |  | ||||||
|     + squadId: `5aba54eaeadcce6332c6a774` (string, required) - unique id of the squad in which awardings are requested |  | ||||||
| 
 |  | ||||||
| + Response 200 (application/json; charset=utf-8) |  | ||||||
| 
 |  | ||||||
|     + Attributes (array[AwardingPopulated], fixed-type) |  | ||||||
|  |  | ||||||
|  | @ -5,14 +5,17 @@ Get single army member information | ||||||
| + Parameters | + Parameters | ||||||
|     + q: `hardi` (string, optional) - filter string which filters for partial username |     + q: `hardi` (string, optional) - filter string which filters for partial username | ||||||
| 
 | 
 | ||||||
|     + fractFilter: `BLUFOR` (enum[string], optional) |     + fractFilter: `BLUFOR` (enum[string], optional) - Field to filter by fraction | ||||||
|         Field to filter by fraction |  | ||||||
| 
 | 
 | ||||||
|         + Members |         + Members | ||||||
|             + `BLUFOR` |             + `BLUFOR` | ||||||
|             + `OPFOR` |             + `OPFOR` | ||||||
|             + `GLOBAL` |             + `GLOBAL` | ||||||
| 
 | 
 | ||||||
|  |     + squadId: `591470249e9fae286e008e31` (string, optional) - Field to filter by membership of certain squad | ||||||
|  | 
 | ||||||
|  |     + decorationId: `5abd3dff6e6a0334d95b8ba0` (string, optional) - Field to filter by ownership of certain decoration | ||||||
|  | 
 | ||||||
|     + limit: 20 (number, optional) |     + limit: 20 (number, optional) | ||||||
|         Maximum number of users to return |         Maximum number of users to return | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,3 +1,12 @@ | ||||||
|  | ### Get Campaigns [GET /campaigns] | ||||||
|  | 
 | ||||||
|  | Get all campaigns information | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | + Response 200 (application/json; charset=utf-8) | ||||||
|  | 
 | ||||||
|  |     + Attributes (array[Campaign], fixed-type) | ||||||
|  | 
 | ||||||
| ### Get Campaign [GET /campaigns/{id}] | ### Get Campaign [GET /campaigns/{id}] | ||||||
| 
 | 
 | ||||||
| Get single campaign information | Get single campaign information | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -78,10 +78,10 @@ authenticate.route('/signup') | ||||||
|             .post((req, res, next) => { |             .post((req, res, next) => { | ||||||
|               create(req.body) |               create(req.body) | ||||||
|                 .then(() => { |                 .then(() => { | ||||||
|                   res.send(201, {message: 'User successfully created'}); |                   res.status(codes.created).send({message: 'User successfully created'}); | ||||||
|                 }) |                 }) | ||||||
|                 .catch((err) => { |                 .catch((err) => { | ||||||
|                   res.status(400).send(err); |                   res.status(codes.wrongrequest).send(err); | ||||||
|                 }); |                 }); | ||||||
|             }) |             }) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -12,7 +12,6 @@ const routerHandling = require('../middleware/router-handling'); | ||||||
| 
 | 
 | ||||||
| const apiAuthenticationMiddleware = require('../middleware/auth-middleware'); | const apiAuthenticationMiddleware = require('../middleware/auth-middleware'); | ||||||
| const checkHl = require('../middleware/permission-check').checkHl; | const checkHl = require('../middleware/permission-check').checkHl; | ||||||
| const checkSql = require('../middleware/permission-check').checkSql; |  | ||||||
| 
 | 
 | ||||||
| // Mongoose Model using mongoDB
 | // Mongoose Model using mongoDB
 | ||||||
| const AwardingModel = require('../models/awarding'); | const AwardingModel = require('../models/awarding'); | ||||||
|  | @ -25,41 +24,52 @@ const resultSet = { | ||||||
| 
 | 
 | ||||||
| const awarding = new express.Router(); | const awarding = new express.Router(); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| // routes **********************
 | // routes **********************
 | ||||||
| awarding.route('/') | awarding.route('/') | ||||||
|         .get((req, res, next) => { |         .get((req, res, next) => { | ||||||
|  |           const listAwardsCall = (filter) => | ||||||
|  |             AwardingModel.find(filter, {}, {sort: {date: 'desc'}}) | ||||||
|  |                          .populate('decorationId') | ||||||
|  |                          .populate('proposer', resultSet) | ||||||
|  |                          .populate('userId') | ||||||
|  |                          .exec((err, items) => { | ||||||
|  |                            if (err) { | ||||||
|  |                              err.status = codes.servererror; | ||||||
|  |                              return next(err); | ||||||
|  |                              // with return before (or after) the next(err) we prevent that the code continues here
 | ||||||
|  |                              // after next(err) has finished. this saves an extra else {..}
 | ||||||
|  |                            } | ||||||
|  |                            let results = []; | ||||||
|  |                            if (req.query.fractFilter) { | ||||||
|  |                              for (let item of items) { | ||||||
|  |                                if (item.decorationId.fraction === req.query.fractFilter) { | ||||||
|  |                                  results.push(item); | ||||||
|  |                                } | ||||||
|  |                              } | ||||||
|  |                              res.locals.items = results; | ||||||
|  |                            } else { | ||||||
|  |                              res.locals.items = items; | ||||||
|  |                            } | ||||||
|  |                            res.locals.processed = true; | ||||||
|  |                            return next(); | ||||||
|  |                          }); | ||||||
|  | 
 | ||||||
|           const filter = {}; |           const filter = {}; | ||||||
|           if (req.query.userId) { |           if (req.query.userId) { | ||||||
|             filter.userId = req.query.userId; |             filter.userId = req.query.userId; | ||||||
|           } |           } | ||||||
|           if (req.query.inProgress) { |           if (req.query.inProgress === 'true') { | ||||||
|             filter.confirmed = 0; |             filter.confirmed = 0; | ||||||
|           } |           } | ||||||
|           AwardingModel.find(filter, {}, {sort: {date: 'desc'}}) |           if (req.query.squadId) { | ||||||
|                        .populate('decorationId').populate('proposer', resultSet).populate('userId') |             UserModel.find({squadId: req.query.squadId}, (err, users) => { | ||||||
|                        .exec((err, items) => { |               const squadUserIds = users.map((user) => new mongoose.Types.ObjectId(user._id)); | ||||||
|                          if (err) { |               filter.userId = {$in: squadUserIds}; | ||||||
|                            err.status = codes.servererror; |               return listAwardsCall(filter); | ||||||
|                            return next(err); |             }); | ||||||
|                            // with return before (or after) the next(err) we prevent that the code continues here
 |           } else { | ||||||
|                            // after next(err) has finished. this saves an extra else {..}
 |             return listAwardsCall(filter); | ||||||
|                          } |           } | ||||||
|                          let results = []; |  | ||||||
|                          if (req.query.fractFilter) { |  | ||||||
|                            for (let item of items) { |  | ||||||
|                              if (item.decorationId.fraction === req.query.fractFilter) { |  | ||||||
|                                results.push(item); |  | ||||||
|                              } |  | ||||||
|                            } |  | ||||||
|                            res.locals.items = results; |  | ||||||
|                          } else { |  | ||||||
|                            res.locals.items = items; |  | ||||||
|                          } |  | ||||||
| 
 |  | ||||||
|                          res.locals.processed = true; |  | ||||||
|                          next(); |  | ||||||
|                        }); |  | ||||||
|         }) |         }) | ||||||
| 
 | 
 | ||||||
|         .post(apiAuthenticationMiddleware, checkHl, (req, res, next) => { |         .post(apiAuthenticationMiddleware, checkHl, (req, res, next) => { | ||||||
|  | @ -81,25 +91,6 @@ awarding.route('/') | ||||||
| 
 | 
 | ||||||
|         .all(routerHandling.httpMethodNotAllowed); |         .all(routerHandling.httpMethodNotAllowed); | ||||||
| 
 | 
 | ||||||
| awarding.route('/unprocessed/:squadId') |  | ||||||
|         .get(apiAuthenticationMiddleware, checkSql, (req, res, next) => { |  | ||||||
|           const filter = {squadId: req.params.squadId}; |  | ||||||
|           UserModel.find(filter, (err, users) => { |  | ||||||
|             if (!users || users.length === 0) { |  | ||||||
|               return next(); |  | ||||||
|             } |  | ||||||
|             const squadUserIds = users.map((user) => new mongoose.Types.ObjectId(user._id)); |  | ||||||
|             AwardingModel.find({userId: {$in: squadUserIds}, confirmed: 0}) |  | ||||||
|                          .populate('decorationId') |  | ||||||
|                          .populate('proposer', resultSet) |  | ||||||
|                          .populate('userId') |  | ||||||
|                          .exec((err, awards) => { |  | ||||||
|                            res.locals.items = awards; |  | ||||||
|                            next(); |  | ||||||
|                          }); |  | ||||||
|           }); |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
| awarding.route('/:id') | awarding.route('/:id') | ||||||
|         .patch(apiAuthenticationMiddleware, checkHl, (req, res, next) => { |         .patch(apiAuthenticationMiddleware, checkHl, (req, res, next) => { | ||||||
|           if (!req.body || (req.body._id && req.body._id !== req.params.id)) { |           if (!req.body || (req.body._id && req.body._id !== req.params.id)) { | ||||||
|  |  | ||||||
|  | @ -24,6 +24,26 @@ const campaigns = new express.Router(); | ||||||
| 
 | 
 | ||||||
| // routes **********************
 | // routes **********************
 | ||||||
| campaigns.route('/') | campaigns.route('/') | ||||||
|  |          .get((req, res, next) => { | ||||||
|  |            CampaignModel.find({}, {}, { | ||||||
|  |              sort: { | ||||||
|  |                timestamp: 'desc', | ||||||
|  |              }, | ||||||
|  |            }, (err, items) => { | ||||||
|  |              if (err) { | ||||||
|  |                err.status = codes.servererror; | ||||||
|  |                return next(err); | ||||||
|  |              } | ||||||
|  |              if (items && items.length > 0) { | ||||||
|  |                res.locals.items = items; | ||||||
|  |              } else { | ||||||
|  |                res.locals.items = []; | ||||||
|  |              } | ||||||
|  |              res.locals.processed = true; | ||||||
|  |              next(); | ||||||
|  |            }); | ||||||
|  |          }) | ||||||
|  | 
 | ||||||
|          .post(apiAuthenticationMiddleware, checkMT, (req, res, next) => { |          .post(apiAuthenticationMiddleware, checkMT, (req, res, next) => { | ||||||
|            const campaign = new CampaignModel(req.body); |            const campaign = new CampaignModel(req.body); | ||||||
|            // timestamp and default are set automatically by Mongoose Schema Validation
 |            // timestamp and default are set automatically by Mongoose Schema Validation
 | ||||||
|  | @ -45,7 +65,7 @@ campaigns.route('/') | ||||||
| 
 | 
 | ||||||
| campaigns.route('/:id') | campaigns.route('/:id') | ||||||
|          .get(idValidator, (req, res, next) => { |          .get(idValidator, (req, res, next) => { | ||||||
|             return genericGetById(req, res, next, CampaignModel); |            return genericGetById(req, res, next, CampaignModel); | ||||||
|          }) |          }) | ||||||
| 
 | 
 | ||||||
|          .patch(apiAuthenticationMiddleware, checkMT, (req, res, next) => { |          .patch(apiAuthenticationMiddleware, checkMT, (req, res, next) => { | ||||||
|  |  | ||||||
|  | @ -29,40 +29,59 @@ users.get('/', offsetlimitMiddleware); | ||||||
| // routes **********************
 | // routes **********************
 | ||||||
| users.route('/') | users.route('/') | ||||||
|      .get((req, res, next) => { |      .get((req, res, next) => { | ||||||
|  |        const finishFiltersAndExecute = () => { | ||||||
|  |          // squad / fraction filter setup
 | ||||||
|  |          if (req.query.fractFilter && req.query.fractFilter !== 'UNASSIGNED' && !req.query.squadId) { | ||||||
|  |            SquadModel.find({'fraction': req.query.fractFilter}, {_id: 1}, (err, squads) => { | ||||||
|  |              dbFilter['squadId'] = {$in: squads.map((squad) => squad.id)}; | ||||||
|  |              userQuery(); | ||||||
|  |            }); | ||||||
|  |          } else { | ||||||
|  |            if (req.query.fractFilter === 'UNASSIGNED') { | ||||||
|  |              dbFilter['squadId'] = {$eq: null}; | ||||||
|  |            } | ||||||
|  |            userQuery(); | ||||||
|  |          } | ||||||
|  |        }; | ||||||
|  | 
 | ||||||
|        const userQuery = () => { |        const userQuery = () => { | ||||||
|          UserModel.find(dbFilter, res.locals.filter, res.locals.limitskip) |          UserModel.find(dbFilter, res.locals.filter, res.locals.limitskip) | ||||||
|                   .populate('squadId') |                   .populate('squadId') | ||||||
|                   .collation({locale: 'en', strength: 2}) // case insensitive order
 |                   .collation({locale: 'en', strength: 2}) // case insensitive order
 | ||||||
|                   .sort('username').exec((err, users) => { |                   .sort('username') | ||||||
|            if (err) return next(err); |                   .exec((err, users) => { | ||||||
|            if (users.length === 0) { |                     if (err) return next(err); | ||||||
|              res.locals.items = users; |                     if (users.length === 0) { | ||||||
|              res.locals.processed = true; |                       res.locals.items = users; | ||||||
|              return next(); |                       res.locals.processed = true; | ||||||
|            } |                       return next(); | ||||||
|            UserModel.count(dbFilter, (err, totalCount) => { |                     } | ||||||
|              res.set('x-total-count', totalCount); | 
 | ||||||
|              res.locals.items = users; |                     UserModel.count(dbFilter, (err, totalCount) => { | ||||||
|              res.locals.processed = true; |                       res.set('x-total-count', totalCount); | ||||||
|              return next(); |                       res.locals.items = users; | ||||||
|            }); |                       res.locals.processed = true; | ||||||
|          }); |                       return next(); | ||||||
|  |                     }); | ||||||
|  |                   }); | ||||||
|        }; |        }; | ||||||
| 
 | 
 | ||||||
|        if (!req.query.q) req.query.q = ''; |        const nameQuery = (!req.query.q) ? '' : req.query.q; | ||||||
|        const dbFilter = {username: {'$regex': req.query.q, '$options': 'i'}}; | 
 | ||||||
|  |        const dbFilter = {username: {'$regex': nameQuery, '$options': 'i'}}; | ||||||
|  | 
 | ||||||
|        if (req.query.squadId) dbFilter['squadId'] = {'$eq': req.query.squadId}; |        if (req.query.squadId) dbFilter['squadId'] = {'$eq': req.query.squadId}; | ||||||
|        // squad / fraction filter setup
 | 
 | ||||||
|        if (req.query.fractFilter && req.query.fractFilter !== 'UNASSIGNED' && !req.query.squadId) { |        // decoration filter
 | ||||||
|          SquadModel.find({'fraction': req.query.fractFilter}, {_id: 1}, (err, squads) => { |        const queryDecoId = req.query.decorationId; | ||||||
|            dbFilter['squadId'] = {$in: squads.map((squad) => squad.id)}; |        if (queryDecoId) { | ||||||
|            userQuery(); |          AwardingModel.find({decorationId: queryDecoId}, (err, awards) => { | ||||||
|  |            const userIds = [...new Set(awards.map((award) => award.userId))]; | ||||||
|  |            dbFilter._id = {'$in': userIds}; | ||||||
|  |            finishFiltersAndExecute(); | ||||||
|          }); |          }); | ||||||
|        } else { |        } else { | ||||||
|          if (req.query.fractFilter === 'UNASSIGNED') { |          finishFiltersAndExecute(); | ||||||
|            dbFilter['squadId'] = {$eq: null}; |  | ||||||
|          } |  | ||||||
|          userQuery(); |  | ||||||
|        } |        } | ||||||
|      }) |      }) | ||||||
| 
 | 
 | ||||||
|  | @ -148,6 +167,7 @@ users.route('/:id') | ||||||
|              res.locals.items = item; |              res.locals.items = item; | ||||||
|            } else { |            } else { | ||||||
|              err.status = codes.wrongrequest; |              err.status = codes.wrongrequest; | ||||||
|  |              console.log(err); | ||||||
|              err.message += ' in fields: ' + Object.getOwnPropertyNames(err.errors); |              err.message += ' in fields: ' + Object.getOwnPropertyNames(err.errors); | ||||||
|            } |            } | ||||||
| 
 | 
 | ||||||
|  | @ -195,7 +215,6 @@ users.route('/:id') | ||||||
|        routerHandling.httpMethodNotAllowed |        routerHandling.httpMethodNotAllowed | ||||||
|      ); |      ); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| // this middleware function can be used, if you like or remove it
 | // this middleware function can be used, if you like or remove it
 | ||||||
| // it looks for object(s) in res.locals.items and if they exist, they are send to the client as json
 | // it looks for object(s) in res.locals.items and if they exist, they are send to the client as json
 | ||||||
| users.use(routerHandling.emptyResponse); | users.use(routerHandling.emptyResponse); | ||||||
|  |  | ||||||
|  | @ -1,9 +1,10 @@ | ||||||
| <code_scheme name="OPT-CC copy" version="173"> | <code_scheme name="OPT-CC" version="173"> | ||||||
|   <option name="FORMATTER_TAGS_ENABLED" value="true" /> |   <option name="FORMATTER_TAGS_ENABLED" value="true" /> | ||||||
|   <JSCodeStyleSettings> |   <JSCodeStyleSettings> | ||||||
|     <option name="USE_CHAINED_CALLS_GROUP_INDENTS" value="true" /> |     <option name="USE_CHAINED_CALLS_GROUP_INDENTS" value="true" /> | ||||||
|   </JSCodeStyleSettings> |   </JSCodeStyleSettings> | ||||||
|   <TypeScriptCodeStyleSettings> |   <TypeScriptCodeStyleSettings> | ||||||
|  |     <option name="USE_DOUBLE_QUOTES" value="false" /> | ||||||
|     <option name="USE_CHAINED_CALLS_GROUP_INDENTS" value="true" /> |     <option name="USE_CHAINED_CALLS_GROUP_INDENTS" value="true" /> | ||||||
|   </TypeScriptCodeStyleSettings> |   </TypeScriptCodeStyleSettings> | ||||||
|   <codeStyleSettings language="JavaScript"> |   <codeStyleSettings language="JavaScript"> | ||||||
|  |  | ||||||
|  | @ -1,32 +1,29 @@ | ||||||
| { | { | ||||||
|   "name": "opt-cc", |   "name": "opt-cc", | ||||||
|   "version": "1.7.2", |   "version": "1.8.0", | ||||||
|   "lockfileVersion": 1, |   "lockfileVersion": 1, | ||||||
|   "requires": true, |   "requires": true, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "ajv": { |     "ajv": { | ||||||
|       "version": "5.3.0", |       "version": "5.5.2", | ||||||
|       "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.3.0.tgz", |       "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", | ||||||
|       "integrity": "sha1-RBT/dKUIecII7l/cgm4ywwNUnto=", |       "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "co": "4.6.0", |         "co": "4.6.0", | ||||||
|         "fast-deep-equal": "1.0.0", |         "fast-deep-equal": "1.1.0", | ||||||
|         "fast-json-stable-stringify": "2.0.0", |         "fast-json-stable-stringify": "2.0.0", | ||||||
|         "json-schema-traverse": "0.3.1" |         "json-schema-traverse": "0.3.1" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "ansi-regex": { |  | ||||||
|       "version": "0.2.1", |  | ||||||
|       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", |  | ||||||
|       "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", |  | ||||||
|       "dev": true |  | ||||||
|     }, |  | ||||||
|     "ansi-styles": { |     "ansi-styles": { | ||||||
|       "version": "1.1.0", |       "version": "3.2.1", | ||||||
|       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", |       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", | ||||||
|       "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", |       "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", | ||||||
|       "dev": true |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "color-convert": "1.9.2" | ||||||
|  |       } | ||||||
|     }, |     }, | ||||||
|     "asn1": { |     "asn1": { | ||||||
|       "version": "0.2.3", |       "version": "0.2.3", | ||||||
|  | @ -53,29 +50,26 @@ | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "aws4": { |     "aws4": { | ||||||
|       "version": "1.6.0", |       "version": "1.7.0", | ||||||
|       "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", |       "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", | ||||||
|       "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", |       "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "bcrypt-pbkdf": { |     "bcrypt-pbkdf": { | ||||||
|       "version": "1.0.1", |       "version": "1.0.2", | ||||||
|       "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", |       "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", | ||||||
|       "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", |       "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "optional": true, |       "optional": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "tweetnacl": "0.14.5" |         "tweetnacl": "0.14.5" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "boom": { |     "builtin-modules": { | ||||||
|       "version": "4.3.1", |       "version": "1.1.1", | ||||||
|       "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", |       "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", | ||||||
|       "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", |       "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", | ||||||
|       "dev": true, |       "dev": true | ||||||
|       "requires": { |  | ||||||
|         "hoek": "4.2.0" |  | ||||||
|       } |  | ||||||
|     }, |     }, | ||||||
|     "caseless": { |     "caseless": { | ||||||
|       "version": "0.12.0", |       "version": "0.12.0", | ||||||
|  | @ -84,23 +78,24 @@ | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "chalk": { |     "chalk": { | ||||||
|       "version": "0.5.1", |       "version": "2.4.1", | ||||||
|       "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", |       "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", | ||||||
|       "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", |       "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "ansi-styles": "1.1.0", |         "ansi-styles": "3.2.1", | ||||||
|         "escape-string-regexp": "1.0.5", |         "escape-string-regexp": "1.0.5", | ||||||
|         "has-ansi": "0.1.0", |         "supports-color": "5.4.0" | ||||||
|         "strip-ansi": "0.3.0", |  | ||||||
|         "supports-color": "0.2.0" |  | ||||||
|       }, |       }, | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "supports-color": { |         "supports-color": { | ||||||
|           "version": "0.2.0", |           "version": "5.4.0", | ||||||
|           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", |           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", | ||||||
|           "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", |           "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", | ||||||
|           "dev": true |           "dev": true, | ||||||
|  |           "requires": { | ||||||
|  |             "has-flag": "3.0.0" | ||||||
|  |           } | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  | @ -110,10 +105,25 @@ | ||||||
|       "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", |       "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|  |     "color-convert": { | ||||||
|  |       "version": "1.9.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", | ||||||
|  |       "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "color-name": "1.1.1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "color-name": { | ||||||
|  |       "version": "1.1.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", | ||||||
|  |       "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=", | ||||||
|  |       "dev": true | ||||||
|  |     }, | ||||||
|     "combined-stream": { |     "combined-stream": { | ||||||
|       "version": "1.0.5", |       "version": "1.0.6", | ||||||
|       "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", |       "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", | ||||||
|       "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", |       "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "delayed-stream": "1.0.0" |         "delayed-stream": "1.0.0" | ||||||
|  | @ -126,15 +136,16 @@ | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "concurrently": { |     "concurrently": { | ||||||
|       "version": "3.5.0", |       "version": "3.6.0", | ||||||
|       "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-3.5.0.tgz", |       "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-3.6.0.tgz", | ||||||
|       "integrity": "sha1-jPG3cHppFqeKT/W3e7BN7FSzebI=", |       "integrity": "sha512-6XiIYtYzmGEccNZFkih5JOH92jLA4ulZArAYy5j1uDSdrPLB3KzdE8GW7t2fHPcg9ry2+5LP9IEYzXzxw9lFdA==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "chalk": "0.5.1", |         "chalk": "2.4.1", | ||||||
|         "commander": "2.6.0", |         "commander": "2.6.0", | ||||||
|         "date-fns": "1.29.0", |         "date-fns": "1.29.0", | ||||||
|         "lodash": "4.17.4", |         "lodash": "4.17.10", | ||||||
|  |         "read-pkg": "3.0.0", | ||||||
|         "rx": "2.3.24", |         "rx": "2.3.24", | ||||||
|         "spawn-command": "0.0.2-1", |         "spawn-command": "0.0.2-1", | ||||||
|         "supports-color": "3.2.3", |         "supports-color": "3.2.3", | ||||||
|  | @ -142,9 +153,9 @@ | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "core-js": { |     "core-js": { | ||||||
|       "version": "2.5.1", |       "version": "2.5.7", | ||||||
|       "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", |       "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", | ||||||
|       "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=", |       "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "core-util-is": { |     "core-util-is": { | ||||||
|  | @ -153,26 +164,6 @@ | ||||||
|       "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", |       "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "cryptiles": { |  | ||||||
|       "version": "3.1.2", |  | ||||||
|       "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", |  | ||||||
|       "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", |  | ||||||
|       "dev": true, |  | ||||||
|       "requires": { |  | ||||||
|         "boom": "5.2.0" |  | ||||||
|       }, |  | ||||||
|       "dependencies": { |  | ||||||
|         "boom": { |  | ||||||
|           "version": "5.2.0", |  | ||||||
|           "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", |  | ||||||
|           "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", |  | ||||||
|           "dev": true, |  | ||||||
|           "requires": { |  | ||||||
|             "hoek": "4.2.0" |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "dashdash": { |     "dashdash": { | ||||||
|       "version": "1.14.1", |       "version": "1.14.1", | ||||||
|       "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", |       "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", | ||||||
|  | @ -204,6 +195,15 @@ | ||||||
|         "jsbn": "0.1.1" |         "jsbn": "0.1.1" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "error-ex": { | ||||||
|  |       "version": "1.3.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", | ||||||
|  |       "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "is-arrayish": "0.2.1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "escape-string-regexp": { |     "escape-string-regexp": { | ||||||
|       "version": "1.0.5", |       "version": "1.0.5", | ||||||
|       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", |       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", | ||||||
|  | @ -223,9 +223,9 @@ | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "fast-deep-equal": { |     "fast-deep-equal": { | ||||||
|       "version": "1.0.0", |       "version": "1.1.0", | ||||||
|       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", |       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", | ||||||
|       "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", |       "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "fast-json-stable-stringify": { |     "fast-json-stable-stringify": { | ||||||
|  | @ -241,14 +241,14 @@ | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "form-data": { |     "form-data": { | ||||||
|       "version": "2.3.1", |       "version": "2.3.2", | ||||||
|       "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", |       "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", | ||||||
|       "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", |       "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "asynckit": "0.4.0", |         "asynckit": "0.4.0", | ||||||
|         "combined-stream": "1.0.5", |         "combined-stream": "1.0.6", | ||||||
|         "mime-types": "2.1.17" |         "mime-types": "2.1.18" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "getpass": { |     "getpass": { | ||||||
|  | @ -260,6 +260,12 @@ | ||||||
|         "assert-plus": "1.0.0" |         "assert-plus": "1.0.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "graceful-fs": { | ||||||
|  |       "version": "4.1.11", | ||||||
|  |       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", | ||||||
|  |       "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", | ||||||
|  |       "dev": true | ||||||
|  |     }, | ||||||
|     "har-schema": { |     "har-schema": { | ||||||
|       "version": "2.0.0", |       "version": "2.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", |       "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", | ||||||
|  | @ -272,41 +278,26 @@ | ||||||
|       "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", |       "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "ajv": "5.3.0", |         "ajv": "5.5.2", | ||||||
|         "har-schema": "2.0.0" |         "har-schema": "2.0.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "has-ansi": { |  | ||||||
|       "version": "0.1.0", |  | ||||||
|       "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", |  | ||||||
|       "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", |  | ||||||
|       "dev": true, |  | ||||||
|       "requires": { |  | ||||||
|         "ansi-regex": "0.2.1" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "has-flag": { |     "has-flag": { | ||||||
|       "version": "1.0.0", |       "version": "3.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", |       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", | ||||||
|       "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", |       "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "hawk": { |  | ||||||
|       "version": "6.0.2", |  | ||||||
|       "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", |  | ||||||
|       "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", |  | ||||||
|       "dev": true, |  | ||||||
|       "requires": { |  | ||||||
|         "boom": "4.3.1", |  | ||||||
|         "cryptiles": "3.1.2", |  | ||||||
|         "hoek": "4.2.0", |  | ||||||
|         "sntp": "2.1.0" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "hoek": { |     "hoek": { | ||||||
|       "version": "4.2.0", |       "version": "4.2.1", | ||||||
|       "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", |       "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", | ||||||
|       "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==", |       "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", | ||||||
|  |       "dev": true | ||||||
|  |     }, | ||||||
|  |     "hosted-git-info": { | ||||||
|  |       "version": "2.6.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.1.tgz", | ||||||
|  |       "integrity": "sha512-Ba4+0M4YvIDUUsprMjhVTU1yN9F2/LJSAl69ZpzaLT4l4j5mwTS6jqqW9Ojvj6lKz/veqPzpJBqGbXspOb533A==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "http-signature": { |     "http-signature": { | ||||||
|  | @ -317,7 +308,22 @@ | ||||||
|       "requires": { |       "requires": { | ||||||
|         "assert-plus": "1.0.0", |         "assert-plus": "1.0.0", | ||||||
|         "jsprim": "1.4.1", |         "jsprim": "1.4.1", | ||||||
|         "sshpk": "1.13.1" |         "sshpk": "1.14.2" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "is-arrayish": { | ||||||
|  |       "version": "0.2.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", | ||||||
|  |       "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", | ||||||
|  |       "dev": true | ||||||
|  |     }, | ||||||
|  |     "is-builtin-module": { | ||||||
|  |       "version": "1.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", | ||||||
|  |       "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "builtin-modules": "1.1.1" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "is-typedarray": { |     "is-typedarray": { | ||||||
|  | @ -350,10 +356,10 @@ | ||||||
|       "integrity": "sha1-M4WseQGSEwy+Iw6ALsAskhW7/to=", |       "integrity": "sha1-M4WseQGSEwy+Iw6ALsAskhW7/to=", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "hoek": "4.2.0", |         "hoek": "4.2.1", | ||||||
|         "isemail": "2.2.1", |         "isemail": "2.2.1", | ||||||
|         "items": "2.1.1", |         "items": "2.1.1", | ||||||
|         "moment": "2.19.1", |         "moment": "2.22.2", | ||||||
|         "topo": "2.0.2" |         "topo": "2.0.2" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  | @ -364,6 +370,12 @@ | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "optional": true |       "optional": true | ||||||
|     }, |     }, | ||||||
|  |     "json-parse-better-errors": { | ||||||
|  |       "version": "1.0.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", | ||||||
|  |       "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", | ||||||
|  |       "dev": true | ||||||
|  |     }, | ||||||
|     "json-schema": { |     "json-schema": { | ||||||
|       "version": "0.2.3", |       "version": "0.2.3", | ||||||
|       "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", |       "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", | ||||||
|  | @ -394,25 +406,37 @@ | ||||||
|         "verror": "1.10.0" |         "verror": "1.10.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "load-json-file": { | ||||||
|  |       "version": "4.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", | ||||||
|  |       "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "graceful-fs": "4.1.11", | ||||||
|  |         "parse-json": "4.0.0", | ||||||
|  |         "pify": "3.0.0", | ||||||
|  |         "strip-bom": "3.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "lodash": { |     "lodash": { | ||||||
|       "version": "4.17.4", |       "version": "4.17.10", | ||||||
|       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", |       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", | ||||||
|       "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", |       "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "mime-db": { |     "mime-db": { | ||||||
|       "version": "1.30.0", |       "version": "1.33.0", | ||||||
|       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", |       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", | ||||||
|       "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=", |       "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "mime-types": { |     "mime-types": { | ||||||
|       "version": "2.1.17", |       "version": "2.1.18", | ||||||
|       "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", |       "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", | ||||||
|       "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", |       "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "mime-db": "1.30.0" |         "mime-db": "1.33.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "minimist": { |     "minimist": { | ||||||
|  | @ -422,23 +446,60 @@ | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "moment": { |     "moment": { | ||||||
|       "version": "2.19.1", |       "version": "2.22.2", | ||||||
|       "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.1.tgz", |       "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", | ||||||
|       "integrity": "sha1-VtoaLRy/AdOLfhr8McELz6GSkWc=", |       "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|  |     "normalize-package-data": { | ||||||
|  |       "version": "2.4.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", | ||||||
|  |       "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "hosted-git-info": "2.6.1", | ||||||
|  |         "is-builtin-module": "1.0.0", | ||||||
|  |         "semver": "5.5.0", | ||||||
|  |         "validate-npm-package-license": "3.0.3" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "oauth-sign": { |     "oauth-sign": { | ||||||
|       "version": "0.8.2", |       "version": "0.8.2", | ||||||
|       "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", |       "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", | ||||||
|       "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", |       "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|  |     "parse-json": { | ||||||
|  |       "version": "4.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", | ||||||
|  |       "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "error-ex": "1.3.2", | ||||||
|  |         "json-parse-better-errors": "1.0.2" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "path-type": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", | ||||||
|  |       "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "pify": "3.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "performance-now": { |     "performance-now": { | ||||||
|       "version": "2.1.0", |       "version": "2.1.0", | ||||||
|       "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", |       "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", | ||||||
|       "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", |       "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|  |     "pify": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", | ||||||
|  |       "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", | ||||||
|  |       "dev": true | ||||||
|  |     }, | ||||||
|     "punycode": { |     "punycode": { | ||||||
|       "version": "1.4.1", |       "version": "1.4.1", | ||||||
|       "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", |       "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", | ||||||
|  | @ -446,39 +507,48 @@ | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "qs": { |     "qs": { | ||||||
|       "version": "6.5.1", |       "version": "6.5.2", | ||||||
|       "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", |       "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", | ||||||
|       "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", |       "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|  |     "read-pkg": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", | ||||||
|  |       "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "load-json-file": "4.0.0", | ||||||
|  |         "normalize-package-data": "2.4.0", | ||||||
|  |         "path-type": "3.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "request": { |     "request": { | ||||||
|       "version": "2.83.0", |       "version": "2.87.0", | ||||||
|       "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", |       "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", | ||||||
|       "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", |       "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "aws-sign2": "0.7.0", |         "aws-sign2": "0.7.0", | ||||||
|         "aws4": "1.6.0", |         "aws4": "1.7.0", | ||||||
|         "caseless": "0.12.0", |         "caseless": "0.12.0", | ||||||
|         "combined-stream": "1.0.5", |         "combined-stream": "1.0.6", | ||||||
|         "extend": "3.0.1", |         "extend": "3.0.1", | ||||||
|         "forever-agent": "0.6.1", |         "forever-agent": "0.6.1", | ||||||
|         "form-data": "2.3.1", |         "form-data": "2.3.2", | ||||||
|         "har-validator": "5.0.3", |         "har-validator": "5.0.3", | ||||||
|         "hawk": "6.0.2", |  | ||||||
|         "http-signature": "1.2.0", |         "http-signature": "1.2.0", | ||||||
|         "is-typedarray": "1.0.0", |         "is-typedarray": "1.0.0", | ||||||
|         "isstream": "0.1.2", |         "isstream": "0.1.2", | ||||||
|         "json-stringify-safe": "5.0.1", |         "json-stringify-safe": "5.0.1", | ||||||
|         "mime-types": "2.1.17", |         "mime-types": "2.1.18", | ||||||
|         "oauth-sign": "0.8.2", |         "oauth-sign": "0.8.2", | ||||||
|         "performance-now": "2.1.0", |         "performance-now": "2.1.0", | ||||||
|         "qs": "6.5.1", |         "qs": "6.5.2", | ||||||
|         "safe-buffer": "5.1.1", |         "safe-buffer": "5.1.2", | ||||||
|         "stringstream": "0.0.5", |         "tough-cookie": "2.3.4", | ||||||
|         "tough-cookie": "2.3.3", |  | ||||||
|         "tunnel-agent": "0.6.0", |         "tunnel-agent": "0.6.0", | ||||||
|         "uuid": "3.1.0" |         "uuid": "3.3.2" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "rx": { |     "rx": { | ||||||
|  | @ -488,19 +558,22 @@ | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "safe-buffer": { |     "safe-buffer": { | ||||||
|       "version": "5.1.1", |       "version": "5.1.2", | ||||||
|       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", |       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", | ||||||
|       "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", |       "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "sntp": { |     "safer-buffer": { | ||||||
|       "version": "2.1.0", |       "version": "2.1.2", | ||||||
|       "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", |       "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", | ||||||
|       "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", |       "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", | ||||||
|       "dev": true, |       "dev": true | ||||||
|       "requires": { |     }, | ||||||
|         "hoek": "4.2.0" |     "semver": { | ||||||
|       } |       "version": "5.5.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", | ||||||
|  |       "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", | ||||||
|  |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "spawn-command": { |     "spawn-command": { | ||||||
|       "version": "0.0.2-1", |       "version": "0.0.2-1", | ||||||
|  | @ -508,37 +581,61 @@ | ||||||
|       "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", |       "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|  |     "spdx-correct": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", | ||||||
|  |       "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "spdx-expression-parse": "3.0.0", | ||||||
|  |         "spdx-license-ids": "3.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "spdx-exceptions": { | ||||||
|  |       "version": "2.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", | ||||||
|  |       "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", | ||||||
|  |       "dev": true | ||||||
|  |     }, | ||||||
|  |     "spdx-expression-parse": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", | ||||||
|  |       "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "spdx-exceptions": "2.1.0", | ||||||
|  |         "spdx-license-ids": "3.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "spdx-license-ids": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", | ||||||
|  |       "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", | ||||||
|  |       "dev": true | ||||||
|  |     }, | ||||||
|     "sshpk": { |     "sshpk": { | ||||||
|       "version": "1.13.1", |       "version": "1.14.2", | ||||||
|       "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", |       "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", | ||||||
|       "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", |       "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "asn1": "0.2.3", |         "asn1": "0.2.3", | ||||||
|         "assert-plus": "1.0.0", |         "assert-plus": "1.0.0", | ||||||
|         "bcrypt-pbkdf": "1.0.1", |         "bcrypt-pbkdf": "1.0.2", | ||||||
|         "dashdash": "1.14.1", |         "dashdash": "1.14.1", | ||||||
|         "ecc-jsbn": "0.1.1", |         "ecc-jsbn": "0.1.1", | ||||||
|         "getpass": "0.1.7", |         "getpass": "0.1.7", | ||||||
|         "jsbn": "0.1.1", |         "jsbn": "0.1.1", | ||||||
|  |         "safer-buffer": "2.1.2", | ||||||
|         "tweetnacl": "0.14.5" |         "tweetnacl": "0.14.5" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "stringstream": { |     "strip-bom": { | ||||||
|       "version": "0.0.5", |       "version": "3.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", |       "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", | ||||||
|       "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", |       "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "strip-ansi": { |  | ||||||
|       "version": "0.3.0", |  | ||||||
|       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", |  | ||||||
|       "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", |  | ||||||
|       "dev": true, |  | ||||||
|       "requires": { |  | ||||||
|         "ansi-regex": "0.2.1" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "supports-color": { |     "supports-color": { | ||||||
|       "version": "3.2.3", |       "version": "3.2.3", | ||||||
|       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", |       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", | ||||||
|  | @ -546,6 +643,14 @@ | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "has-flag": "1.0.0" |         "has-flag": "1.0.0" | ||||||
|  |       }, | ||||||
|  |       "dependencies": { | ||||||
|  |         "has-flag": { | ||||||
|  |           "version": "1.0.0", | ||||||
|  |           "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", | ||||||
|  |           "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", | ||||||
|  |           "dev": true | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "topo": { |     "topo": { | ||||||
|  | @ -554,13 +659,13 @@ | ||||||
|       "integrity": "sha1-zVYVdSU5BXwNwEkaYhw7xvvh0YI=", |       "integrity": "sha1-zVYVdSU5BXwNwEkaYhw7xvvh0YI=", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "hoek": "4.2.0" |         "hoek": "4.2.1" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "tough-cookie": { |     "tough-cookie": { | ||||||
|       "version": "2.3.3", |       "version": "2.3.4", | ||||||
|       "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", |       "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", | ||||||
|       "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", |       "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "punycode": "1.4.1" |         "punycode": "1.4.1" | ||||||
|  | @ -578,7 +683,7 @@ | ||||||
|       "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", |       "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "safe-buffer": "5.1.1" |         "safe-buffer": "5.1.2" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "tweetnacl": { |     "tweetnacl": { | ||||||
|  | @ -589,11 +694,21 @@ | ||||||
|       "optional": true |       "optional": true | ||||||
|     }, |     }, | ||||||
|     "uuid": { |     "uuid": { | ||||||
|       "version": "3.1.0", |       "version": "3.3.2", | ||||||
|       "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", |       "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", | ||||||
|       "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", |       "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|  |     "validate-npm-package-license": { | ||||||
|  |       "version": "3.0.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", | ||||||
|  |       "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "spdx-correct": "3.0.0", | ||||||
|  |         "spdx-expression-parse": "3.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "verror": { |     "verror": { | ||||||
|       "version": "1.10.0", |       "version": "1.10.0", | ||||||
|       "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", |       "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", | ||||||
|  | @ -606,15 +721,15 @@ | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "wait-on": { |     "wait-on": { | ||||||
|       "version": "2.0.2", |       "version": "2.1.0", | ||||||
|       "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-2.0.2.tgz", |       "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-2.1.0.tgz", | ||||||
|       "integrity": "sha1-CoT9BwJMb8Joyw6r5YW+IXqvK6o=", |       "integrity": "sha512-hDwJ674+7dfiiK/cxtYCwPxlnjXDjto/pCz1PF02sXUhqCqCWsgvxZln0699PReWqXXgkxqkF6DDo5Rj9sjNvw==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "core-js": "2.5.1", |         "core-js": "2.5.7", | ||||||
|         "joi": "9.2.0", |         "joi": "9.2.0", | ||||||
|         "minimist": "1.2.0", |         "minimist": "1.2.0", | ||||||
|         "request": "2.83.0", |         "request": "2.87.0", | ||||||
|         "rx": "4.1.0" |         "rx": "4.1.0" | ||||||
|       }, |       }, | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|  |  | ||||||
|  | @ -1,13 +1,14 @@ | ||||||
| { | { | ||||||
|   "name": "opt-cc", |   "name": "opt-cc", | ||||||
|   "version": "1.7.7", |   "version": "1.8.0", | ||||||
|   "author": "Florian Hartwich <hardi@noarch.de>", |   "author": "Florian Hartwich <hardi@noarch.de>", | ||||||
|   "private": true, |   "private": true, | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "start": "npm run deploy-static-prod && npm start --prefix ./api", |     "start": "npm run deploy-static-prod && npm start --prefix ./api", | ||||||
|     "dev": "npm run deploy-static && npm run dev --prefix ./api", |     "dev": "npm run deploy-static && npm run dev --prefix ./api", | ||||||
|     "deploy-static": "npm run build --prefix=static && npm run deploy-static:link-resource && npm run deploy-static:api-docs", |     "pre-deploy-clean": "rm -f ./public/resource", | ||||||
|     "deploy-static:prod": "npm run build:prod --prefix=static && npm run deploy-static:link-resource && npm run deploy-static:api-docs", |     "deploy-static": "npm run pre-deploy-clean && npm run build --prefix=static && npm run deploy-static:link-resource && npm run deploy-static:api-docs", | ||||||
|  |     "deploy-static:prod": "npm run pre-deploy-clean && npm run build:prod --prefix=static && npm run deploy-static:link-resource && npm run deploy-static:api-docs", | ||||||
|     "deploy-static:link-resource": "ln -s ../api/resource/ public/resource", |     "deploy-static:link-resource": "ln -s ../api/resource/ public/resource", | ||||||
|     "deploy-static:api-docs": "npm run api:docs --prefix=api", |     "deploy-static:api-docs": "npm run api:docs --prefix=api", | ||||||
|     "postinstall": "npm install --prefix ./static && npm install --prefix  ./api", |     "postinstall": "npm install --prefix ./static && npm install --prefix  ./api", | ||||||
|  |  | ||||||
|  | @ -1,66 +0,0 @@ | ||||||
| { |  | ||||||
|   "$schema": "./node_modules/@angular/cli/lib/config/schema.json", |  | ||||||
|   "project": { |  | ||||||
|     "name": "optCC" |  | ||||||
|   }, |  | ||||||
|   "apps": [ |  | ||||||
|     { |  | ||||||
|       "root": "src", |  | ||||||
|       "outDir": "../public", |  | ||||||
|       "assets": [ |  | ||||||
|         "assets", |  | ||||||
|         "favicon.ico" |  | ||||||
|       ], |  | ||||||
|       "index": "index.html", |  | ||||||
|       "main": "main.ts", |  | ||||||
|       "polyfills": "polyfills.ts", |  | ||||||
|       "test": "test.ts", |  | ||||||
|       "tsconfig": "tsconfig.app.json", |  | ||||||
|       "testTsconfig": "tsconfig.spec.json", |  | ||||||
|       "prefix": "app", |  | ||||||
|       "styles": [ |  | ||||||
|         "styles.css", |  | ||||||
|         "../node_modules/jquery-ui-bundle/jquery-ui.css", |  | ||||||
|         "../node_modules/bootstrap/dist/css/bootstrap.min.css" |  | ||||||
|       ], |  | ||||||
|       "scripts": [ |  | ||||||
|         "../node_modules/jquery/dist/jquery.js", |  | ||||||
|         "../node_modules/bootstrap/dist/js/bootstrap.min.js" |  | ||||||
|       ], |  | ||||||
|       "environmentSource": "environments/environment.ts", |  | ||||||
|       "environments": { |  | ||||||
|         "dev": "environments/environment.ts", |  | ||||||
|         "prod": "environments/environment.prod.ts", |  | ||||||
|         "e2e": "environments/environment.e2e.ts" |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   ], |  | ||||||
|   "e2e": { |  | ||||||
|     "protractor": { |  | ||||||
|       "config": "./protractor.conf.js" |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   "lint": [ |  | ||||||
|     { |  | ||||||
|       "files": "src/**/*.ts", |  | ||||||
|       "project": "src/tsconfig.app.json" |  | ||||||
|     }, |  | ||||||
|     { |  | ||||||
|       "files": "src/**/*.ts", |  | ||||||
|       "project": "src/tsconfig.spec.json" |  | ||||||
|     }, |  | ||||||
|     { |  | ||||||
|       "files": "src/**/*.ts", |  | ||||||
|       "project": "e2e/tsconfig.e2e.json" |  | ||||||
|     } |  | ||||||
|   ], |  | ||||||
|   "test": { |  | ||||||
|     "karma": { |  | ||||||
|       "config": "./karma.conf.js" |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   "defaults": { |  | ||||||
|     "styleExt": "css", |  | ||||||
|     "component": {} |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  | @ -0,0 +1,149 @@ | ||||||
|  | { | ||||||
|  |   "$schema": "./node_modules/@angular/cli/lib/config/schema.json", | ||||||
|  |   "version": 1, | ||||||
|  |   "newProjectRoot": "projects", | ||||||
|  |   "projects": { | ||||||
|  |     "optCC": { | ||||||
|  |       "root": "", | ||||||
|  |       "sourceRoot": "src", | ||||||
|  |       "projectType": "application", | ||||||
|  |       "architect": { | ||||||
|  |         "build": { | ||||||
|  |           "builder": "@angular-devkit/build-angular:browser", | ||||||
|  |           "options": { | ||||||
|  |             "outputPath": "../public", | ||||||
|  |             "index": "src/index.html", | ||||||
|  |             "main": "src/main.ts", | ||||||
|  |             "tsConfig": "src/tsconfig.app.json", | ||||||
|  |             "polyfills": "src/polyfills.ts", | ||||||
|  |             "assets": [ | ||||||
|  |               "src/assets", | ||||||
|  |               "src/favicon.ico" | ||||||
|  |             ], | ||||||
|  |             "styles": [ | ||||||
|  |               "src/styles.css", | ||||||
|  |               "node_modules/jquery-ui-bundle/jquery-ui.css", | ||||||
|  |               "node_modules/bootstrap/dist/css/bootstrap.min.css" | ||||||
|  |             ], | ||||||
|  |             "scripts": [ | ||||||
|  |               "node_modules/jquery/dist/jquery.js", | ||||||
|  |               "node_modules/bootstrap/dist/js/bootstrap.min.js" | ||||||
|  |             ] | ||||||
|  |           }, | ||||||
|  |           "configurations": { | ||||||
|  |             "production": { | ||||||
|  |               "optimization": true, | ||||||
|  |               "outputHashing": "all", | ||||||
|  |               "sourceMap": false, | ||||||
|  |               "extractCss": true, | ||||||
|  |               "namedChunks": false, | ||||||
|  |               "aot": true, | ||||||
|  |               "extractLicenses": true, | ||||||
|  |               "vendorChunk": false, | ||||||
|  |               "buildOptimizer": true, | ||||||
|  |               "fileReplacements": [ | ||||||
|  |                 { | ||||||
|  |                   "replace": "src/environments/environment.ts", | ||||||
|  |                   "with": "src/environments/environment.prod.ts" | ||||||
|  |                 } | ||||||
|  |               ] | ||||||
|  |             }, | ||||||
|  |             "e2e": { | ||||||
|  |               "fileReplacements": [ | ||||||
|  |                 { | ||||||
|  |                   "replace": "src/environments/environment.ts", | ||||||
|  |                   "with": "src/environments/environment.e2e.ts" | ||||||
|  |                 } | ||||||
|  |               ] | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         "serve": { | ||||||
|  |           "builder": "@angular-devkit/build-angular:dev-server", | ||||||
|  |           "options": { | ||||||
|  |             "browserTarget": "optCC:build" | ||||||
|  |           }, | ||||||
|  |           "configurations": { | ||||||
|  |             "production": { | ||||||
|  |               "browserTarget": "optCC:build:production" | ||||||
|  |             }, | ||||||
|  |             "e2e": { | ||||||
|  |               "browserTarget": "optCC:build:e2e" | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         "extract-i18n": { | ||||||
|  |           "builder": "@angular-devkit/build-angular:extract-i18n", | ||||||
|  |           "options": { | ||||||
|  |             "browserTarget": "optCC:build" | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         "test": { | ||||||
|  |           "builder": "@angular-devkit/build-angular:karma", | ||||||
|  |           "options": { | ||||||
|  |             "main": "src/test.ts", | ||||||
|  |             "karmaConfig": "./karma.conf.js", | ||||||
|  |             "polyfills": "src/polyfills.ts", | ||||||
|  |             "tsConfig": "src/tsconfig.spec.json", | ||||||
|  |             "scripts": [ | ||||||
|  |               "node_modules/jquery/dist/jquery.js", | ||||||
|  |               "node_modules/bootstrap/dist/js/bootstrap.min.js" | ||||||
|  |             ], | ||||||
|  |             "styles": [ | ||||||
|  |               "src/styles.css", | ||||||
|  |               "node_modules/jquery-ui-bundle/jquery-ui.css", | ||||||
|  |               "node_modules/bootstrap/dist/css/bootstrap.min.css" | ||||||
|  |             ], | ||||||
|  |             "assets": [ | ||||||
|  |               "src/assets", | ||||||
|  |               "src/favicon.ico" | ||||||
|  |             ] | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         "lint": { | ||||||
|  |           "builder": "@angular-devkit/build-angular:tslint", | ||||||
|  |           "options": { | ||||||
|  |             "tsConfig": [ | ||||||
|  |               "src/tsconfig.app.json", | ||||||
|  |               "src/tsconfig.spec.json" | ||||||
|  |             ], | ||||||
|  |             "exclude": [] | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "optCC-e2e": { | ||||||
|  |       "root": "", | ||||||
|  |       "sourceRoot": "e2e", | ||||||
|  |       "projectType": "application", | ||||||
|  |       "architect": { | ||||||
|  |         "e2e": { | ||||||
|  |           "builder": "@angular-devkit/build-angular:protractor", | ||||||
|  |           "options": { | ||||||
|  |             "protractorConfig": "./protractor.conf.js", | ||||||
|  |             "devServerTarget": "optCC:serve" | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         "lint": { | ||||||
|  |           "builder": "@angular-devkit/build-angular:tslint", | ||||||
|  |           "options": { | ||||||
|  |             "tsConfig": [ | ||||||
|  |               "e2e/tsconfig.e2e.json" | ||||||
|  |             ], | ||||||
|  |             "exclude": [] | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   "defaultProject": "optCC", | ||||||
|  |   "schematics": { | ||||||
|  |     "@schematics/angular:component": { | ||||||
|  |       "prefix": "app", | ||||||
|  |       "styleext": "css" | ||||||
|  |     }, | ||||||
|  |     "@schematics/angular:directive": { | ||||||
|  |       "prefix": "app" | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -4,33 +4,30 @@ | ||||||
| module.exports = function (config) { | module.exports = function (config) { | ||||||
|   config.set({ |   config.set({ | ||||||
|     basePath: '', |     basePath: '', | ||||||
|     frameworks: ['jasmine', '@angular/cli'], |     frameworks: ['jasmine', '@angular-devkit/build-angular'], | ||||||
|     plugins: [ |     plugins: [ | ||||||
|       require('karma-jasmine'), |       require('karma-jasmine'), | ||||||
|       require('karma-chrome-launcher'), |       require('karma-chrome-launcher'), | ||||||
|       require('karma-remap-istanbul'), |       require('karma-remap-istanbul'), | ||||||
|       require('karma-spec-reporter'), |       require('karma-spec-reporter'), | ||||||
|       require('@angular/cli/plugins/karma') |       require('@angular-devkit/build-angular/plugins/karma') | ||||||
|     ], |     ], | ||||||
|     files: [ |     files: [ | ||||||
|       {pattern: './src/test.ts', watched: false} |       {pattern: './src/test.ts', watched: false} | ||||||
|     ], |     ], | ||||||
|     preprocessors: { |     preprocessors: { | ||||||
|       './src/test.ts': ['@angular/cli'] |        | ||||||
|     }, |     }, | ||||||
|     mime: { |     mime: { | ||||||
|       'text/x-typescript': ['ts', 'tsx'] |       'text/x-typescript': ['ts', 'tsx'] | ||||||
|     }, |     }, | ||||||
|     remapIstanbulReporter: { |     remapIstanbulReporter: { | ||||||
|       reports: { |       dir: require('path').join(__dirname, 'coverage'), reports: { | ||||||
|         html: 'coverage', |         html: 'coverage', | ||||||
|         lcovonly: './coverage/coverage.lcov' |         lcovonly: './coverage/coverage.lcov' | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     angularCli: { |      | ||||||
|       config: './.angular-cli.json', |  | ||||||
|       environment: 'dev' |  | ||||||
|     }, |  | ||||||
|     reporters: config.angularCli && config.angularCli.codeCoverage |     reporters: config.angularCli && config.angularCli.codeCoverage | ||||||
|       ? ['spec', 'karma-remap-istanbul'] |       ? ['spec', 'karma-remap-istanbul'] | ||||||
|       : ['spec'], |       : ['spec'], | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -15,45 +15,48 @@ | ||||||
|     "e2e": "ng e2e --serve=false" |     "e2e": "ng e2e --serve=false" | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@angular/animations": "^5.0.0", |     "@angular/animations": "^6.0.7", | ||||||
|     "@angular/cli": "^1.5.0", |     "@angular/cdk": "^6.0.7", | ||||||
|     "@angular/common": "^5.0.0", |     "@angular/cli": "^6.0.7", | ||||||
|     "@angular/compiler": "^5.0.0", |     "@angular/common": "^6.0.7", | ||||||
|     "@angular/compiler-cli": "^5.0.0", |     "@angular/compiler": "^6.0.7", | ||||||
|     "@angular/core": "^5.0.0", |     "@angular/compiler-cli": "^6.0.7", | ||||||
|     "@angular/forms": "^5.0.0", |     "@angular/core": "^6.0.7", | ||||||
|     "@angular/http": "^5.0.0", |     "@angular/forms": "^6.0.7", | ||||||
|     "@angular/platform-browser": "^5.0.0", |     "@angular/http": "^6.0.7", | ||||||
|     "@angular/platform-browser-dynamic": "^5.0.0", |     "@angular/material": "^6.0.7", | ||||||
|     "@angular/router": "^5.0.0", |     "@angular/platform-browser": "^6.0.7", | ||||||
|     "@swimlane/ngx-charts": "^7.1.0", |     "@angular/platform-browser-dynamic": "^6.0.7", | ||||||
|     "@swimlane/ngx-datatable": "^11.0.4", |     "@angular/router": "^6.0.7", | ||||||
|  |     "@swimlane/ngx-charts": "^8.1.0", | ||||||
|     "bootstrap": "^3.3.7", |     "bootstrap": "^3.3.7", | ||||||
|     "d3": "^4.11.0", |     "d3": "^4.11.0", | ||||||
|     "file-saver": "^1.3.8", |     "file-saver": "^1.3.8", | ||||||
|     "jquery": "^3.1.0", |     "jquery": "^3.1.0", | ||||||
|     "jquery-ui": "^1.12.0", |     "jquery-ui": "^1.12.0", | ||||||
|     "jquery-ui-bundle": "^1.11.4", |     "jquery-ui-bundle": "^1.11.4", | ||||||
|     "ngx-bootstrap": "^2.0.0-beta.8", |     "ngx-clipboard": "^11.1.1", | ||||||
|     "ngx-clipboard": "^8.1.0", |     "ngx-cookie-service": "^1.0.10", | ||||||
|     "ngx-cookie-service": "^1.0.9", |  | ||||||
|     "ngx-infinite-scroll": "^0.5.2", |     "ngx-infinite-scroll": "^0.5.2", | ||||||
|  |     "rxjs-compat": "^6.2.1", | ||||||
|     "ts-helpers": "^1.1.2", |     "ts-helpers": "^1.1.2", | ||||||
|     "typescript": "^2.6.1" |     "zone.js": "^0.8.26" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@types/jasmine": "2.5.38", |     "@types/jasmine": "2.5.38", | ||||||
|     "@types/node": "^6.0.89", |     "@types/node": "^6.0.89", | ||||||
|     "codelyzer": "~2.0.0-beta.1", |     "codelyzer": "^4.4.2", | ||||||
|     "jasmine-core": "^2.5.2", |     "jasmine-core": "^2.5.2", | ||||||
|     "jasmine-spec-reporter": "^3.2.0", |     "jasmine-spec-reporter": "^3.2.0", | ||||||
|     "karma": "^1.5.0", |     "karma": "^2.0.4", | ||||||
|     "karma-chrome-launcher": "^2.0.0", |     "karma-chrome-launcher": "^2.0.0", | ||||||
|     "karma-jasmine": "^1.1.0", |     "karma-jasmine": "^1.1.0", | ||||||
|     "karma-spec-reporter": "0.0.30", |     "karma-spec-reporter": "0.0.30", | ||||||
|     "protractor": "~5.1.1", |     "protractor": "^5.3.2", | ||||||
|     "protractor-jasmine2-screenshot-reporter": "^0.3.2", |     "protractor-jasmine2-screenshot-reporter": "^0.3.2", | ||||||
|     "ts-node": "1.2.1", |     "ts-node": "1.2.1", | ||||||
|     "tslint": "^4.3.0" |     "tslint": "^5.10.0", | ||||||
|  |     "@angular-devkit/build-angular": "~0.6.8", | ||||||
|  |     "typescript": "^2.7.2" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| .overview { | .overview { | ||||||
|   padding: 80px 0 0 10% !important; |   padding-bottom: 50px!important; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .trash { | .trash { | ||||||
|  |  | ||||||
|  | @ -2,11 +2,6 @@ | ||||||
| 
 | 
 | ||||||
|   <h2>Admin Panel</h2> |   <h2>Admin Panel</h2> | ||||||
| 
 | 
 | ||||||
|   <span *ngIf="showSuccessLabel" |  | ||||||
|         class="absolute-label label label-success label-small"> |  | ||||||
|         Erfolgreich gespeichert |  | ||||||
|   </span> |  | ||||||
| 
 |  | ||||||
|   <div class="pull-left" style="margin-top:20px;"> |   <div class="pull-left" style="margin-top:20px;"> | ||||||
|     <div class="table-container" style="width: 75%; min-width: 500px"> |     <div class="table-container" style="width: 75%; min-width: 500px"> | ||||||
|       <table class="table table-hover"> |       <table class="table table-hover"> | ||||||
|  | @ -59,7 +54,7 @@ | ||||||
|             </select> |             </select> | ||||||
|           </td> |           </td> | ||||||
|           <td class="text-center"> |           <td class="text-center"> | ||||||
|             <span class="glyphicon glyphicon-trash trash" title="Löschen" (click)="deleteUser(user)"></span> |             <span class="glyphicon glyphicon-trash trash" matTooltip="Löschen" (click)="deleteUser(user)"></span> | ||||||
|           </td> |           </td> | ||||||
|         </tr> |         </tr> | ||||||
|         </tbody> |         </tbody> | ||||||
|  |  | ||||||
|  | @ -4,6 +4,8 @@ import {Observable} from 'rxjs/Observable'; | ||||||
| import {AppUserService} from '../services/app-user-service/app-user.service'; | import {AppUserService} from '../services/app-user-service/app-user.service'; | ||||||
| import {SquadService} from '../services/army-management/squad.service'; | import {SquadService} from '../services/army-management/squad.service'; | ||||||
| import {Fraction} from '../utils/fraction.enum'; | import {Fraction} from '../utils/fraction.enum'; | ||||||
|  | import {SnackBarService} from '../services/user-interface/snack-bar/snack-bar.service'; | ||||||
|  | import {Message} from '../i18n/de.messages'; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @Component({ | @Component({ | ||||||
|  | @ -17,12 +19,11 @@ export class AdminComponent implements OnInit { | ||||||
| 
 | 
 | ||||||
|   squads: Squad[] = []; |   squads: Squad[] = []; | ||||||
| 
 | 
 | ||||||
|   showSuccessLabel = false; |  | ||||||
| 
 |  | ||||||
|   readonly fraction = Fraction; |   readonly fraction = Fraction; | ||||||
| 
 | 
 | ||||||
|   constructor(private appUserService: AppUserService, |   constructor(private appUserService: AppUserService, | ||||||
|               private squadService: SquadService) { |               private squadService: SquadService, | ||||||
|  |               private snackBarService: SnackBarService) { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   ngOnInit() { |   ngOnInit() { | ||||||
|  | @ -46,10 +47,7 @@ export class AdminComponent implements OnInit { | ||||||
| 
 | 
 | ||||||
|     this.appUserService.updateUser(updateObject) |     this.appUserService.updateUser(updateObject) | ||||||
|         .subscribe(resUser => { |         .subscribe(resUser => { | ||||||
|           this.showSuccessLabel = true; |           this.snackBarService.showSuccess(Message.SUCCESS_SAVE); | ||||||
|           setTimeout(() => { |  | ||||||
|             this.showSuccessLabel = false; |  | ||||||
|           }, 2000); |  | ||||||
|         }); |         }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -13,16 +13,6 @@ li { | ||||||
|   padding-right: 15px; |   padding-right: 15px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .right { |  | ||||||
|   float: right; |  | ||||||
|   width: 300px; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .left { |  | ||||||
|   float: left; |  | ||||||
|   width: calc(100% - 400px); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .scrollable-menu { | .scrollable-menu { | ||||||
|   height: auto; |   height: auto; | ||||||
|   max-height: 200px; |   max-height: 200px; | ||||||
|  | @ -30,32 +20,23 @@ li { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .version-label { | .version-label { | ||||||
|   display: block; |   position: absolute; | ||||||
|   position: fixed; |   top: 27px; | ||||||
|   top: 32px; |   left: 115px; | ||||||
|   left: 106px; |  | ||||||
|   font-size: 12px; |   font-size: 12px; | ||||||
|   color: #7e7d64; |   color: #bebebe; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #scrollTopBtn { | #scrollTopBtn { | ||||||
|   position: fixed; /* Fixed/sticky position */ |   position: fixed; | ||||||
|   bottom: 20px; |   bottom: 20px; | ||||||
|   right: 30px; |   right: 30px; | ||||||
|   z-index: 99; |   z-index: 99; | ||||||
|   border: none; |   background: rgba(16, 16, 16, 0.8); | ||||||
|   outline: none; |  | ||||||
|   background-color: #101010; |  | ||||||
|   color: white; |  | ||||||
|   font-weight: bolder; |  | ||||||
|   cursor: pointer; |  | ||||||
|   padding: 7px 25px 10px 25px; |  | ||||||
|   border-radius: 20px; |  | ||||||
|   font-size: 22px; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #scrollTopBtn:hover { | #scrollTopBtn:hover { | ||||||
|   background-color: rgba(25, 142, 25, 1); |   background: rgba(16, 16, 16); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .unprocessed { | .unprocessed { | ||||||
|  | @ -70,10 +51,6 @@ li { | ||||||
|   background-color: orange; |   background-color: orange; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| unprocessed-child:hover { |  | ||||||
|   background-color: orange; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* Safari 4.0 - 8.0 */ | /* Safari 4.0 - 8.0 */ | ||||||
| @-webkit-keyframes color-blink { | @-webkit-keyframes color-blink { | ||||||
|   from { |   from { | ||||||
|  |  | ||||||
|  | @ -3,11 +3,6 @@ | ||||||
|     <div class="container-fluid"> |     <div class="container-fluid"> | ||||||
| 
 | 
 | ||||||
|       <div class="navbar-header"> |       <div class="navbar-header"> | ||||||
|         <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#mynavbar"> |  | ||||||
|           <span class="icon-bar"></span> |  | ||||||
|           <span class="icon-bar"></span> |  | ||||||
|           <span class="icon-bar"></span> |  | ||||||
|         </button> |  | ||||||
|         <a class="navbar-brand" href="#" style="padding-top: 2px"> |         <a class="navbar-brand" href="#" style="padding-top: 2px"> | ||||||
|           <img height="40px" src="assets/opt-logo-klein.png"> |           <img height="40px" src="assets/opt-logo-klein.png"> | ||||||
|         </a> |         </a> | ||||||
|  | @ -22,20 +17,36 @@ | ||||||
|           <li routerLinkActive="active"> |           <li routerLinkActive="active"> | ||||||
|             <a routerLink='{{config.overviewPath}}' class="link">Armeeübersicht</a> |             <a routerLink='{{config.overviewPath}}' class="link">Armeeübersicht</a> | ||||||
|           </li> |           </li> | ||||||
|  |           <li routerLinkActive="active"> | ||||||
|  |             <a [routerLink]="[config.publicPath.concat('/').concat(config.rankPath)]" class="link">Ränge</a> | ||||||
|  |           </li> | ||||||
|  |           <li routerLinkActive="active"> | ||||||
|  |             <a [routerLink]="[config.publicPath.concat('/').concat(config.decorationPath)]" class="link">Auszeichnungen</a> | ||||||
|  |           </li> | ||||||
|           <li routerLinkActive="active"> |           <li routerLinkActive="active"> | ||||||
|             <a routerLink='{{config.statsPath}}' class="link">Statistiken</a> |             <a routerLink='{{config.statsPath}}' class="link">Statistiken</a> | ||||||
|           </li> |           </li> | ||||||
|           <li *ngIf="loginService.hasPermission(2)" routerLinkActive="active"> |           <li *ngIf="loginService.hasPermission(2)" | ||||||
|             <a routerLink='{{config.userPath}}' class="link">Teilnehmer</a> |               class="dropdown"> | ||||||
|           </li> |             <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" | ||||||
|           <li *ngIf="loginService.hasPermission(2)" routerLinkActive="active"> |                aria-expanded="false"> | ||||||
|             <a routerLink='{{config.squadPath}}' class="link">Squads</a> |               Verwaltung | ||||||
|           </li> |               <span class="caret"></span> | ||||||
|           <li *ngIf="loginService.hasPermission(2)" routerLinkActive="active"> |             </a> | ||||||
|             <a routerLink='{{config.decorationPath}}' class="link">Auszeichnungen</a> |             <ul class="dropdown-menu"> | ||||||
|           </li> |               <li routerLinkActive="active"> | ||||||
|           <li *ngIf="loginService.hasPermission(2)" routerLinkActive="active"> |                 <a routerLink='{{config.userPath}}' class="link">Teilnehmer</a> | ||||||
|             <a routerLink='{{config.rankPath}}' class="link">Ränge</a> |               </li> | ||||||
|  |               <li routerLinkActive="active"> | ||||||
|  |                 <a routerLink='{{config.squadPath}}' class="link">Squads</a> | ||||||
|  |               </li> | ||||||
|  |               <li routerLinkActive="active"> | ||||||
|  |                 <a routerLink='{{config.decorationPath}}' class="link">Auszeichnungen</a> | ||||||
|  |               </li> | ||||||
|  |               <li routerLinkActive="active"> | ||||||
|  |                 <a routerLink='{{config.rankPath}}' class="link">Ränge</a> | ||||||
|  |               </li> | ||||||
|  |             </ul> | ||||||
|           </li> |           </li> | ||||||
|           <li *ngIf="loginService.hasPermission(1) && !loginService.hasPermission(2) && loginService.hasSquad()" |           <li *ngIf="loginService.hasPermission(1) && !loginService.hasPermission(2) && loginService.hasSquad()" | ||||||
|               class="dropdown"> |               class="dropdown"> | ||||||
|  | @ -91,20 +102,27 @@ | ||||||
|       </div> |       </div> | ||||||
|     </div> |     </div> | ||||||
|   </nav> |   </nav> | ||||||
| 
 |  | ||||||
|   <button (click)="scrollToTop()" *ngIf="scrollTopVisible" id="scrollTopBtn" title="Zum Seitenanfang">△</button> |  | ||||||
| 
 |  | ||||||
| </div> | </div> | ||||||
| 
 | 
 | ||||||
| <div> | <div> | ||||||
|   <span *ngIf="loading" class="load-indicator load-arrow glyphicon-refresh-animate"></span> |   <router-outlet></router-outlet> | ||||||
|  | 
 | ||||||
|   <div id="left"> |   <div id="left"> | ||||||
|     <router-outlet></router-outlet> |     <router-outlet name="left"></router-outlet> | ||||||
|   </div> |   </div> | ||||||
|  | 
 | ||||||
|   <div id="right"> |   <div id="right"> | ||||||
|     <router-outlet name="right"></router-outlet> |     <router-outlet name="right"></router-outlet> | ||||||
|   </div> |   </div> | ||||||
|   <div id="footer"> |  | ||||||
|     <router-outlet name="footer"></router-outlet> |  | ||||||
|   </div> |  | ||||||
| </div> | </div> | ||||||
|  | 
 | ||||||
|  | <span *ngIf="loading" class="load-indicator load-arrow glyphicon-refresh-animate"></span> | ||||||
|  | 
 | ||||||
|  | <button mat-icon-button | ||||||
|  |         mat-mini-fab | ||||||
|  |         id="scrollTopBtn" | ||||||
|  |         *ngIf="scrollTopVisible" | ||||||
|  |         matTooltip="Zum Seitenanfang" | ||||||
|  |         (click)="scrollToTop()"> | ||||||
|  |   <mat-icon svgIcon="arrow-up"></mat-icon> | ||||||
|  | </button> | ||||||
|  |  | ||||||
|  | @ -5,6 +5,9 @@ import {PromotionService} from './services/army-management/promotion.service'; | ||||||
| import {AwardingService} from './services/army-management/awarding.service'; | import {AwardingService} from './services/army-management/awarding.service'; | ||||||
| import {RouteConfig} from './app.config'; | import {RouteConfig} from './app.config'; | ||||||
| import {DOCUMENT} from '@angular/common'; | import {DOCUMENT} from '@angular/common'; | ||||||
|  | import {DomSanitizer} from '@angular/platform-browser'; | ||||||
|  | import {MatIconRegistry} from '@angular/material'; | ||||||
|  | import {SpinnerService} from './services/user-interface/spinner/spinner.service'; | ||||||
| 
 | 
 | ||||||
| declare function require(url: string); | declare function require(url: string); | ||||||
| 
 | 
 | ||||||
|  | @ -23,34 +26,78 @@ export class AppComponent implements OnInit { | ||||||
| 
 | 
 | ||||||
|   scrollBtnVisibleVal = 100; |   scrollBtnVisibleVal = 100; | ||||||
| 
 | 
 | ||||||
|  |   // a map of svgIcon names and associated svg file names
 | ||||||
|  |   // to load from assets/icon folder
 | ||||||
|  |   svgIcons = { | ||||||
|  |     'add': 'outline-add_box-24px', | ||||||
|  |     'add-user': 'twotone-person_add-24px', | ||||||
|  |     'edit': 'baseline-edit-24px', | ||||||
|  |     'delete': 'baseline-delete-24px', | ||||||
|  |     'stats-detail': 'round-assessment-24px', | ||||||
|  |     'chevron-left': 'baseline-chevron_left-24px', | ||||||
|  |     'chevron-right': 'baseline-chevron_right-24px', | ||||||
|  |     'arrow-up': 'baseline-arrow_upward-24px', | ||||||
|  |     'more-vert': 'baseline-more_vert-24px', | ||||||
|  |     // --------STATISTICS---------
 | ||||||
|  |     'award': 'stats/award', | ||||||
|  |     'battle': 'stats/battle', | ||||||
|  |     'flagTouch': 'stats/flagTouch', | ||||||
|  |     'friendlyFire': 'stats/friendlyFire', | ||||||
|  |     'highscore': 'stats/highscore', | ||||||
|  |     'kill': 'stats/kill', | ||||||
|  |     'respawn': 'stats/respawn', | ||||||
|  |     'revive': 'stats/respawn', | ||||||
|  |     'stats-chart': 'stats/statsChart', | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|   version = 'v'.concat(require('./../../../package.json').version); |   version = 'v'.concat(require('./../../../package.json').version); | ||||||
| 
 | 
 | ||||||
|   constructor(public loginService: LoginService, |   constructor(public loginService: LoginService, | ||||||
|               private promotionService: PromotionService, |               private promotionService: PromotionService, | ||||||
|               private awardingService: AwardingService, |               private awardingService: AwardingService, | ||||||
|               private router: Router, |               private router: Router, | ||||||
|  |               private iconRegistry: MatIconRegistry, | ||||||
|  |               private sanitizer: DomSanitizer, | ||||||
|  |               private spinnerService: SpinnerService, | ||||||
|               @Inject(DOCUMENT) private document) { |               @Inject(DOCUMENT) private document) { | ||||||
|  |     this.initMaterialSvgIcons(); | ||||||
|  | 
 | ||||||
|  |     this.spinnerService.spinnerActive.subscribe(active => this.toggleSpinner(active)); | ||||||
|  | 
 | ||||||
|     router.events.subscribe(event => { |     router.events.subscribe(event => { | ||||||
|       if (event instanceof NavigationStart) { |       if (event instanceof NavigationStart) { | ||||||
|         this.loading = true; |         this.spinnerService.activate(); | ||||||
|       } |       } | ||||||
|       if (event instanceof NavigationEnd) { |       if (event instanceof NavigationEnd) { | ||||||
|         this.loading = false; |         this.spinnerService.deactivate(); | ||||||
|  |         const currentUrl = this.router.url; | ||||||
|  | 
 | ||||||
|         // scroll to top on route from army overview to user detail and back
 |         // scroll to top on route from army overview to user detail and back
 | ||||||
|         if (router.url.includes('overview')) { |         if (currentUrl.includes('/overview') || currentUrl.includes('/public')) { | ||||||
|           this.scrollToTop(); |           this.scrollToTop(); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   toggleSpinner(active) { | ||||||
|  |     this.loading = active; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   initMaterialSvgIcons() { | ||||||
|  |     Object.keys(this.svgIcons).forEach(key => { | ||||||
|  |       const fileUri = '../assets/icon/'.concat(this.svgIcons[key]) | ||||||
|  |                                        .concat('.svg'); | ||||||
|  |       this.iconRegistry.addSvgIcon(key, this.sanitizer.bypassSecurityTrustResourceUrl(fileUri)); | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   @HostListener('window:scroll', []) |   @HostListener('window:scroll', []) | ||||||
|   onWindowScroll() { |   onWindowScroll() { | ||||||
|     this.scrollTopVisible = document.body.scrollTop > this.scrollBtnVisibleVal |     this.scrollTopVisible = document.body.scrollTop > this.scrollBtnVisibleVal | ||||||
|       || document.documentElement.scrollTop > this.scrollBtnVisibleVal; |       || document.documentElement.scrollTop > this.scrollBtnVisibleVal; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|   ngOnInit() { |   ngOnInit() { | ||||||
|     if (this.loginService.hasPermission(2)) { |     if (this.loginService.hasPermission(2)) { | ||||||
|       const fraction = this.loginService.getCurrentUser().squad.fraction; |       const fraction = this.loginService.getCurrentUser().squad.fraction; | ||||||
|  | @ -61,14 +108,14 @@ export class AppComponent implements OnInit { | ||||||
| 
 | 
 | ||||||
|   logout() { |   logout() { | ||||||
|     this.loginService.logout(); |     this.loginService.logout(); | ||||||
|     this.router.navigate([RouteConfig.overviewPath]); |     setTimeout(() => { | ||||||
|     return false; |       this.router.navigate([RouteConfig.overviewPath]); | ||||||
|  |     }, 500); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   scrollToTop() { |   scrollToTop() { | ||||||
|     this.document.body.scrollTop = 0; // For Safari
 |     this.document.body.scrollTop = 0; // For Safari
 | ||||||
|     this.document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
 |     this.document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
 | ||||||
|   } |   } | ||||||
| 
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,7 +5,6 @@ export class AppConfig { | ||||||
|   public readonly apiAppUserPath = this.apiUrl + '/account/'; |   public readonly apiAppUserPath = this.apiUrl + '/account/'; | ||||||
|   public readonly apiAuthenticationPath = this.apiUrl + '/authenticate'; |   public readonly apiAuthenticationPath = this.apiUrl + '/authenticate'; | ||||||
|   public readonly apiAwardPath = this.apiUrl + '/awardings'; |   public readonly apiAwardPath = this.apiUrl + '/awardings'; | ||||||
|   public readonly apiAwardSquadPath = this.apiUrl + '/awardings/unprocessed'; |  | ||||||
|   public readonly apiCampaignPath = this.apiUrl + '/campaigns'; |   public readonly apiCampaignPath = this.apiUrl + '/campaigns'; | ||||||
|   public readonly apiDecorationPath = this.apiUrl + '/decorations/'; |   public readonly apiDecorationPath = this.apiUrl + '/decorations/'; | ||||||
|   public readonly apiLogsPath = this.apiUrl + '/logs'; |   public readonly apiLogsPath = this.apiUrl + '/logs'; | ||||||
|  | @ -36,4 +35,7 @@ export const RouteConfig = { | ||||||
|   confirmAwardPath: 'confirm-award', |   confirmAwardPath: 'confirm-award', | ||||||
|   confirmPromotionPath: 'confirm-promotion', |   confirmPromotionPath: 'confirm-promotion', | ||||||
|   sqlDashboardPath: 'sql-dashboard', |   sqlDashboardPath: 'sql-dashboard', | ||||||
|  |   publicPath: 'public', | ||||||
|  |   rankOverviewPath: 'public/ranks', | ||||||
|  |   decorationOverviewPath: 'public/decorations', | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -11,7 +11,7 @@ import {DecorationService} from './services/army-management/decoration.service'; | ||||||
| import {RankStore} from './services/stores/rank.store'; | import {RankStore} from './services/stores/rank.store'; | ||||||
| import {RankService} from './services/army-management/rank.service'; | import {RankService} from './services/army-management/rank.service'; | ||||||
| import {AppConfig} from './app.config'; | import {AppConfig} from './app.config'; | ||||||
| import {LoginGuardAdmin, LoginGuardHL, LoginGuardSQL} from './login/login.guard'; | import {LoginGuardAdmin, LoginGuardHL, LoginGuardSQL} from './login'; | ||||||
| import {AwardingService} from './services/army-management/awarding.service'; | import {AwardingService} from './services/army-management/awarding.service'; | ||||||
| import {HttpClient} from './services/http-client'; | import {HttpClient} from './services/http-client'; | ||||||
| import {ArmyService} from './services/army-service/army.service'; | import {ArmyService} from './services/army-service/army.service'; | ||||||
|  | @ -22,9 +22,14 @@ import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; | ||||||
| import {UserService} from './services/army-management/user.service'; | import {UserService} from './services/army-management/user.service'; | ||||||
| import {UserStore} from './services/stores/user.store'; | import {UserStore} from './services/stores/user.store'; | ||||||
| import {CookieService} from 'ngx-cookie-service'; | import {CookieService} from 'ngx-cookie-service'; | ||||||
|  | import {SnackBarService} from './services/user-interface/snack-bar/snack-bar.service'; | ||||||
|  | import {HttpClientModule} from '@angular/common/http'; | ||||||
|  | import {SpinnerService} from './services/user-interface/spinner/spinner.service'; | ||||||
|  | import {MatSnackBarModule} from '@angular/material'; | ||||||
| 
 | 
 | ||||||
| @NgModule({ | @NgModule({ | ||||||
|   imports: [SharedModule, BrowserModule, BrowserAnimationsModule, appRouting, HttpModule, ClipboardModule], |   imports: [SharedModule, BrowserModule, BrowserAnimationsModule, appRouting, HttpModule, HttpClientModule, | ||||||
|  |     ClipboardModule, MatSnackBarModule], | ||||||
|   providers: [ |   providers: [ | ||||||
|     HttpClient, |     HttpClient, | ||||||
|     LoginService, |     LoginService, | ||||||
|  | @ -44,7 +49,9 @@ import {CookieService} from 'ngx-cookie-service'; | ||||||
|     PromotionService, |     PromotionService, | ||||||
|     AppConfig, |     AppConfig, | ||||||
|     routingProviders, |     routingProviders, | ||||||
|     CookieService |     CookieService, | ||||||
|  |     SnackBarService, | ||||||
|  |     SpinnerService, | ||||||
|   ], |   ], | ||||||
|   declarations: [ |   declarations: [ | ||||||
|     AppComponent, |     AppComponent, | ||||||
|  |  | ||||||
|  | @ -42,6 +42,10 @@ export const appRoutes: Routes = [ | ||||||
|     loadChildren: './ranks/ranks.module#RanksModule', |     loadChildren: './ranks/ranks.module#RanksModule', | ||||||
|     canActivate: [LoginGuardHL] |     canActivate: [LoginGuardHL] | ||||||
|   }, |   }, | ||||||
|  |   { | ||||||
|  |     path: RouteConfig.publicPath, | ||||||
|  |     loadChildren: './pub/public.module#PublicModule' | ||||||
|  |   }, | ||||||
|   { |   { | ||||||
|     path: RouteConfig.adminPanelPath, |     path: RouteConfig.adminPanelPath, | ||||||
|     loadChildren: './admin/admin.module#AdminModule', |     loadChildren: './admin/admin.module#AdminModule', | ||||||
|  |  | ||||||
|  | @ -1,3 +1,18 @@ | ||||||
|  | :host { | ||||||
|  |   display: flow-root; | ||||||
|  |   height: 100%; | ||||||
|  |   min-height: 100vh; | ||||||
|  |   width: 100%; | ||||||
|  |   margin-top: -23px; | ||||||
|  |   padding-top: 23px; | ||||||
|  |   padding-bottom: 23px; | ||||||
|  |   background-image: url('../../../assets/bg.jpg'); | ||||||
|  |   background-size: cover; | ||||||
|  |   background-attachment: fixed; | ||||||
|  |   background-position: top; | ||||||
|  |   background-repeat: no-repeat; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .army-member-view { | .army-member-view { | ||||||
|   width: 90%; |   width: 90%; | ||||||
|   height: 100vh; |   height: 100vh; | ||||||
|  | @ -12,8 +27,8 @@ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .return-button { | .return-button { | ||||||
|   display: block; |   position: absolute; | ||||||
|   width: auto; |   padding-left: 5px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .table { | .table { | ||||||
|  | @ -39,3 +54,7 @@ tbody { | ||||||
| .cell-outline { | .cell-outline { | ||||||
|   outline: 1px solid #D4D4D4; |   outline: 1px solid #D4D4D4; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | tr.cell-outline:hover { | ||||||
|  |   background-color: #ffffff; | ||||||
|  | } | ||||||
|  | @ -1,13 +1,17 @@ | ||||||
| <div class="army-member-view"> | <div class="army-member-view"> | ||||||
|   <div class="army-member-view-container"> |   <div class="army-member-view-container"> | ||||||
|     <div class="return-button"> |     <div class="return-button"> | ||||||
|       <span class="btn btn-default" style="position:absolute;" (click)="backToOverview()">< zurück zur Übersicht</span> |       <button mat-raised-button (click)="backToOverview()"> | ||||||
|       <h3 class="text-center" style="font-weight: 600" |         <mat-icon svgIcon="chevron-left"></mat-icon> | ||||||
|           [style.color]="user.squadId?.fraction === 'BLUFOR' ? fraction.COLOR_BLUFOR : fraction.COLOR_OPFOR"> |         Zurück | ||||||
|         Auszeichnungen von {{user.username}} |       </button> | ||||||
|       </h3> |  | ||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|  |     <h3 class="text-center" style="font-weight: 600" | ||||||
|  |         [style.color]="user.squadId?.fraction === 'BLUFOR' ? fraction.COLOR_BLUFOR : fraction.COLOR_OPFOR"> | ||||||
|  |       Auszeichnungen von {{user.username}} | ||||||
|  |     </h3> | ||||||
|  | 
 | ||||||
|     <div class="text-center"> |     <div class="text-center"> | ||||||
|       <img src="{{signatureUrl}}"> |       <img src="{{signatureUrl}}"> | ||||||
|     </div> |     </div> | ||||||
|  | @ -21,7 +25,7 @@ | ||||||
| 
 | 
 | ||||||
|     <div class="pull-left" style="margin-top:20px;"> |     <div class="pull-left" style="margin-top:20px;"> | ||||||
|       <div class="table-container" style="min-width: 500px"> |       <div class="table-container" style="min-width: 500px"> | ||||||
|         <table class="table table-hover"> |         <table class="table"> | ||||||
|           <thead> |           <thead> | ||||||
|           <tr class="table-head"> |           <tr class="table-head"> | ||||||
|             <th class="col-sm-1" style="border-radius: 10px 0 0 0;"></th> |             <th class="col-sm-1" style="border-radius: 10px 0 0 0;"></th> | ||||||
|  | @ -1,21 +1,19 @@ | ||||||
| import {Component, Inject, OnDestroy, OnInit} from '@angular/core'; | import {Component, Inject, OnDestroy, OnInit} from '@angular/core'; | ||||||
| import {Award, User} from '../models/model-interfaces'; | import {Award, User} from '../../models/model-interfaces'; | ||||||
| import {ActivatedRoute, Router} from '@angular/router'; | import {ActivatedRoute, Router} from '@angular/router'; | ||||||
| import {UserService} from '../services/army-management/user.service'; | import {UserService} from '../../services/army-management/user.service'; | ||||||
| import {Subscription} from 'rxjs/Subscription'; | import {Subscription} from 'rxjs/Subscription'; | ||||||
| import {RouteConfig} from '../app.config'; | import {RouteConfig} from '../../app.config'; | ||||||
| import {AwardingService} from '../services/army-management/awarding.service'; | import {AwardingService} from '../../services/army-management/awarding.service'; | ||||||
| import {Fraction} from '../utils/fraction.enum'; | import {Fraction} from '../../utils/fraction.enum'; | ||||||
| import {DOCUMENT} from '@angular/common'; | import {Location} from '@angular/common'; | ||||||
| import {CSSHelpers} from '../global.helpers'; |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'army-member', |   selector: 'army-member', | ||||||
|   templateUrl: './army-member.component.html', |   templateUrl: './army-member.component.html', | ||||||
|   styleUrls: ['./army-member.component.css'] |   styleUrls: ['./army-member.component.css'] | ||||||
| }) | }) | ||||||
| export class ArmyMemberComponent implements OnInit, OnDestroy { | export class ArmyMemberComponent implements OnInit { | ||||||
| 
 | 
 | ||||||
|   subscription: Subscription; |   subscription: Subscription; | ||||||
| 
 | 
 | ||||||
|  | @ -33,12 +31,10 @@ export class ArmyMemberComponent implements OnInit, OnDestroy { | ||||||
|               private route: ActivatedRoute, |               private route: ActivatedRoute, | ||||||
|               private userService: UserService, |               private userService: UserService, | ||||||
|               private awardingService: AwardingService, |               private awardingService: AwardingService, | ||||||
|               @Inject(DOCUMENT) private document) { |               private location: Location) { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   ngOnInit() { |   ngOnInit() { | ||||||
|     // set background image css
 |  | ||||||
|     this.document.getElementById('right').setAttribute('style', CSSHelpers.getBackgroundCSS('../assets/bg.jpg')); |  | ||||||
| 
 | 
 | ||||||
|     this.subscription = this.route.params |     this.subscription = this.route.params | ||||||
|                             .map(params => params['id']) |                             .map(params => params['id']) | ||||||
|  | @ -51,17 +47,9 @@ export class ArmyMemberComponent implements OnInit, OnDestroy { | ||||||
|                                 this.awards = awards; |                                 this.awards = awards; | ||||||
|                               })); |                               })); | ||||||
|                             }); |                             }); | ||||||
| 
 |  | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   ngOnDestroy() { |  | ||||||
|     if (this.router.url !== '/' + RouteConfig.overviewPath) { |  | ||||||
|       this.document.getElementById('right').setAttribute('style', ''); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   backToOverview() { |   backToOverview() { | ||||||
|     this.router.navigate([RouteConfig.overviewPath]); |     this.location.back(); | ||||||
|   } |   } | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  | @ -0,0 +1,70 @@ | ||||||
|  | .squad-layout { | ||||||
|  |   overflow: hidden; | ||||||
|  |   padding: 6px 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .squad-layout > div { | ||||||
|  |   clear: both; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .squad-layout > div:first-child { | ||||||
|  |   background: rgb(34, 34, 34); | ||||||
|  |   border-radius: 12px 12px 0 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .squad-layout > div:last-child { | ||||||
|  |   display: flex; | ||||||
|  |   background: rgb(34, 34, 34); | ||||||
|  |   border-radius: 0 0 12px 12px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .squad-cell { | ||||||
|  |   display: table-cell; | ||||||
|  |   padding: 5px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .squad-member-count { | ||||||
|  |   float:left; | ||||||
|  |   color: whitesmoke; | ||||||
|  |   margin-left: 42px | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .middle-row { | ||||||
|  |   min-height: 120px; | ||||||
|  |   padding: 5px; | ||||||
|  |   border: rgb(34, 34, 34); | ||||||
|  |   background-color: rgba(255, 255, 255, 0.88); | ||||||
|  |   border-left-style: solid; | ||||||
|  |   border-right-style: solid; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .member-link { | ||||||
|  |   cursor: pointer; | ||||||
|  |   text-decoration: underline; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | img { | ||||||
|  |   position: absolute; | ||||||
|  |   margin-top: 8px; | ||||||
|  |   margin-left: 25px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .title { | ||||||
|  |   color: whitesmoke; | ||||||
|  |   font-weight: bold; | ||||||
|  |   font-size: 14px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .name-cell { | ||||||
|  |   display: inherit; | ||||||
|  |   margin-left: 200px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | .colored-row { | ||||||
|  |   background: rgb(34, 34, 34); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .footer-row { | ||||||
|  |   border-radius: 0 0 12px 12px; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,24 @@ | ||||||
|  | <div class="squad-layout"> | ||||||
|  |   <div> | ||||||
|  |     <div class="squad-cell pull-left"> | ||||||
|  |       <img src="resource/squad/{{squad._id}}.png"> | ||||||
|  |     </div> | ||||||
|  |     <div class="squad-cell title name-cell">{{squad.name}}</div> | ||||||
|  |   </div> | ||||||
|  |   <div class=" middle-row"> | ||||||
|  |     <div class="name-cell"> | ||||||
|  |       <div [style.color]="squadFraction === 'BLUFOR' ? fraction.COLOR_BLUFOR : fraction.COLOR_OPFOR" | ||||||
|  |            *ngFor="let member of squad.members"> | ||||||
|  |           <span class="member-link" | ||||||
|  |                 (click)="select(member._id)"> | ||||||
|  |             {{member.rank}} {{member.username}} | ||||||
|  |           </span> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  |   <div> | ||||||
|  |     <div class="squad-cell squad-member-count"> | ||||||
|  |       Mitglieder: {{squad.memberCount}} | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
|  | @ -0,0 +1,26 @@ | ||||||
|  | import {Component, EventEmitter, Input, Output} from '@angular/core'; | ||||||
|  | 
 | ||||||
|  | import {Fraction} from '../../utils/fraction.enum'; | ||||||
|  | 
 | ||||||
|  | @Component({ | ||||||
|  |   selector: 'cc-army-squad', | ||||||
|  |   templateUrl: './army-squad.component.html', | ||||||
|  |   styleUrls: ['./army-squad.component.css'] | ||||||
|  | }) | ||||||
|  | export class ArmySquadComponent { | ||||||
|  | 
 | ||||||
|  |   @Input() squad; | ||||||
|  | 
 | ||||||
|  |   @Input() squadFraction: String; | ||||||
|  | 
 | ||||||
|  |   @Output() memberSelect = new EventEmitter(); | ||||||
|  | 
 | ||||||
|  |   readonly fraction = Fraction; | ||||||
|  | 
 | ||||||
|  |   constructor() { | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   select(memberId) { | ||||||
|  |     this.memberSelect.emit(memberId); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -1,63 +1,26 @@ | ||||||
| .squad-layout { | :host { | ||||||
|   overflow: hidden; |   display: flow-root; | ||||||
|   padding: 5px 15px 5px 15px; |   height: 100%; | ||||||
|  |   min-height: 100vh; | ||||||
|  |   width: 100%; | ||||||
|  |   margin-top: -23px; | ||||||
|  |   padding-top: 23px; | ||||||
|  |   padding-bottom: 23px; | ||||||
|  |   background-image: url('../../assets/bg.jpg'); | ||||||
|  |   background-size: cover; | ||||||
|  |   background-attachment: fixed; | ||||||
|  |   background-position: top; | ||||||
|  |   background-repeat: no-repeat; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .row { | .army-column { | ||||||
|   clear: both; |   width: 45%; | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .squad-cell { |  | ||||||
|   display: table-cell; |  | ||||||
|   padding: 5px; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .colored-row { |  | ||||||
|   background: rgb(34, 34, 34); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .title-row { |  | ||||||
|   border-radius: 12px 12px 0 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .footer-row { |  | ||||||
|   border-radius: 0 0 12px 12px; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .middle-row { |  | ||||||
|   min-height: 120px; |  | ||||||
|   border: rgb(34, 34, 34); |  | ||||||
|   background-color: rgba(255, 255, 255, 0.88); |  | ||||||
|   border-left-style: solid; |  | ||||||
|   border-right-style: solid; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .title { |  | ||||||
|   color: whitesmoke; |  | ||||||
|   font-weight: bold; |  | ||||||
|   font-size: 14px; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .name-cell { |  | ||||||
|   display: inherit; |  | ||||||
|   margin-left: 200px; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| h1 { | h1 { | ||||||
|   text-align: center; |   text-align: center; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| img { |  | ||||||
|   position: absolute; |  | ||||||
|   margin-top: 8px; |  | ||||||
|   margin-left: 25px; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .member-link { |  | ||||||
|   cursor: pointer; |  | ||||||
|   text-decoration: underline; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .army-head { | .army-head { | ||||||
|   font-weight: bolder; |   font-weight: bolder; | ||||||
|   text-align: center |   text-align: center | ||||||
|  | @ -72,4 +35,3 @@ img { | ||||||
|   background: #222222; |   background: #222222; | ||||||
|   border-radius: 12px; |   border-radius: 12px; | ||||||
| } | } | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -1,62 +1,23 @@ | ||||||
| <div style="width: 1100px; margin:auto; position: relative;"> | <div style="width: 1100px; margin:auto; position: relative;"> | ||||||
|   <h1>Übersicht über alle Spieler, Squads und Armeen</h1> |   <h1>Übersicht über alle Spieler, Squads und Armeen</h1> | ||||||
| 
 | 
 | ||||||
|   <div class="pull-left" style="width: 45%;"> |   <div class="pull-left army-column"> | ||||||
|     <h3 class="army-head" [style.color]="fraction.COLOR_BLUFOR">{{fraction.BLUFOR}}</h3> |     <h3 class="army-head" [style.color]="fraction.COLOR_BLUFOR">{{fraction.BLUFOR}}</h3> | ||||||
|     <div class="squad-layout" *ngFor="let squad of army[0].squads"> |     <cc-army-squad *ngFor="let squad of army[0].squads" | ||||||
|       <div class="row colored-row title-row"> |                    [squad]="squad" | ||||||
|         <div class="squad-cell pull-left"><img |                    squadFraction="BLUFOR" | ||||||
|           src="resource/squad/{{squad._id}}.png"></div> |                    (memberSelect)="select($event)"> | ||||||
|         <div class="squad-cell title name-cell">{{squad.name}}</div> |     </cc-army-squad> | ||||||
|       </div> |  | ||||||
|       <div class="row middle-row"> |  | ||||||
|         <div class="squad-cell name-cell"> |  | ||||||
|         <span style="display: block" |  | ||||||
|               [style.color]="fraction.COLOR_BLUFOR" |  | ||||||
|               *ngFor="let member of squad.members"> |  | ||||||
|           <span class="member-link" |  | ||||||
|                 (click)="select(member._id)"> |  | ||||||
|             {{member.rank}} {{member.username}} |  | ||||||
|           </span> |  | ||||||
|         </span> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|       <div class="row colored-row footer-row"> |  | ||||||
|         <div class="squad-cell pull-left" style="color: whitesmoke; margin-left: 42px"> |  | ||||||
|           Mitglieder: {{squad.memberCount}} |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|     </div> |  | ||||||
|     <div class="member-count">Armeemitglieder: {{army[0].memberCount}}</div> |     <div class="member-count">Armeemitglieder: {{army[0].memberCount}}</div> | ||||||
|   </div> |   </div> | ||||||
| 
 | 
 | ||||||
|   <div class="pull-right" style="width: 45%;"> |   <div class="pull-right army-column"> | ||||||
|     <h3 class="army-head" [style.color]="fraction.COLOR_OPFOR">{{fraction.OPFOR}}</h3> |     <h3 class="army-head" [style.color]="fraction.COLOR_OPFOR">{{fraction.OPFOR}}</h3> | ||||||
|     <div class="squad-layout" *ngFor="let squad of army[1].squads"> |     <cc-army-squad *ngFor="let squad of army[1].squads" | ||||||
|       <div class="row colored-row title-row"> |                    [squad]="squad" | ||||||
|         <div class="squad-cell pull-left"><img |                    squadFraction="OPFOR" | ||||||
|           src="resource/squad/{{squad._id}}.png"></div> |                    (memberSelect)="select($event)"> | ||||||
|         <div class="squad-cell title name-cell">{{squad.name}}</div> |     </cc-army-squad> | ||||||
|       </div> |  | ||||||
|       <div class="row middle-row"> |  | ||||||
|         <div class="squad-cell name-cell"> |  | ||||||
|         <span style="display: block" |  | ||||||
|               [style.color]="fraction.COLOR_OPFOR" |  | ||||||
|               *ngFor="let member of squad.members"> |  | ||||||
|           <span class="member-link" |  | ||||||
|                 (click)="select(member._id)"> |  | ||||||
|             {{member.rank}} {{member.username}} |  | ||||||
|           </span> |  | ||||||
|         </span> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|       <div class="row colored-row footer-row"> |  | ||||||
|         <div class="squad-cell pull-left" style="color: whitesmoke; margin-left: 42px"> |  | ||||||
|           Mitglieder: {{squad.memberCount}} |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|     </div> |  | ||||||
|     <div class="member-count">Armeemitglieder: {{army[1].memberCount}}</div> |     <div class="member-count">Armeemitglieder: {{army[1].memberCount}}</div> | ||||||
|   </div> |   </div> | ||||||
| 
 |  | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
|  | @ -1,11 +1,8 @@ | ||||||
| import {Component, Inject, OnDestroy, OnInit} from '@angular/core'; | import {Component, OnInit} from '@angular/core'; | ||||||
| import {Army} from '../models/model-interfaces'; | import {Army} from '../models/model-interfaces'; | ||||||
| import {ArmyService} from '../services/army-service/army.service'; | import {ArmyService} from '../services/army-service/army.service'; | ||||||
| import {ActivatedRoute, Router} from '@angular/router'; | import {ActivatedRoute, Router} from '@angular/router'; | ||||||
| import {Fraction} from '../utils/fraction.enum'; | import {Fraction} from '../utils/fraction.enum'; | ||||||
| import {DOCUMENT} from '@angular/common'; |  | ||||||
| import {RouteConfig} from '../app.config'; |  | ||||||
| import {CSSHelpers} from '../global.helpers'; |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @Component({ | @Component({ | ||||||
|  | @ -13,7 +10,7 @@ import {CSSHelpers} from '../global.helpers'; | ||||||
|   templateUrl: './army.component.html', |   templateUrl: './army.component.html', | ||||||
|   styleUrls: ['./army.component.css'] |   styleUrls: ['./army.component.css'] | ||||||
| }) | }) | ||||||
| export class ArmyComponent implements OnInit, OnDestroy { | export class ArmyComponent implements OnInit { | ||||||
| 
 | 
 | ||||||
|   army: Army[] = [{}, {}]; |   army: Army[] = [{}, {}]; | ||||||
| 
 | 
 | ||||||
|  | @ -21,14 +18,10 @@ export class ArmyComponent implements OnInit, OnDestroy { | ||||||
| 
 | 
 | ||||||
|   constructor(private router: Router, |   constructor(private router: Router, | ||||||
|               private route: ActivatedRoute, |               private route: ActivatedRoute, | ||||||
|               private armyService: ArmyService, |               private armyService: ArmyService) { | ||||||
|               @Inject(DOCUMENT) private document) { |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   ngOnInit() { |   ngOnInit() { | ||||||
|     // set background image css
 |  | ||||||
|     this.document.getElementById('right').setAttribute('style', CSSHelpers.getBackgroundCSS('../assets/bg.jpg')); |  | ||||||
| 
 |  | ||||||
|     // init army data
 |     // init army data
 | ||||||
|     this.armyService.getArmy() |     this.armyService.getArmy() | ||||||
|         .subscribe(army => { |         .subscribe(army => { | ||||||
|  | @ -36,14 +29,8 @@ export class ArmyComponent implements OnInit, OnDestroy { | ||||||
|         }); |         }); | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   ngOnDestroy() { |  | ||||||
|     if (!this.router.url.includes(RouteConfig.overviewPath)) { |  | ||||||
|       this.document.getElementById('right').setAttribute('style', ''); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   select(memberId) { |   select(memberId) { | ||||||
|     this.router.navigate([{outlets: {'right': ['member', memberId]}}], {relativeTo: this.route}); |     this.router.navigate(['member', memberId], {relativeTo: this.route}); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,20 +1,17 @@ | ||||||
| import {Routes} from '@angular/router'; | import {Routes} from '@angular/router'; | ||||||
| import {ArmyComponent} from './army.component'; | import {ArmyComponent} from './army.component'; | ||||||
| import {ArmyMemberComponent} from './army-member.component'; | import {ArmyMemberComponent} from './army-member/army-member.component'; | ||||||
| 
 | import {ArmySquadComponent} from './army-squad/army-squad.component'; | ||||||
| 
 | 
 | ||||||
| export const armyRoutes: Routes = [ | export const armyRoutes: Routes = [ | ||||||
|   { |   { | ||||||
|     path: '', |     path: '', | ||||||
|     component: ArmyComponent, |     component: ArmyComponent, | ||||||
|     outlet: 'right' |  | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     path: 'member/:id', |     path: 'member/:id', | ||||||
|     component: ArmyMemberComponent, |     component: ArmyMemberComponent, | ||||||
|     outlet: 'right' |  | ||||||
|   } |   } | ||||||
| ]; | ]; | ||||||
| 
 | 
 | ||||||
| export const armyRoutingComponents = [ArmyComponent, ArmyMemberComponent]; | export const armyRoutingComponents = [ArmyComponent, ArmySquadComponent, ArmyMemberComponent]; | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -12,8 +12,10 @@ import {FormGroup, NgForm} from '@angular/forms'; | ||||||
| }) | }) | ||||||
| export class ShowErrorComponent { | export class ShowErrorComponent { | ||||||
| 
 | 
 | ||||||
|  |   // tslint:disable-next-line:no-input-rename
 | ||||||
|   @Input('controlPath') controlPath; |   @Input('controlPath') controlPath; | ||||||
| 
 | 
 | ||||||
|  |   // tslint:disable-next-line:no-input-rename
 | ||||||
|   @Input('displayName') displayName = ''; |   @Input('displayName') displayName = ''; | ||||||
| 
 | 
 | ||||||
|   private form: FormGroup; |   private form: FormGroup; | ||||||
|  |  | ||||||
|  | @ -0,0 +1,34 @@ | ||||||
|  | .list-header { | ||||||
|  |   width: 100%; | ||||||
|  |   padding-bottom: 20px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .add-btn { | ||||||
|  |   margin-right: 16px; | ||||||
|  |   margin-top: -3px; | ||||||
|  |   float: right; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :host/deep/.mat-icon { | ||||||
|  |   height: 32px; | ||||||
|  |   width: 32px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :host/deep/.mat-icon > svg { | ||||||
|  |   color: #222222; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :host/deep/.mat-icon { | ||||||
|  |   height: 32px; | ||||||
|  |   width: 32px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :host/deep/.mat-button-toggle { | ||||||
|  |   background: white; | ||||||
|  |   color: darkslategrey; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :host/deep/.mat-button-toggle-checked { | ||||||
|  |   background: rgba(51, 122, 183, 0.64); | ||||||
|  |   color: white; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,14 @@ | ||||||
|  | <div class="input-group list-header pull-left"> | ||||||
|  |   <mat-button-toggle-group #group="matButtonToggleGroup"> | ||||||
|  |     <mat-button-toggle *ngFor="let button of filterButtons" value="{{button.value}}" (change)="execute(group)"> | ||||||
|  |       {{button.label}} | ||||||
|  |     </mat-button-toggle> | ||||||
|  |   </mat-button-toggle-group> | ||||||
|  |   <button mat-icon-button | ||||||
|  |           class="add-btn" | ||||||
|  |           matTooltip="{{addButton.tooltip}}" | ||||||
|  |           (click)="add()"> | ||||||
|  |       <mat-icon svgIcon="{{addButton.svgIcon}}"> | ||||||
|  |     </mat-icon> | ||||||
|  |   </button> | ||||||
|  | </div> | ||||||
|  | @ -0,0 +1,28 @@ | ||||||
|  | import {Component, EventEmitter, Input, Output} from '@angular/core'; | ||||||
|  | 
 | ||||||
|  | @Component({ | ||||||
|  |   selector: 'cc-list-filter', | ||||||
|  |   templateUrl: './list-filter.component.html', | ||||||
|  |   styleUrls: ['./list-filter.component.css'] | ||||||
|  | }) | ||||||
|  | export class ListFilterComponent { | ||||||
|  | 
 | ||||||
|  |   @Input() filterButtons: any[]; | ||||||
|  | 
 | ||||||
|  |   @Input() addButton: any; | ||||||
|  | 
 | ||||||
|  |   @Output() executeSearch = new EventEmitter(); | ||||||
|  | 
 | ||||||
|  |   @Output() openAddFrom = new EventEmitter(); | ||||||
|  | 
 | ||||||
|  |   constructor() { | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   execute(group) { | ||||||
|  |     this.executeSearch.emit(group); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   add() { | ||||||
|  |     this.openAddFrom.emit(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | .list-header { | ||||||
|  |   width: 100%; | ||||||
|  |   padding-bottom: 20px; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,12 @@ | ||||||
|  | <div class="input-group list-header"> | ||||||
|  |   <input id="search-field" | ||||||
|  |          type="text" #query class="form-control" | ||||||
|  |          (keyup.enter)="emitSearch()" | ||||||
|  |          [formControl]="searchTerm"> | ||||||
|  |   <span class="input-group-btn"> | ||||||
|  |       <button class="btn btn-default" type="button" | ||||||
|  |               (click)="emitSearch()"> | ||||||
|  |         Suchen | ||||||
|  |       </button> | ||||||
|  |     </span> | ||||||
|  | </div> | ||||||
|  | @ -0,0 +1,43 @@ | ||||||
|  | import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; | ||||||
|  | import {Location} from '@angular/common'; | ||||||
|  | import {ActivatedRoute} from '@angular/router'; | ||||||
|  | 
 | ||||||
|  | @Component({ | ||||||
|  |   selector: 'cc-list-search', | ||||||
|  |   templateUrl: './search-field.component.html', | ||||||
|  |   styleUrls: ['./search-field.component.css'] | ||||||
|  | }) | ||||||
|  | export class SearchFieldComponent implements OnInit { | ||||||
|  | 
 | ||||||
|  |   @Input() searchTerm; | ||||||
|  | 
 | ||||||
|  |   @Output() executeSearch = new EventEmitter(); | ||||||
|  | 
 | ||||||
|  |   @Output() searchTermStream = new EventEmitter(); | ||||||
|  | 
 | ||||||
|  |   constructor(private route: ActivatedRoute, | ||||||
|  |               private location: Location) { | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   ngOnInit() { | ||||||
|  |     const paramsObservable = this.route.queryParams | ||||||
|  |                              .map(params => decodeURI(params['query'] || '')) | ||||||
|  |                              .do(query => this.searchTerm.setValue(query)); | ||||||
|  | 
 | ||||||
|  |     const searchTermObservable = this.searchTerm.valueChanges | ||||||
|  |                                 .debounceTime(400) | ||||||
|  |                                 .do(query => this.adjustBrowserUrl(query)); | ||||||
|  |     this.searchTermStream.emit({params: paramsObservable, searchTerm: searchTermObservable}); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   emitSearch() { | ||||||
|  |     this.executeSearch.emit(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   adjustBrowserUrl(queryString = '') { | ||||||
|  |     const absoluteUrl = this.location.path().split('?')[0]; | ||||||
|  |     const queryPart = queryString !== '' ? `query=${queryString}` : ''; | ||||||
|  | 
 | ||||||
|  |     this.location.replaceState(absoluteUrl, queryPart); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -18,7 +18,7 @@ | ||||||
|            [style.max-width]="imgStyle.width" |            [style.max-width]="imgStyle.width" | ||||||
|            [style.margin-top]="imgStyle.marginTop" |            [style.margin-top]="imgStyle.marginTop" | ||||||
|            class="decoration-list-preview"> |            class="decoration-list-preview"> | ||||||
|       <span (click)="delete(); $event.stopPropagation()" title="Löschen" class="glyphicon glyphicon-trash trash"></span> |       <span (click)="delete(); $event.stopPropagation()" matTooltip="Löschen" class="glyphicon glyphicon-trash trash"></span> | ||||||
|     </div> |     </div> | ||||||
|   </div> |   </div> | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
|  | @ -1,33 +1,22 @@ | ||||||
| <div class="select-list"> | <div class="select-list"> | ||||||
|   <div class="input-group list-header pull-left"> |   <cc-list-filter | ||||||
|     <div class="btn-group" (click)="filterDecorations()"> |     [filterButtons]="[{label: fraction.BLUFOR, value: 'BLUFOR'}, | ||||||
|       <label class="btn btn-success" [(ngModel)]="radioModel" btnRadio="BLUFOR" uncheckable>{{fraction.BLUFOR}}</label> |                       {label: fraction.OPFOR, value: 'OPFOR'}, | ||||||
|       <label class="btn btn-success" [(ngModel)]="radioModel" btnRadio="OPFOR" uncheckable>{{fraction.OPFOR}}</label> |                       {label: 'Global', value: 'GLOBAL'}]" | ||||||
|       <label class="btn btn-success" [(ngModel)]="radioModel" btnRadio="GLOBAL" uncheckable>Global</label> |     [addButton]="{svgIcon: 'add', tooltip: 'Neue Auszeichnung hinzufügen'}" | ||||||
|     </div> |     (executeSearch)="filterDecorations($event)" | ||||||
|     <a class="pull-right btn btn-success" (click)="openNewDecorationForm()">+</a> |     (openAddFrom)="openNewDecorationForm()"> | ||||||
|   </div> |   </cc-list-filter> | ||||||
| 
 | 
 | ||||||
|   <div class="input-group list-header"> |   <cc-list-search [searchTerm]="searchTerm" | ||||||
|     <input id="search-tasks" |                   (searchTermStream)="initObservable($event)" | ||||||
|            type="text" #query class="form-control" |                   (executeSearch)="filterDecorations()"> | ||||||
|            (keyup.enter)="filterDecorations()" |   </cc-list-search> | ||||||
|            [formControl]="searchTerm"> |  | ||||||
|     <span class="input-group-btn"> |  | ||||||
|       <button class="btn btn-default" type="button" |  | ||||||
|               (click)="filterDecorations()"> |  | ||||||
|         Suchen |  | ||||||
|       </button> |  | ||||||
|     </span> |  | ||||||
|   </div> |  | ||||||
| 
 |  | ||||||
|   <div> |  | ||||||
|     <decoration-item *ngFor="let decoration of decorations$ | async" |  | ||||||
|                      [decoration]="decoration" |  | ||||||
|                      (decorationDelete)="deleteDecoration(decoration)" |  | ||||||
|                      (decorationSelected)="selectDecoration($event)" |  | ||||||
|                      [selected]="decoration._id == selectedDecorationId"> |  | ||||||
|     </decoration-item> |  | ||||||
|   </div> |  | ||||||
| 
 | 
 | ||||||
|  |   <decoration-item *ngFor="let decoration of decorations$ | async" | ||||||
|  |                    [decoration]="decoration" | ||||||
|  |                    (decorationDelete)="deleteDecoration(decoration)" | ||||||
|  |                    (decorationSelected)="selectDecoration($event)" | ||||||
|  |                    [selected]="decoration._id == selectedDecorationId"> | ||||||
|  |   </decoration-item> | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
|  | @ -1,5 +1,4 @@ | ||||||
| import {Component, OnInit} from '@angular/core'; | import {Component, OnInit} from '@angular/core'; | ||||||
| import {Location} from '@angular/common'; |  | ||||||
| 
 | 
 | ||||||
| import {FormControl} from '@angular/forms'; | import {FormControl} from '@angular/forms'; | ||||||
| import {ActivatedRoute, Router} from '@angular/router'; | import {ActivatedRoute, Router} from '@angular/router'; | ||||||
|  | @ -7,9 +6,11 @@ import {Observable} from 'rxjs/Observable'; | ||||||
| import {Decoration} from '../../models/model-interfaces'; | import {Decoration} from '../../models/model-interfaces'; | ||||||
| import {DecorationService} from '../../services/army-management/decoration.service'; | import {DecorationService} from '../../services/army-management/decoration.service'; | ||||||
| import {Fraction} from '../../utils/fraction.enum'; | import {Fraction} from '../../utils/fraction.enum'; | ||||||
|  | import {MatButtonToggleGroup} from '@angular/material'; | ||||||
|  | import {UIHelpers} from '../../utils/global.helpers'; | ||||||
| 
 | 
 | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'decoration-list', |   selector: 'cc-decoration-list', | ||||||
|   templateUrl: './decoration-list.component.html', |   templateUrl: './decoration-list.component.html', | ||||||
|   styleUrls: ['./decoration-list.component.css', '../../style/select-list.css'] |   styleUrls: ['./decoration-list.component.css', '../../style/select-list.css'] | ||||||
| }) | }) | ||||||
|  | @ -21,28 +22,21 @@ export class DecorationListComponent implements OnInit { | ||||||
| 
 | 
 | ||||||
|   searchTerm = new FormControl(); |   searchTerm = new FormControl(); | ||||||
| 
 | 
 | ||||||
|   public radioModel: string; |   radioModel = ''; | ||||||
| 
 | 
 | ||||||
|   readonly fraction = Fraction; |   readonly fraction = Fraction; | ||||||
| 
 | 
 | ||||||
|   constructor(private decorationService: DecorationService, |   constructor(private decorationService: DecorationService, | ||||||
|               private router: Router, |               private router: Router, | ||||||
|               private route: ActivatedRoute, |               private route: ActivatedRoute) { | ||||||
|               private location: Location) { |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   ngOnInit() { |   ngOnInit() { | ||||||
|     this.decorations$ = this.decorationService.decorations$; |     this.decorations$ = this.decorationService.decorations$; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|     const paramsStream = this.route.queryParams |   initObservable(observables: any) { | ||||||
|                              .map(params => decodeURI(params['query'] || '')) |     Observable.merge(observables.params as Observable<string>, observables.searchTerm) | ||||||
|                              .do(query => this.searchTerm.setValue(query)); |  | ||||||
| 
 |  | ||||||
|     const searchTermStream = this.searchTerm.valueChanges |  | ||||||
|                                  .debounceTime(400) |  | ||||||
|                                  .do(query => this.adjustBrowserUrl(query)); |  | ||||||
| 
 |  | ||||||
|     Observable.merge(paramsStream, searchTermStream) |  | ||||||
|               .distinctUntilChanged() |               .distinctUntilChanged() | ||||||
|               .switchMap(query => this.decorationService.findDecorations(query, this.radioModel)) |               .switchMap(query => this.decorationService.findDecorations(query, this.radioModel)) | ||||||
|               .subscribe(); |               .subscribe(); | ||||||
|  | @ -73,15 +67,8 @@ export class DecorationListComponent implements OnInit { | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   filterDecorations() { |   filterDecorations(group?: MatButtonToggleGroup) { | ||||||
|  |     this.radioModel = UIHelpers.toggleReleaseButton(this.radioModel, group); | ||||||
|     this.decorations$ = this.decorationService.findDecorations(this.searchTerm.value, this.radioModel); |     this.decorations$ = this.decorationService.findDecorations(this.searchTerm.value, this.radioModel); | ||||||
|   } |   } | ||||||
| 
 |  | ||||||
|   adjustBrowserUrl(queryString = '') { |  | ||||||
|     const absoluteUrl = this.location.path().split('?')[0]; |  | ||||||
|     const queryPart = queryString !== '' ? `query=${queryString}` : ''; |  | ||||||
| 
 |  | ||||||
|     this.location.replaceState(absoluteUrl, queryPart); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1 +0,0 @@ | ||||||
| <router-outlet></router-outlet> |  | ||||||
|  | @ -1,11 +0,0 @@ | ||||||
| import {Component} from '@angular/core'; |  | ||||||
| 
 |  | ||||||
| @Component({ |  | ||||||
|   selector: 'cc-decorations', |  | ||||||
|   templateUrl: './decoration.component.html', |  | ||||||
|   styleUrls: ['./decoration.component.css'] |  | ||||||
| }) |  | ||||||
| export class DecorationComponent { |  | ||||||
|   constructor() { |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  | @ -4,11 +4,10 @@ import {CommonModule} from '@angular/common'; | ||||||
| import {DecorationStore} from '../services/stores/decoration.store'; | import {DecorationStore} from '../services/stores/decoration.store'; | ||||||
| import {DecorationService} from '../services/army-management/decoration.service'; | import {DecorationService} from '../services/army-management/decoration.service'; | ||||||
| import {NgModule} from '@angular/core'; | import {NgModule} from '@angular/core'; | ||||||
| import {ButtonsModule} from 'ngx-bootstrap'; |  | ||||||
| 
 | 
 | ||||||
| @NgModule({ | @NgModule({ | ||||||
|   declarations: decorationsRoutingComponents, |   declarations: decorationsRoutingComponents, | ||||||
|   imports: [CommonModule, SharedModule, ButtonsModule.forRoot(), decorationRoutesModule], |   imports: [CommonModule, SharedModule, decorationRoutesModule], | ||||||
|   providers: [DecorationStore, DecorationService] |   providers: [DecorationStore, DecorationService] | ||||||
| }) | }) | ||||||
| export class DecorationsModule { | export class DecorationsModule { | ||||||
|  |  | ||||||
|  | @ -1,19 +1,15 @@ | ||||||
| import {RouterModule, Routes} from '@angular/router'; | import {RouterModule, Routes} from '@angular/router'; | ||||||
| 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 {EditDecorationComponent} from './edit-decoration/edit-decoration.component'; | ||||||
| import {ModuleWithProviders} from '@angular/core'; | import {ModuleWithProviders} from '@angular/core'; | ||||||
| import {DecorationItemComponent} from './decoration-list/decoration-item.component'; | import {DecorationItemComponent} from './decoration-list/decoration-item.component'; | ||||||
| 
 | 
 | ||||||
| export const decorationsRoutes: Routes = [{ | export const decorationsRoutes: Routes = [ | ||||||
|   path: '', component: DecorationComponent, |   { | ||||||
|   children: [ |     path: '', | ||||||
|     { |     component: DecorationListComponent, | ||||||
|       path: '', |     outlet: 'left' | ||||||
|       component: DecorationListComponent |   }, | ||||||
|     } |  | ||||||
|   ] |  | ||||||
| }, |  | ||||||
|   { |   { | ||||||
|     path: 'new', |     path: 'new', | ||||||
|     component: EditDecorationComponent, |     component: EditDecorationComponent, | ||||||
|  | @ -27,6 +23,5 @@ export const decorationsRoutes: Routes = [{ | ||||||
| 
 | 
 | ||||||
| export const decorationRoutesModule: ModuleWithProviders = RouterModule.forChild(decorationsRoutes); | export const decorationRoutesModule: ModuleWithProviders = RouterModule.forChild(decorationsRoutes); | ||||||
| 
 | 
 | ||||||
| export const decorationsRoutingComponents = [DecorationItemComponent, DecorationComponent, DecorationListComponent, | export const decorationsRoutingComponents = [DecorationItemComponent, DecorationListComponent, EditDecorationComponent]; | ||||||
|   EditDecorationComponent]; |  | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| <form #form="ngForm" class="overview"> | <form #form="ngForm" (keydown.enter)="$event.preventDefault()" class="overview"> | ||||||
|   <h3 *ngIf="decoration._id">Auszeichnung editieren</h3> |   <h3 *ngIf="decoration._id">Auszeichnung editieren</h3> | ||||||
|   <h3 *ngIf="!decoration._id">Neue Auszeichnung hinzufügen</h3> |   <h3 *ngIf="!decoration._id">Neue Auszeichnung hinzufügen</h3> | ||||||
| 
 | 
 | ||||||
|  | @ -70,16 +70,10 @@ | ||||||
|   </button> |   </button> | ||||||
| 
 | 
 | ||||||
|   <button id="save" |   <button id="save" | ||||||
|  |           type="submit" | ||||||
|           (click)="saveDecoration(fileInput)" |           (click)="saveDecoration(fileInput)" | ||||||
|           class="btn btn-default" |           class="btn btn-default" | ||||||
|           [disabled]="!form.valid"> |           [disabled]="!form.valid"> | ||||||
|     Bestätigen |     Bestätigen | ||||||
|   </button> |   </button> | ||||||
| 
 |  | ||||||
|   <span *ngIf="showSuccessLabel" |  | ||||||
|         class="label label-success label-small" |  | ||||||
|         style="margin-left: inherit"> |  | ||||||
|         Erfolgreich gespeichert |  | ||||||
|   </span> |  | ||||||
| 
 |  | ||||||
| </form> | </form> | ||||||
|  |  | ||||||
|  | @ -5,6 +5,8 @@ import {Decoration} from '../../models/model-interfaces'; | ||||||
| import {DecorationService} from '../../services/army-management/decoration.service'; | import {DecorationService} from '../../services/army-management/decoration.service'; | ||||||
| import {Subscription} from 'rxjs/Subscription'; | import {Subscription} from 'rxjs/Subscription'; | ||||||
| import {Fraction} from '../../utils/fraction.enum'; | import {Fraction} from '../../utils/fraction.enum'; | ||||||
|  | import {SnackBarService} from '../../services/user-interface/snack-bar/snack-bar.service'; | ||||||
|  | import {Message} from '../../i18n/de.messages'; | ||||||
| 
 | 
 | ||||||
| @Component({ | @Component({ | ||||||
|   templateUrl: './edit-decoration.component.html', |   templateUrl: './edit-decoration.component.html', | ||||||
|  | @ -22,15 +24,14 @@ export class EditDecorationComponent implements OnInit, OnDestroy { | ||||||
| 
 | 
 | ||||||
|   imagePreviewSrc; |   imagePreviewSrc; | ||||||
| 
 | 
 | ||||||
|   showSuccessLabel = false; |  | ||||||
| 
 |  | ||||||
|   @ViewChild(NgForm) form: NgForm; |   @ViewChild(NgForm) form: NgForm; | ||||||
| 
 | 
 | ||||||
|   readonly fraction = Fraction; |   readonly fraction = Fraction; | ||||||
| 
 | 
 | ||||||
|   constructor(private route: ActivatedRoute, |   constructor(private route: ActivatedRoute, | ||||||
|               private router: Router, |               private router: Router, | ||||||
|               private decorationService: DecorationService) { |               private decorationService: DecorationService, | ||||||
|  |               private snackBarService: SnackBarService) { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   ngOnInit() { |   ngOnInit() { | ||||||
|  | @ -81,10 +82,7 @@ export class EditDecorationComponent implements OnInit, OnDestroy { | ||||||
|               this.imagePreviewSrc = 'resource/decoration/' + this.decoration._id + '.png?' + Date.now(); |               this.imagePreviewSrc = 'resource/decoration/' + this.decoration._id + '.png?' + Date.now(); | ||||||
|             }, 300); |             }, 300); | ||||||
|             fileInput.value = ''; |             fileInput.value = ''; | ||||||
|             this.showSuccessLabel = true; |             this.snackBarService.showSuccess(Message.SUCCESS_SAVE); | ||||||
|             setTimeout(() => { |  | ||||||
|               this.showSuccessLabel = false; |  | ||||||
|             }, 2000); |  | ||||||
|           }); |           }); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -1,9 +0,0 @@ | ||||||
| export const CSSHelpers = { |  | ||||||
|   getBackgroundCSS: (imageUrl) => { |  | ||||||
|     return 'background-image: url(' + imageUrl + ');' + |  | ||||||
|       'background-size: cover;' + |  | ||||||
|       'background-attachment: fixed;' + |  | ||||||
|       'background-position: center;' + |  | ||||||
|       'background-repeat: no-repeat;'; |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  | @ -0,0 +1,5 @@ | ||||||
|  | export enum Message { | ||||||
|  |   SIGN_UP_SUCCESS = 'Account erfolgreich erstellt', | ||||||
|  |   SUCCESS_SAVE = 'Erfolgreich gespeichert', | ||||||
|  |   DUPLICATED_NAME_ERR = 'Benutzername existiert bereits', | ||||||
|  | } | ||||||
|  | @ -4,6 +4,14 @@ | ||||||
|   margin: 0 auto; |   margin: 0 auto; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .form-signin > .row { | ||||||
|  |   width: 400px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .form-signin-heading { | ||||||
|  |   text-align: center; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .form-signin .form-signin-heading, .form-signin .checkbox, #inputEmail { | .form-signin .form-signin-heading, .form-signin .checkbox, #inputEmail { | ||||||
|   margin-bottom: 10px; |   margin-bottom: 10px; | ||||||
| } | } | ||||||
|  | @ -38,39 +46,8 @@ | ||||||
|   border-top-right-radius: 0; |   border-top-right-radius: 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .account-wall { | button { | ||||||
|   margin-top: 20px; |   width: 100%; | ||||||
|   padding: 40px 0px 20px 0px; |  | ||||||
|   background-color: #f7f7f7; |  | ||||||
|   -moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); |  | ||||||
|   -webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); |  | ||||||
|   box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .login-title { |  | ||||||
|   color: #555; |  | ||||||
|   font-size: 18px; |  | ||||||
|   font-weight: 400; |  | ||||||
|   display: block; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .profile-img { |  | ||||||
|   width: 96px; |  | ||||||
|   height: 96px; |  | ||||||
|   margin: 0 auto 10px; |  | ||||||
|   display: block; |  | ||||||
|   -moz-border-radius: 50%; |  | ||||||
|   -webkit-border-radius: 50%; |  | ||||||
|   border-radius: 50%; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .need-help { |  | ||||||
|   margin-top: 10px; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .new-account { |  | ||||||
|   display: block; |  | ||||||
|   margin-top: 10px; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Loading Animation */ | /* Loading Animation */ | ||||||
|  |  | ||||||
|  | @ -1,7 +1,6 @@ | ||||||
| <form class="form-signin" (ngSubmit)="login(userName.value, password.value)"> | <form class="form-signin" (ngSubmit)="login(userName.value, password.value)"> | ||||||
| 
 |   <div class="row"> | ||||||
|   <div class="row" style="position: absolute;width: 400px;left: 40%;"> |     <h2 class="form-signin-heading">Login</h2> | ||||||
|     <h2 style="text-align: center;" class="form-signin-heading">Anmelden</h2> |  | ||||||
| 
 | 
 | ||||||
|     <label for="inputEmail" class="sr-only">Benutzername</label> |     <label for="inputEmail" class="sr-only">Benutzername</label> | ||||||
|     <input #userName id="inputEmail" class="form-control" placeholder="Benutzername" required="" autofocus=""> |     <input #userName id="inputEmail" class="form-control" placeholder="Benutzername" required="" autofocus=""> | ||||||
|  | @ -9,19 +8,12 @@ | ||||||
|     <label for="inputPassword" class="sr-only">Passwort</label> |     <label for="inputPassword" class="sr-only">Passwort</label> | ||||||
|     <input #password type="password" id="inputPassword" class="form-control" placeholder="Passwort" required=""> |     <input #password type="password" id="inputPassword" class="form-control" placeholder="Passwort" required=""> | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     <div class="form-group"> |     <div class="form-group"> | ||||||
|       <button type="submit" class="btn btn-lg btn-block btn-primary"> |       <button mat-stroked-button type="submit"> | ||||||
|         <span *ngIf="!loading">Anmelden</span> |         <span *ngIf="!loading">Anmelden</span> | ||||||
|         <span *ngIf="loading" class="glyphicon glyphicon-refresh glyphicon-refresh-animate"></span> |         <span *ngIf="loading" class="glyphicon glyphicon-refresh glyphicon-refresh-animate"></span> | ||||||
|       </button> |       </button> | ||||||
|       <span *ngIf="showErrorLabel" |  | ||||||
|             class="center-block label label-danger" style="font-size: medium; padding: 2px; margin-top: 2px"> |  | ||||||
|         {{error}} |  | ||||||
|       </span> |  | ||||||
|     </div> |     </div> | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|   </div> |   </div> | ||||||
| </form> | </form> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2,6 +2,7 @@ import {Component, OnInit} from '@angular/core'; | ||||||
| import {Router} from '@angular/router'; | import {Router} from '@angular/router'; | ||||||
| import {LoginService} from '../services/app-user-service/login-service'; | import {LoginService} from '../services/app-user-service/login-service'; | ||||||
| import {RouteConfig} from '../app.config'; | import {RouteConfig} from '../app.config'; | ||||||
|  | import {SnackBarService} from '../services/user-interface/snack-bar/snack-bar.service'; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @Component({ | @Component({ | ||||||
|  | @ -12,16 +13,13 @@ import {RouteConfig} from '../app.config'; | ||||||
| 
 | 
 | ||||||
| export class LoginComponent implements OnInit { | export class LoginComponent implements OnInit { | ||||||
| 
 | 
 | ||||||
|   showErrorLabel = false; |  | ||||||
| 
 |  | ||||||
|   error: string; |  | ||||||
| 
 |  | ||||||
|   loading = false; |   loading = false; | ||||||
| 
 | 
 | ||||||
|   returnUrl: string; |   returnUrl: string; | ||||||
| 
 | 
 | ||||||
|   constructor(private router: Router, |   constructor(private router: Router, | ||||||
|               private loginService: LoginService) { |               private loginService: LoginService, | ||||||
|  |               private snackBarService: SnackBarService) { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   ngOnInit() { |   ngOnInit() { | ||||||
|  | @ -40,11 +38,7 @@ export class LoginComponent implements OnInit { | ||||||
|               this.router.navigate([this.returnUrl]); |               this.router.navigate([this.returnUrl]); | ||||||
|             }, |             }, | ||||||
|             error => { |             error => { | ||||||
|               this.error = error._body; |               this.snackBarService.showError(error._body, 15000); | ||||||
|               this.showErrorLabel = true; |  | ||||||
|               setTimeout(() => { |  | ||||||
|                 this.showErrorLabel = false; |  | ||||||
|               }, 4000); |  | ||||||
|               this.loading = false; |               this.loading = false; | ||||||
|             }); |             }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -1,11 +1,11 @@ | ||||||
| <form class="form-signin" (ngSubmit)="login(userName.value, password.value, secret.value)"> | <form class="form-signin" (ngSubmit)="login(userName.value, password.value, secret.value)"> | ||||||
| 
 | 
 | ||||||
|   <div class="row"> |   <div class="row" style="position: absolute;width: 500px;left: 40%;"> | ||||||
|     <h2 style="text-align: center;" class="form-signin-heading">Registrieren</h2> |     <h2 style="text-align: center;" class="form-signin-heading">Registrieren</h2> | ||||||
| 
 | 
 | ||||||
|     <p>Dieses Formular nur ausfüllen wenn du einer <b>HL</b> angehörst oder <b>SQL</b> bist. Dabei den Nutzernamen aus |     <p>Dieses Formular nur ausfüllen wenn du einer <b>HL</b> angehörst oder <b>SQL</b> bist. Dabei den Nutzernamen aus | ||||||
|       dem OPT Forum verwenden! |       dem OPT Forum verwenden! | ||||||
|       Im Forum eine Nachricht an <a href="https://operation-pandora.com/dashboard/index.php?conversation-add/&userID=9" |       Im Forum eine Nachricht an <a href="https://www.opt4.net/dashboard/index.php?conversation-add/&userID=9" | ||||||
|                                     target="_blank">HardiReady</a> |                                     target="_blank">HardiReady</a> | ||||||
|       senden, in welcher der 'geheime Text' steht, den du bei der Registrierung nutzt.<br> |       senden, in welcher der 'geheime Text' steht, den du bei der Registrierung nutzt.<br> | ||||||
|       Dabei kann es sich um irgend eine willkürliche Zeichenfolge oder einen Satz handeln - dient nur dem Abgleich. |       Dabei kann es sich um irgend eine willkürliche Zeichenfolge oder einen Satz handeln - dient nur dem Abgleich. | ||||||
|  | @ -21,28 +21,12 @@ | ||||||
|     <input #secret type="text" id="inputSecret" class="form-control" placeholder="Geheimer Text für PN Abgleich" |     <input #secret type="text" id="inputSecret" class="form-control" placeholder="Geheimer Text für PN Abgleich" | ||||||
|            required=""> |            required=""> | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     <div class="form-group"> |     <div class="form-group"> | ||||||
|       <button type="submit" class="btn btn-lg btn-block btn-primary"> |       <button type="submit" class="btn btn-lg btn-block btn-primary"> | ||||||
|         <span *ngIf="!loading">Registrieren</span> |         <span *ngIf="!loading">Registrieren</span> | ||||||
|         <span *ngIf="loading" class="glyphicon glyphicon-refresh glyphicon-refresh-animate"></span> |         <span *ngIf="loading" class="glyphicon glyphicon-refresh glyphicon-refresh-animate"></span> | ||||||
|       </button> |       </button> | ||||||
|       <h3 class="text-center"> |  | ||||||
|         <span *ngIf="showSuccessLabel" |  | ||||||
|               class="label label-success label-small" |  | ||||||
|               style="margin-left: inherit"> |  | ||||||
|           Account erfolgreich erstellt |  | ||||||
|         </span> |  | ||||||
|       </h3> |  | ||||||
|       <span *ngIf="showErrorLabel" |  | ||||||
|             class="center-block label label-danger" style="font-size: medium; padding: 2px; margin-top: 2px"> |  | ||||||
|         {{error}} |  | ||||||
|     </span> |  | ||||||
|     </div> |     </div> | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|   </div> |   </div> | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| </form> | </form> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2,6 +2,8 @@ import {Component, OnInit} from '@angular/core'; | ||||||
| import {ActivatedRoute, Router} from '@angular/router'; | import {ActivatedRoute, Router} from '@angular/router'; | ||||||
| import {LoginService} from '../services/app-user-service/login-service'; | import {LoginService} from '../services/app-user-service/login-service'; | ||||||
| import {RouteConfig} from '../app.config'; | import {RouteConfig} from '../app.config'; | ||||||
|  | import {Message} from '../i18n/de.messages'; | ||||||
|  | import {SnackBarService} from '../services/user-interface/snack-bar/snack-bar.service'; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @Component({ | @Component({ | ||||||
|  | @ -12,19 +14,14 @@ import {RouteConfig} from '../app.config'; | ||||||
| 
 | 
 | ||||||
| export class SignupComponent implements OnInit { | export class SignupComponent implements OnInit { | ||||||
| 
 | 
 | ||||||
|   showErrorLabel = false; |  | ||||||
| 
 |  | ||||||
|   showSuccessLabel = false; |  | ||||||
| 
 |  | ||||||
|   error: string; |  | ||||||
| 
 |  | ||||||
|   loading = false; |   loading = false; | ||||||
| 
 | 
 | ||||||
|   returnUrl: string; |   returnUrl: string; | ||||||
| 
 | 
 | ||||||
|   constructor(private route: ActivatedRoute, |   constructor(private route: ActivatedRoute, | ||||||
|               private router: Router, |               private router: Router, | ||||||
|               private loginService: LoginService) { |               private loginService: LoginService, | ||||||
|  |               private snackBarService: SnackBarService) { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   ngOnInit() { |   ngOnInit() { | ||||||
|  | @ -41,15 +38,11 @@ export class SignupComponent implements OnInit { | ||||||
|           .subscribe( |           .subscribe( | ||||||
|             data => { |             data => { | ||||||
|               this.loading = false; |               this.loading = false; | ||||||
|               this.showSuccessLabel = true; |               this.snackBarService.showSuccess(Message.SIGN_UP_SUCCESS); | ||||||
|             }, |             }, | ||||||
|             error => { |             error => { | ||||||
|               this.error = error; |  | ||||||
|               this.showErrorLabel = true; |  | ||||||
|               setTimeout(() => { |  | ||||||
|                 this.showErrorLabel = false; |  | ||||||
|               }, 4000); |  | ||||||
|               this.loading = false; |               this.loading = false; | ||||||
|  |               this.snackBarService.showError(error, 10000); | ||||||
|             }); |             }); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,94 @@ | ||||||
|  | :host { | ||||||
|  |   display: flow-root; | ||||||
|  |   height: 100%; | ||||||
|  |   width: 100%; | ||||||
|  |   margin-top: -23px; | ||||||
|  |   padding-top: 23px; | ||||||
|  |   padding-bottom: 23px; | ||||||
|  |   background-image: url('../../../assets/bg.jpg'); | ||||||
|  |   background-size: cover; | ||||||
|  |   background-attachment: fixed; | ||||||
|  |   background-position: top; | ||||||
|  |   background-repeat: no-repeat; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | h1 { | ||||||
|  |   margin-bottom: 30px; | ||||||
|  |   text-align: center; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .decoration-overview-container { | ||||||
|  |   position: relative; | ||||||
|  |   margin: auto 140px 30px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :host /deep/ .mat-tab-header { | ||||||
|  |   background-color: #222222; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :host /deep/ .mat-tab-label { | ||||||
|  |   font-size: 16px; | ||||||
|  |   color: #dadada; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :host /deep/ .mat-tab-group.mat-primary .mat-ink-bar { | ||||||
|  |   background-color: #ffd740; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :host /deep/ .mat-tab-group.mat-primary .mat-tab-label:not(.mat-tab-disabled):focus { | ||||||
|  |   background-color: #222222; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :host /deep/ div.mat-tab-body-wrapper { | ||||||
|  |   box-shadow: #666666 2px 2px 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :host /deep/ .mat-tab-body-content { | ||||||
|  |   background-color: rgba(255, 255, 255, 0.35); | ||||||
|  |   height: calc(100vh - 241px); | ||||||
|  |   min-width: 560px; | ||||||
|  |   padding: 1em 1.5em; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fraction-side-bar { | ||||||
|  |   float: left; | ||||||
|  |   width: 10%; | ||||||
|  |   min-width: 100px; | ||||||
|  |   height: calc(100vh - 192px); | ||||||
|  |   background: #222222;; | ||||||
|  |   box-shadow: #666666 2px 2px 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fraction-side-bar > div { | ||||||
|  |   text-align: center; | ||||||
|  |   padding: 12px 25px; | ||||||
|  |   margin-bottom: 15px; | ||||||
|  |   font-size: 16px; | ||||||
|  |   color: #666; | ||||||
|  |   cursor: pointer; | ||||||
|  |   border-top: 1px solid #666666; | ||||||
|  |   border-bottom: 1px solid #666666; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fraction-side-bar > div:first-child { | ||||||
|  |   margin-top: 100%; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fraction-side-bar > div.active { | ||||||
|  |   background-color: #080808; | ||||||
|  |   color: white; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* SCROLL BAR */ | ||||||
|  | 
 | ||||||
|  | :host /deep/ .mat-tab-body-content::-webkit-scrollbar { | ||||||
|  |   width: 12px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :host /deep/ .mat-tab-body-content::-webkit-scrollbar-track { | ||||||
|  |   border-left: 1px solid #080808; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :host /deep/ .mat-tab-body-content::-webkit-scrollbar-thumb { | ||||||
|  |   background: #222222; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,28 @@ | ||||||
|  | <div class="decoration-overview-container"> | ||||||
|  |   <h1>Übersicht über alle Auszeichnungen</h1> | ||||||
|  | 
 | ||||||
|  |   <div class="fraction-side-bar"> | ||||||
|  |     <div [ngClass]="{active: active === 'BLUFOR'}" (click)="switchFraction('BLUFOR')">{{fraction.BLUFOR}}</div> | ||||||
|  |     <div [ngClass]="{active: active === 'OPFOR'}" (click)="switchFraction('OPFOR')">{{fraction.OPFOR}}</div> | ||||||
|  |     <div [ngClass]="{active: active === 'GLOBAL'}" (click)="switchFraction('GLOBAL')">GLOBAL</div> | ||||||
|  |   </div> | ||||||
|  | 
 | ||||||
|  |   <mat-tab-group [selectedIndex]="selectedType" (selectedIndexChange)="switchTab($event)"> | ||||||
|  |     <mat-tab label="Orden"> | ||||||
|  |       <ng-template matTabContent> | ||||||
|  |         <cc-decoration-panel *ngFor="let decoration of medals" | ||||||
|  |                              [decoration]="decoration" | ||||||
|  |                              (select)="select($event)"> | ||||||
|  |         </cc-decoration-panel> | ||||||
|  |       </ng-template> | ||||||
|  |     </mat-tab> | ||||||
|  |     <mat-tab label="Ordensbänder"> | ||||||
|  |       <ng-template matTabContent> | ||||||
|  |         <cc-decoration-panel *ngFor="let decoration of ribbons" | ||||||
|  |                              [decoration]="decoration" | ||||||
|  |                              (select)="select($event)"> | ||||||
|  |         </cc-decoration-panel> | ||||||
|  |       </ng-template> | ||||||
|  |     </mat-tab> | ||||||
|  |   </mat-tab-group> | ||||||
|  | </div> | ||||||
|  | @ -0,0 +1,84 @@ | ||||||
|  | import {Component, OnInit} from '@angular/core'; | ||||||
|  | import {ActivatedRoute, Router} from '@angular/router'; | ||||||
|  | 
 | ||||||
|  | import {Fraction} from '../../utils/fraction.enum'; | ||||||
|  | import {Decoration} from '../../models/model-interfaces'; | ||||||
|  | import {DecorationService} from '../../services/army-management/decoration.service'; | ||||||
|  | import {MatBottomSheet} from '@angular/material'; | ||||||
|  | import {UserListSheetComponent} from '../user-list-sheet/user-list-sheet.component'; | ||||||
|  | import {Location} from '@angular/common'; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @Component({ | ||||||
|  |   selector: 'cc-decoration-overview', | ||||||
|  |   templateUrl: './decoration-overview.component.html', | ||||||
|  |   styleUrls: ['./decoration-overview.component.css'] | ||||||
|  | }) | ||||||
|  | export class DecorationOverviewComponent implements OnInit { | ||||||
|  | 
 | ||||||
|  |   decorations: Decoration[]; | ||||||
|  | 
 | ||||||
|  |   medals: Decoration[]; | ||||||
|  | 
 | ||||||
|  |   ribbons: Decoration[]; | ||||||
|  | 
 | ||||||
|  |   active: string; | ||||||
|  | 
 | ||||||
|  |   selectedType = 0; | ||||||
|  | 
 | ||||||
|  |   readonly fraction = Fraction; | ||||||
|  | 
 | ||||||
|  |   constructor(private router: Router, | ||||||
|  |               private route: ActivatedRoute, | ||||||
|  |               private location: Location, | ||||||
|  |               private decorationService: DecorationService, | ||||||
|  |               private bottomSheet: MatBottomSheet) { | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   ngOnInit() { | ||||||
|  |     // init decoration data
 | ||||||
|  |     this.decorationService.findDecorations() | ||||||
|  |         .subscribe(decorations => { | ||||||
|  |           this.decorations = decorations; | ||||||
|  |           const queryParams = this.route.snapshot.queryParams; | ||||||
|  |           if (queryParams.type < 2) { | ||||||
|  |             this.selectedType = queryParams.type; | ||||||
|  |           } | ||||||
|  | 
 | ||||||
|  |           const fract = queryParams.fraction; | ||||||
|  |           if (fract && (fract === 'BLUFOR' || fract === 'OPFOR' || fract === 'GLOBAL')) { | ||||||
|  |             this.switchFraction(queryParams.fraction); | ||||||
|  |           } else { | ||||||
|  |             this.switchFraction('BLUFOR'); | ||||||
|  |           } | ||||||
|  |         }); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   switchFraction(value: any) { | ||||||
|  |     this.medals = this.decorations.filter(d => d.fraction === value && d.isMedal); | ||||||
|  |     this.ribbons = this.decorations.filter(d => d.fraction === value && !d.isMedal); | ||||||
|  |     this.active = value; | ||||||
|  |     this.adjustBrowserUrl(value) | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   switchTab(tabIndex) { | ||||||
|  |     this.selectedType = tabIndex; | ||||||
|  |     this.adjustBrowserUrl(this.active) | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   select(decoration: Decoration) { | ||||||
|  |     this.bottomSheet.open(UserListSheetComponent, {data: {decoration: decoration}}); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   adjustBrowserUrl(fractionKey = '') { | ||||||
|  |     const absoluteUrl = this.location.path().split('?')[0]; | ||||||
|  |     if (fractionKey === 'BLUFOR' && this.selectedType === 0) { | ||||||
|  |       this.location.replaceState(absoluteUrl); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     const queryPart = fractionKey !== '' ? 'fraction='.concat(fractionKey) | ||||||
|  |                                                       .concat('&type=' + this.selectedType) : 'type=0'; | ||||||
|  | 
 | ||||||
|  |     this.location.replaceState(absoluteUrl, queryPart); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,67 @@ | ||||||
|  | .decoration-card { | ||||||
|  |   background: rgba(255, 255, 255, 0.87); | ||||||
|  |   width: 213px; | ||||||
|  |   height: 258px; | ||||||
|  |   margin: 7px 12px; | ||||||
|  |   padding: 0; | ||||||
|  |   overflow: hidden; | ||||||
|  |   float: left; | ||||||
|  |   cursor: pointer; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .decoration-card:hover { | ||||||
|  |   background: #ffffff; | ||||||
|  |   overflow: visible; | ||||||
|  |   box-shadow: 0 0 18px 2px #666666; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .decoration-description { | ||||||
|  |   text-align: left; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .decoration-card:hover .decoration-description { | ||||||
|  |   background: #ffffff; | ||||||
|  |   position: relative; | ||||||
|  |   z-index: 5; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .image-head { | ||||||
|  |   height: 100px; | ||||||
|  |   text-align: center; | ||||||
|  |   padding: 12px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .decoration-card .mat-card-content > div { | ||||||
|  |   padding: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .decoration-card .mat-card-content > div:first-child { | ||||||
|  |   color: white; | ||||||
|  |   display: inherit; | ||||||
|  |   text-align: center; | ||||||
|  |   word-wrap: break-word; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | img.img-medal { | ||||||
|  |   height: 100%; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | img.img-ribbon { | ||||||
|  |   padding-top: 10%; | ||||||
|  |   width: 55%; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .gradient { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 2; | ||||||
|  |   right: 0; | ||||||
|  |   bottom: 0; | ||||||
|  |   left: 0; | ||||||
|  |   height: 24px; | ||||||
|  |   background: -moz-linear-gradient(top, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.84) 70%); | ||||||
|  |   background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(70%, rgba(255, 255, 255, 0.84))); | ||||||
|  |   background: -webkit-linear-gradient(top, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.84) 70%); | ||||||
|  |   background: -o-linear-gradient(top, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.84) 70%); | ||||||
|  |   background: -ms-linear-gradient(top, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.84) 70%); | ||||||
|  |   background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.84) 70%); | ||||||
|  | } | ||||||
|  | @ -0,0 +1,18 @@ | ||||||
|  | <mat-card class="decoration-card" (click)="selectDecoration()"> | ||||||
|  |   <div class="image-head"> | ||||||
|  |     <img src="resource/decoration/{{decoration._id}}.png" | ||||||
|  |          alt="{{decoration.name}}" | ||||||
|  |          [class]="decoration.isMedal ? 'img-medal' : 'img-ribbon'"> | ||||||
|  |   </div> | ||||||
|  |   <mat-card-content> | ||||||
|  |     <div [style.background]="decoration.fraction === 'BLUFOR' ? | ||||||
|  |     fraction.COLOR_BLUFOR : decoration.fraction === 'OPFOR' ? fraction.COLOR_OPFOR : '#666666'"> | ||||||
|  |       {{decoration.name}} | ||||||
|  |     </div> | ||||||
|  |     <div class="decoration-description"> | ||||||
|  |       {{decoration.description}} | ||||||
|  |     </div> | ||||||
|  |     <div class="gradient"> | ||||||
|  |     </div> | ||||||
|  |   </mat-card-content> | ||||||
|  | </mat-card> | ||||||
|  | @ -0,0 +1,23 @@ | ||||||
|  | import {Component, EventEmitter, Input, Output} from '@angular/core'; | ||||||
|  | 
 | ||||||
|  | import {Decoration} from '../../../models/model-interfaces'; | ||||||
|  | import {Fraction} from '../../../utils/fraction.enum'; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @Component({ | ||||||
|  |   selector: 'cc-decoration-panel', | ||||||
|  |   templateUrl: './decoration-panel.component.html', | ||||||
|  |   styleUrls: ['./decoration-panel.component.css'] | ||||||
|  | }) | ||||||
|  | export class DecorationPanelComponent { | ||||||
|  | 
 | ||||||
|  |   @Input() decoration: Decoration; | ||||||
|  | 
 | ||||||
|  |   @Output() select = new EventEmitter(); | ||||||
|  | 
 | ||||||
|  |   readonly fraction = Fraction; | ||||||
|  | 
 | ||||||
|  |   selectDecoration() { | ||||||
|  |     this.select.emit(this.decoration); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,23 @@ | ||||||
|  | import {NgModule} from '@angular/core'; | ||||||
|  | import {SharedModule} from '../shared.module'; | ||||||
|  | import {CommonModule} from '@angular/common'; | ||||||
|  | import {RankService} from '../services/army-management/rank.service'; | ||||||
|  | import {pubRouterModule, pubRoutingComponents} from './public.routing'; | ||||||
|  | import {DecorationService} from '../services/army-management/decoration.service'; | ||||||
|  | import {MatTableModule} from '@angular/material/table'; | ||||||
|  | import {MatCardModule} from '@angular/material/card'; | ||||||
|  | import {MatBottomSheetModule} from '@angular/material/bottom-sheet'; | ||||||
|  | import {MatListModule} from '@angular/material/list'; | ||||||
|  | import {MatTabsModule} from '@angular/material/tabs'; | ||||||
|  | import {UserListSheetComponent} from './user-list-sheet/user-list-sheet.component'; | ||||||
|  | 
 | ||||||
|  | @NgModule({ | ||||||
|  |   declarations: pubRoutingComponents, | ||||||
|  |   entryComponents: [UserListSheetComponent], | ||||||
|  |   imports: [CommonModule, SharedModule, MatTableModule, MatCardModule, MatBottomSheetModule, MatListModule, | ||||||
|  |     MatTabsModule, pubRouterModule], | ||||||
|  |   providers: [DecorationService, RankService] | ||||||
|  | }) | ||||||
|  | export class PublicModule { | ||||||
|  |   static routes = pubRouterModule; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,29 @@ | ||||||
|  | import {RouterModule, Routes} from '@angular/router'; | ||||||
|  | import {RankOverviewComponent} from './rank-overview/rank-overview.component'; | ||||||
|  | import {ModuleWithProviders} from '@angular/core'; | ||||||
|  | import {DecorationOverviewComponent} from './decoration-overview/decoration-overview.component'; | ||||||
|  | import {DecorationPanelComponent} from './decoration-overview/decoration-panel/decoration-panel.component'; | ||||||
|  | import {RankPanelComponent} from './rank-overview/rank-panel/rank-panel.component'; | ||||||
|  | import {UserListSheetComponent} from './user-list-sheet/user-list-sheet.component'; | ||||||
|  | 
 | ||||||
|  | export const publicRoutes: Routes = [ | ||||||
|  |   { | ||||||
|  |     path: '', | ||||||
|  |     children: [ | ||||||
|  |       { | ||||||
|  |         path: 'ranks', | ||||||
|  |         component: RankOverviewComponent, | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         path: 'decorations', | ||||||
|  |         component: DecorationOverviewComponent, | ||||||
|  |       }, | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | export const pubRouterModule: ModuleWithProviders = RouterModule.forChild(publicRoutes); | ||||||
|  | 
 | ||||||
|  | export const pubRoutingComponents = [RankOverviewComponent, DecorationOverviewComponent, DecorationPanelComponent, | ||||||
|  |   RankPanelComponent, UserListSheetComponent]; | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,49 @@ | ||||||
|  | :host { | ||||||
|  |   display: flow-root; | ||||||
|  |   height: 100%; | ||||||
|  |   min-height: 100vh; | ||||||
|  |   width: 100%; | ||||||
|  |   margin-top: -23px; | ||||||
|  |   padding-top: 23px; | ||||||
|  |   padding-bottom: 23px; | ||||||
|  |   background-image: url('../../../assets/bg.jpg'); | ||||||
|  |   background-size: cover; | ||||||
|  |   background-attachment: fixed; | ||||||
|  |   background-position: top; | ||||||
|  |   background-repeat: no-repeat; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | table { | ||||||
|  |   width: 100%; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :host /deep/ table.mat-table { | ||||||
|  |   background: rgba(255, 255, 255, 0.6); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :host /deep/ tr.mat-row:hover { | ||||||
|  |   background: #ffffff; | ||||||
|  |   cursor: pointer; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | td > img { | ||||||
|  |   height: 120px; | ||||||
|  |   padding: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | h1, h3 { | ||||||
|  |   text-align: center; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | h3 { | ||||||
|  |   font-weight: bolder; | ||||||
|  |   padding-bottom: 14px; | ||||||
|  |   padding-top: 11px; | ||||||
|  |   margin-bottom: 0; | ||||||
|  |   background: #222222; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .column-container { | ||||||
|  |   width: 48%; | ||||||
|  |   padding-bottom: 20px; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,43 @@ | ||||||
|  | <div style="width: 1000px; margin:auto; position: relative;"> | ||||||
|  |   <h1>Übersicht über alle Ränge</h1> | ||||||
|  | 
 | ||||||
|  |   <div class="column-container pull-left"> | ||||||
|  |     <h3 [style.color]="fraction.COLOR_BLUFOR">{{fraction.BLUFOR}}</h3> | ||||||
|  | 
 | ||||||
|  |     <table mat-table [dataSource]="ranksBlufor" class="mat-elevation-z8"> | ||||||
|  | 
 | ||||||
|  |       <ng-container matColumnDef="picture"> | ||||||
|  |         <th mat-header-cell *matHeaderCellDef> Rankabzeichen</th> | ||||||
|  |         <td mat-cell *matCellDef="let element"><img src="resource/rank/{{element._id}}.png"></td> | ||||||
|  |       </ng-container> | ||||||
|  | 
 | ||||||
|  |       <ng-container matColumnDef="name"> | ||||||
|  |         <th mat-header-cell *matHeaderCellDef> Name</th> | ||||||
|  |         <td mat-cell *matCellDef="let element"> {{element.name}}</td> | ||||||
|  |       </ng-container> | ||||||
|  | 
 | ||||||
|  |       <tr mat-row *matRowDef="let row; columns: displayedColumns;" (click)="selectRow(row)"></tr> | ||||||
|  |     </table> | ||||||
|  |   </div> | ||||||
|  | 
 | ||||||
|  |   <div class="column-container pull-right"> | ||||||
|  |     <h3 [style.color]="fraction.COLOR_OPFOR">{{fraction.OPFOR}}</h3> | ||||||
|  | 
 | ||||||
|  |     <table mat-table [dataSource]="ranksOpfor" class="pull-right mat-elevation-z8"> | ||||||
|  | 
 | ||||||
|  |       <ng-container matColumnDef="picture"> | ||||||
|  |         <th mat-header-cell *matHeaderCellDef> Rankabzeichen</th> | ||||||
|  |         <td mat-cell *matCellDef="let element"><img src="resource/rank/{{element._id}}.png"></td> | ||||||
|  |       </ng-container> | ||||||
|  | 
 | ||||||
|  |       <ng-container matColumnDef="name"> | ||||||
|  |         <th mat-header-cell *matHeaderCellDef> Name</th> | ||||||
|  |         <td mat-cell *matCellDef="let element">{{element.name}}</td> | ||||||
|  |       </ng-container> | ||||||
|  | 
 | ||||||
|  |       <tr mat-row *matRowDef="let row; columns: displayedColumns;" (click)="selectRow(row)"></tr> | ||||||
|  |     </table> | ||||||
|  |   </div> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | </div> | ||||||
|  | @ -0,0 +1,43 @@ | ||||||
|  | import {Component, OnInit} from '@angular/core'; | ||||||
|  | import {ActivatedRoute, Router} from '@angular/router'; | ||||||
|  | import {Fraction} from '../../utils/fraction.enum'; | ||||||
|  | import {Rank} from '../../models/model-interfaces'; | ||||||
|  | import {RankService} from '../../services/army-management/rank.service'; | ||||||
|  | import {MatBottomSheet} from '@angular/material'; | ||||||
|  | import {UserListSheetComponent} from '../user-list-sheet/user-list-sheet.component'; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @Component({ | ||||||
|  |   selector: 'cc-rank-overview', | ||||||
|  |   templateUrl: './rank-overview.component.html', | ||||||
|  |   styleUrls: ['./rank-overview.component.css'] | ||||||
|  | }) | ||||||
|  | export class RankOverviewComponent implements OnInit { | ||||||
|  | 
 | ||||||
|  |   ranksOpfor: Rank[]; | ||||||
|  | 
 | ||||||
|  |   ranksBlufor: Rank[]; | ||||||
|  | 
 | ||||||
|  |   displayedColumns: string[] = ['picture', 'name']; | ||||||
|  | 
 | ||||||
|  |   readonly fraction = Fraction; | ||||||
|  | 
 | ||||||
|  |   constructor(private router: Router, | ||||||
|  |               private route: ActivatedRoute, | ||||||
|  |               private rankService: RankService, | ||||||
|  |               private bottomSheet: MatBottomSheet) { | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   ngOnInit() { | ||||||
|  |     // init rank data
 | ||||||
|  |     this.rankService.findRanks() | ||||||
|  |         .subscribe(ranks => { | ||||||
|  |           this.ranksBlufor = ranks.filter(r => r.fraction === 'BLUFOR'); | ||||||
|  |           this.ranksOpfor = ranks.filter(r => r.fraction === 'OPFOR'); | ||||||
|  |         }); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   selectRow(rank: Rank) { | ||||||
|  |     this.bottomSheet.open(UserListSheetComponent, {data: {rank: rank}}); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,30 @@ | ||||||
|  | .rank-card { | ||||||
|  |   background: rgba(255, 255, 255, 0.87); | ||||||
|  |   width: 275px; | ||||||
|  |   height: 160px; | ||||||
|  |   margin: 6px; | ||||||
|  |   padding: 0; | ||||||
|  |   overflow: hidden; | ||||||
|  |   float: left; | ||||||
|  |   cursor: pointer; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .rank-card:hover { | ||||||
|  |   background: #ffffff; | ||||||
|  |   overflow: visible; | ||||||
|  |   box-shadow: 0 0 18px 2px #666666; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .rank-image { | ||||||
|  |   float: left; | ||||||
|  |   padding: 20px 20px 20px 25px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .rank-name { | ||||||
|  |   width: 169px; | ||||||
|  |   height: 100%; | ||||||
|  |   display: table-cell; | ||||||
|  |   padding-top: 36%; | ||||||
|  |   word-break: break-all; | ||||||
|  |   word-wrap: break-word; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,11 @@ | ||||||
|  | <mat-card class="rank-card" (click)="selectRank()"> | ||||||
|  |   <mat-card-content> | ||||||
|  |     <div class="rank-image"> | ||||||
|  |       <img src="resource/rank/{{rank._id}}.png" | ||||||
|  |            alt="{{rank.name}}"> | ||||||
|  |     </div> | ||||||
|  |     <div class="rank-name"> | ||||||
|  |       {{rank.name}} | ||||||
|  |     </div> | ||||||
|  |   </mat-card-content> | ||||||
|  | </mat-card> | ||||||
|  | @ -0,0 +1,21 @@ | ||||||
|  | import {Component, EventEmitter, Input, Output} from '@angular/core'; | ||||||
|  | import {Rank} from '../../../models/model-interfaces'; | ||||||
|  | import {Fraction} from '../../../utils/fraction.enum'; | ||||||
|  | 
 | ||||||
|  | @Component({ | ||||||
|  |   selector: 'cc-rank-panel', | ||||||
|  |   templateUrl: './rank-panel.component.html', | ||||||
|  |   styleUrls: ['./rank-panel.component.css'] | ||||||
|  | }) | ||||||
|  | export class RankPanelComponent { | ||||||
|  | 
 | ||||||
|  |   @Input() rank: Rank; | ||||||
|  | 
 | ||||||
|  |   @Output() select = new EventEmitter(); | ||||||
|  | 
 | ||||||
|  |   readonly fraction = Fraction; | ||||||
|  | 
 | ||||||
|  |   selectRank() { | ||||||
|  |     this.select.emit(this.rank); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,28 @@ | ||||||
|  | <div *ngIf="data.rank"> | ||||||
|  |   <img src="resource/rank/{{data.rank._id}}.png" height="65" style="float:left;"> | ||||||
|  |   <h4 style="text-align: center;height: 65px; padding-top: 20px;"> | ||||||
|  |     Aktive Teilnehmer mit Rang: {{data.rank.name}} | ||||||
|  |   </h4> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | <div *ngIf="data.decoration"> | ||||||
|  |   <img src="resource/decoration/{{data.decoration._id}}.png" | ||||||
|  |        height="{{data.decoration.isMedal ? 65 : 32}}" | ||||||
|  |        style="float:left;"> | ||||||
|  |   <h4 style="text-align: center;" | ||||||
|  |       [style.height]="data.decoration.isMedal ? '65px' : 'inherit'" | ||||||
|  |       [style.padding-top]="data.decoration.isMedal ? '20px' : 'inherit'"> | ||||||
|  |     Aktive Teilnehmer mit {{data.decoration.isMedal ? 'Orden' : 'Ordensband'}}: {{data.decoration.name}} | ||||||
|  |   </h4> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | <mat-nav-list *ngFor="let user of users"> | ||||||
|  |   <a mat-list-item (click)="selectUser(user)"> | ||||||
|  |       <span mat-line> | ||||||
|  |         {{user.username}} | ||||||
|  |       </span> | ||||||
|  |     <span mat-line [style.color]="user.squadId.fraction === 'BLUFOR' ? fraction.COLOR_BLUFOR :fraction.COLOR_OPFOR"> | ||||||
|  |         {{user.squadId.fraction === 'BLUFOR' ? fraction.BLUFOR : fraction.OPFOR}} -  {{user.squadId.name}} | ||||||
|  |       </span> | ||||||
|  |   </a> | ||||||
|  | </mat-nav-list> | ||||||
|  | @ -0,0 +1,53 @@ | ||||||
|  | import {Component, Inject, OnInit} from '@angular/core'; | ||||||
|  | import {MAT_BOTTOM_SHEET_DATA, MatBottomSheetRef} from '@angular/material'; | ||||||
|  | import {RankOverviewComponent} from '../rank-overview/rank-overview.component'; | ||||||
|  | import {ActivatedRoute, Router} from '@angular/router'; | ||||||
|  | import {RankService} from '../../services/army-management/rank.service'; | ||||||
|  | import {DecorationService} from '../../services/army-management/decoration.service'; | ||||||
|  | import {UserService} from '../../services/army-management/user.service'; | ||||||
|  | import {User} from '../../models/model-interfaces'; | ||||||
|  | import {Fraction} from '../../utils/fraction.enum'; | ||||||
|  | 
 | ||||||
|  | @Component({ | ||||||
|  |   selector: 'cc-user-list-sheet', | ||||||
|  |   templateUrl: 'user-list-sheet.component.html', | ||||||
|  | }) | ||||||
|  | export class UserListSheetComponent implements OnInit { | ||||||
|  | 
 | ||||||
|  |   users: User[]; | ||||||
|  | 
 | ||||||
|  |   readonly fraction = Fraction; | ||||||
|  | 
 | ||||||
|  |   constructor(private router: Router, | ||||||
|  |               private route: ActivatedRoute, | ||||||
|  |               private userService: UserService, | ||||||
|  |               private rankService: RankService, | ||||||
|  |               private decorationService: DecorationService, | ||||||
|  |               private bottomSheetRef: MatBottomSheetRef<RankOverviewComponent>, | ||||||
|  |               @Inject(MAT_BOTTOM_SHEET_DATA) public data: any) { | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   ngOnInit() { | ||||||
|  |     if (this.data.decoration) { | ||||||
|  |       const itemId = this.data.decoration._id; | ||||||
|  |       this.decorationService.getDecoration(itemId).subscribe(decoration => { | ||||||
|  |         this.userService.findUsers({decorationId: decoration._id}).subscribe(users => { | ||||||
|  |           this.users = users.filter(user => user.squadId != null); | ||||||
|  |         }); | ||||||
|  |       }); | ||||||
|  |     } else if (this.data.rank) { | ||||||
|  |       // Rank
 | ||||||
|  |       const itemId = this.data.rank._id; | ||||||
|  |       this.rankService.getRank(itemId).subscribe(rank => { | ||||||
|  |         this.userService.findUsers({fraction: rank.fraction}).subscribe(users => { | ||||||
|  |           this.users = users.filter(user => user.squadId != null && user.rankLvl === rank.level); | ||||||
|  |         }); | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   selectUser(user) { | ||||||
|  |     this.bottomSheetRef.dismiss(); | ||||||
|  |     this.router.navigate(['overview', 'member', user._id]); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| <form #form="ngForm" class="overview"> | <form #form="ngForm" (keydown.enter)="$event.preventDefault()" class="overview"> | ||||||
|   <h3 *ngIf="rank._id">Rang editieren</h3> |   <h3 *ngIf="rank._id">Rang editieren</h3> | ||||||
|   <h3 *ngIf="!rank._id">Neuen Rang hinzufügen</h3> |   <h3 *ngIf="!rank._id">Neuen Rang hinzufügen</h3> | ||||||
| 
 | 
 | ||||||
|  | @ -51,16 +51,10 @@ | ||||||
|   </button> |   </button> | ||||||
| 
 | 
 | ||||||
|   <button id="save" |   <button id="save" | ||||||
|  |           type="submit" | ||||||
|           (click)="saveRank(fileInput)" |           (click)="saveRank(fileInput)" | ||||||
|           class="btn btn-default" |           class="btn btn-default" | ||||||
|           [disabled]="!form.valid"> |           [disabled]="!form.valid"> | ||||||
|     Bestätigen |     Bestätigen | ||||||
|   </button> |   </button> | ||||||
| 
 |  | ||||||
|   <span *ngIf="showSuccessLabel" |  | ||||||
|         class="label label-success label-small" |  | ||||||
|         style="margin-left: inherit"> |  | ||||||
|         Erfolgreich gespeichert |  | ||||||
|   </span> |  | ||||||
| 
 |  | ||||||
| </form> | </form> | ||||||
|  |  | ||||||
|  | @ -5,6 +5,8 @@ import {Rank} from '../../models/model-interfaces'; | ||||||
| import {RankService} from '../../services/army-management/rank.service'; | import {RankService} from '../../services/army-management/rank.service'; | ||||||
| import {Subscription} from 'rxjs/Subscription'; | import {Subscription} from 'rxjs/Subscription'; | ||||||
| import {Fraction} from '../../utils/fraction.enum'; | import {Fraction} from '../../utils/fraction.enum'; | ||||||
|  | import {Message} from '../../i18n/de.messages'; | ||||||
|  | import {SnackBarService} from '../../services/user-interface/snack-bar/snack-bar.service'; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @Component({ | @Component({ | ||||||
|  | @ -25,15 +27,14 @@ export class EditRankComponent implements OnInit, OnDestroy { | ||||||
| 
 | 
 | ||||||
|   imagePreviewSrc; |   imagePreviewSrc; | ||||||
| 
 | 
 | ||||||
|   showSuccessLabel = false; |  | ||||||
| 
 |  | ||||||
|   @ViewChild(NgForm) form: NgForm; |   @ViewChild(NgForm) form: NgForm; | ||||||
| 
 | 
 | ||||||
|   readonly fraction = Fraction; |   readonly fraction = Fraction; | ||||||
| 
 | 
 | ||||||
|   constructor(private route: ActivatedRoute, |   constructor(private route: ActivatedRoute, | ||||||
|               private router: Router, |               private router: Router, | ||||||
|               private rankService: RankService) { |               private rankService: RankService, | ||||||
|  |               private snackBarService: SnackBarService) { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   ngOnInit() { |   ngOnInit() { | ||||||
|  | @ -85,10 +86,7 @@ export class EditRankComponent implements OnInit, OnDestroy { | ||||||
|               this.imagePreviewSrc = 'resource/rank/' + this.rank._id + '.png?' + Date.now(); |               this.imagePreviewSrc = 'resource/rank/' + this.rank._id + '.png?' + Date.now(); | ||||||
|             }, 300); |             }, 300); | ||||||
|             fileInput.value = ''; |             fileInput.value = ''; | ||||||
|             this.showSuccessLabel = true; |             this.snackBarService.showSuccess(Message.SUCCESS_SAVE); | ||||||
|             setTimeout(() => { |  | ||||||
|               this.showSuccessLabel = false; |  | ||||||
|             }, 2000); |  | ||||||
|           }); |           }); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -13,7 +13,7 @@ | ||||||
| 
 | 
 | ||||||
|     <div class="col-xs-4"> |     <div class="col-xs-4"> | ||||||
|       <img src="{{imageSrc}}" class="rank-list-preview"> |       <img src="{{imageSrc}}" class="rank-list-preview"> | ||||||
|       <span (click)="delete(); $event.stopPropagation()" title="Löschen" class="glyphicon glyphicon-trash trash"></span> |       <span (click)="delete(); $event.stopPropagation()" matTooltip="Löschen" class="glyphicon glyphicon-trash trash"></span> | ||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|   </div> |   </div> | ||||||
|  |  | ||||||
|  | @ -1,32 +1,22 @@ | ||||||
| <div class="select-list"> | <div class="select-list"> | ||||||
|   <div class="input-group list-header"> |   <cc-list-filter | ||||||
|     <div class="btn-group" (click)="filterRanks()"> |     [filterButtons]="[{label: fraction.BLUFOR, value: 'BLUFOR'}, | ||||||
|       <label class="btn btn-success" [(ngModel)]="radioModel" btnRadio="BLUFOR" uncheckable>{{fraction.BLUFOR}}</label> |                       {label: fraction.OPFOR, value: 'OPFOR'}]" | ||||||
|       <label class="btn btn-success" [(ngModel)]="radioModel" btnRadio="OPFOR" uncheckable>{{fraction.OPFOR}}</label> |     [addButton]="{svgIcon: 'add', tooltip: 'Neuen Rang hinzufügen'}" | ||||||
|     </div> |     (executeSearch)="filterRanks($event)" | ||||||
|     <a class="pull-right btn btn-success" (click)="openNewRankForm()">+</a> |     (openAddFrom)="openNewRankForm()"> | ||||||
|   </div> |   </cc-list-filter> | ||||||
| 
 | 
 | ||||||
|   <div class="input-group list-header"> |   <cc-list-search [searchTerm]="searchTerm" | ||||||
|     <input id="search-tasks" |                   (searchTermStream)="initObservable($event)" | ||||||
|            type="text" #query class="form-control" |                   (executeSearch)="filterRanks()"> | ||||||
|            (keyup.enter)="filterRanks()" |   </cc-list-search> | ||||||
|            [formControl]="searchTerm"> |  | ||||||
|     <span class="input-group-btn"> |  | ||||||
|       <button class="btn btn-default" type="button" |  | ||||||
|               (click)="filterRanks()"> |  | ||||||
|         Suchen |  | ||||||
|       </button> |  | ||||||
|     </span> |  | ||||||
|   </div> |  | ||||||
| 
 | 
 | ||||||
|   <div> |   <pjm-rank-item *ngFor="let rank of ranks$ | async" | ||||||
|     <pjm-rank-item *ngFor="let rank of ranks$ | async" |                  [rank]="rank" | ||||||
|                    [rank]="rank" |                  (rankDelete)="deleteRank(rank)" | ||||||
|                    (rankDelete)="deleteRank(rank)" |                  (rankSelected)="selectRank($event)" | ||||||
|                    (rankSelected)="selectRank($event)" |                  [selected]="rank._id == selectedRankId"> | ||||||
|                    [selected]="rank._id == selectedRankId"> |   </pjm-rank-item> | ||||||
|     </pjm-rank-item> |  | ||||||
|   </div> |  | ||||||
| 
 | 
 | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
|  | @ -1,5 +1,4 @@ | ||||||
| import {Component, OnInit} from '@angular/core'; | import {Component, OnInit} from '@angular/core'; | ||||||
| import {Location} from '@angular/common'; |  | ||||||
| 
 | 
 | ||||||
| import {FormControl} from '@angular/forms'; | import {FormControl} from '@angular/forms'; | ||||||
| import {ActivatedRoute, Router} from '@angular/router'; | import {ActivatedRoute, Router} from '@angular/router'; | ||||||
|  | @ -7,9 +6,11 @@ import {Observable} from 'rxjs/Observable'; | ||||||
| import {Rank} from '../../models/model-interfaces'; | import {Rank} from '../../models/model-interfaces'; | ||||||
| import {RankService} from '../../services/army-management/rank.service'; | import {RankService} from '../../services/army-management/rank.service'; | ||||||
| import {Fraction} from '../../utils/fraction.enum'; | import {Fraction} from '../../utils/fraction.enum'; | ||||||
|  | import {UIHelpers} from '../../utils/global.helpers'; | ||||||
|  | import {MatButtonToggleGroup} from '@angular/material'; | ||||||
| 
 | 
 | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'rank-list', |   selector: 'cc-rank-list', | ||||||
|   templateUrl: './rank-list.component.html', |   templateUrl: './rank-list.component.html', | ||||||
|   styleUrls: ['./rank-list.component.css', '../../style/select-list.css'] |   styleUrls: ['./rank-list.component.css', '../../style/select-list.css'] | ||||||
| }) | }) | ||||||
|  | @ -21,35 +22,27 @@ export class RankListComponent implements OnInit { | ||||||
| 
 | 
 | ||||||
|   searchTerm = new FormControl(); |   searchTerm = new FormControl(); | ||||||
| 
 | 
 | ||||||
|   public radioModel: string; |   radioModel = ''; | ||||||
| 
 | 
 | ||||||
|   readonly fraction = Fraction; |   readonly fraction = Fraction; | ||||||
| 
 | 
 | ||||||
|   constructor(private rankService: RankService, |   constructor(private rankService: RankService, | ||||||
|               private router: Router, |               private router: Router, | ||||||
|               private route: ActivatedRoute, |               private route: ActivatedRoute) { | ||||||
|               private location: Location) { |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   ngOnInit() { |   ngOnInit() { | ||||||
| 
 |  | ||||||
|     this.ranks$ = this.rankService.ranks$; |     this.ranks$ = this.rankService.ranks$; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|     const paramsStream = this.route.queryParams |   initObservable(observables: any) { | ||||||
|                              .map(params => decodeURI(params['query'] || '')) |     Observable.merge(observables.params as Observable<string>, observables.searchTerm) | ||||||
|                              .do(query => this.searchTerm.setValue(query)); |  | ||||||
| 
 |  | ||||||
|     const searchTermStream = this.searchTerm.valueChanges |  | ||||||
|                                  .debounceTime(400) |  | ||||||
|                                  .do(query => this.adjustBrowserUrl(query)); |  | ||||||
| 
 |  | ||||||
|     Observable.merge(paramsStream, searchTermStream) |  | ||||||
|               .distinctUntilChanged() |               .distinctUntilChanged() | ||||||
|               .switchMap(query => this.rankService.findRanks(query, this.radioModel)) |               .switchMap(query => this.rankService.findRanks(query, this.radioModel)) | ||||||
|               .subscribe(); |               .subscribe(); | ||||||
| 
 |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|   openNewRankForm() { |   openNewRankForm() { | ||||||
|     this.selectedRankId = null; |     this.selectedRankId = null; | ||||||
|     this.router.navigate([{outlets: {'right': ['new']}}], {relativeTo: this.route}); |     this.router.navigate([{outlets: {'right': ['new']}}], {relativeTo: this.route}); | ||||||
|  | @ -60,7 +53,8 @@ export class RankListComponent implements OnInit { | ||||||
|     this.router.navigate([{outlets: {'right': ['edit', rankId]}}], {relativeTo: this.route}); |     this.router.navigate([{outlets: {'right': ['edit', rankId]}}], {relativeTo: this.route}); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   filterRanks() { |   filterRanks(group?: MatButtonToggleGroup) { | ||||||
|  |     this.radioModel = UIHelpers.toggleReleaseButton(this.radioModel, group); | ||||||
|     this.ranks$ = this.rankService.findRanks(this.searchTerm.value, this.radioModel); |     this.ranks$ = this.rankService.findRanks(this.searchTerm.value, this.radioModel); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -72,12 +66,4 @@ export class RankListComponent implements OnInit { | ||||||
|           }); |           }); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 |  | ||||||
|   adjustBrowserUrl(queryString = '') { |  | ||||||
|     const absoluteUrl = this.location.path().split('?')[0]; |  | ||||||
|     const queryPart = queryString !== '' ? `query=${queryString}` : ''; |  | ||||||
| 
 |  | ||||||
|     this.location.replaceState(absoluteUrl, queryPart); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1 +0,0 @@ | ||||||
| <router-outlet></router-outlet> |  | ||||||
|  | @ -1,11 +0,0 @@ | ||||||
| import {Component} from '@angular/core'; |  | ||||||
| 
 |  | ||||||
| @Component({ |  | ||||||
|   selector: 'cc-ranks', |  | ||||||
|   templateUrl: './ranks.component.html', |  | ||||||
|   styleUrls: ['./ranks.component.css'] |  | ||||||
| }) |  | ||||||
| export class RankComponent { |  | ||||||
|   constructor() { |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  | @ -4,11 +4,10 @@ import {SharedModule} from '../shared.module'; | ||||||
| import {CommonModule} from '@angular/common'; | import {CommonModule} from '@angular/common'; | ||||||
| import {RankService} from '../services/army-management/rank.service'; | import {RankService} from '../services/army-management/rank.service'; | ||||||
| import {RankStore} from '../services/stores/rank.store'; | import {RankStore} from '../services/stores/rank.store'; | ||||||
| import {ButtonsModule} from 'ngx-bootstrap'; |  | ||||||
| 
 | 
 | ||||||
| @NgModule({ | @NgModule({ | ||||||
|   declarations: ranksRoutingComponents, |   declarations: ranksRoutingComponents, | ||||||
|   imports: [CommonModule, SharedModule, ButtonsModule.forRoot(), rankRouterModule], |   imports: [CommonModule, SharedModule, rankRouterModule], | ||||||
|   providers: [RankStore, RankService] |   providers: [RankStore, RankService] | ||||||
| }) | }) | ||||||
| export class RanksModule { | export class RanksModule { | ||||||
|  |  | ||||||
|  | @ -1,20 +1,15 @@ | ||||||
| import {RouterModule, Routes} from '@angular/router'; | import {RouterModule, Routes} from '@angular/router'; | ||||||
| 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 {EditRankComponent} from './edit-rank/edit-rank.component'; | ||||||
| import {RankItemComponent} from './rank-list/rank-item.component'; | import {RankItemComponent} from './rank-list/rank-item.component'; | ||||||
| import {ModuleWithProviders} from '@angular/core'; | import {ModuleWithProviders} from '@angular/core'; | ||||||
| 
 | 
 | ||||||
| 
 | export const ranksRoutes: Routes = [ | ||||||
| export const ranksRoutes: Routes = [{ |   { | ||||||
|   path: '', component: RankComponent, |     path: '', | ||||||
|   children: [ |     component: RankListComponent, | ||||||
|     { |     outlet: 'left' | ||||||
|       path: '', |   }, | ||||||
|       component: RankListComponent |  | ||||||
|     } |  | ||||||
|   ] |  | ||||||
| }, |  | ||||||
|   { |   { | ||||||
|     path: 'new', |     path: 'new', | ||||||
|     component: EditRankComponent, |     component: EditRankComponent, | ||||||
|  | @ -28,5 +23,5 @@ export const ranksRoutes: Routes = [{ | ||||||
| 
 | 
 | ||||||
| export const rankRouterModule: ModuleWithProviders = RouterModule.forChild(ranksRoutes); | export const rankRouterModule: ModuleWithProviders = RouterModule.forChild(ranksRoutes); | ||||||
| 
 | 
 | ||||||
| export const ranksRoutingComponents = [RankComponent, RankItemComponent, RankListComponent, EditRankComponent]; | export const ranksRoutingComponents = [RankItemComponent, RankListComponent, EditRankComponent]; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -62,11 +62,6 @@ | ||||||
|     Bestätigen |     Bestätigen | ||||||
|   </button> |   </button> | ||||||
| 
 | 
 | ||||||
|   <span *ngIf="showSuccessLabel" |  | ||||||
|         class="absolute-label label label-success label-small"> |  | ||||||
|   Erfolgreich gespeichert |  | ||||||
|   </span> |  | ||||||
| 
 |  | ||||||
|   <div class="table-container" *ngIf="showForm"> |   <div class="table-container" *ngIf="showForm"> | ||||||
|     <table class="table table-hover"> |     <table class="table table-hover"> | ||||||
|       <thead> |       <thead> | ||||||
|  |  | ||||||
|  | @ -6,6 +6,8 @@ import {AwardingService} from '../../services/army-management/awarding.service'; | ||||||
| import {DecorationService} from '../../services/army-management/decoration.service'; | import {DecorationService} from '../../services/army-management/decoration.service'; | ||||||
| import {UserService} from '../../services/army-management/user.service'; | import {UserService} from '../../services/army-management/user.service'; | ||||||
| import {LoginService} from '../../services/app-user-service/login-service'; | import {LoginService} from '../../services/app-user-service/login-service'; | ||||||
|  | import {SnackBarService} from '../../services/user-interface/snack-bar/snack-bar.service'; | ||||||
|  | import {Message} from '../../i18n/de.messages'; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @Component({ | @Component({ | ||||||
|  | @ -18,8 +20,6 @@ export class RequestAwardComponent implements OnInit { | ||||||
| 
 | 
 | ||||||
|   showForm = false; |   showForm = false; | ||||||
| 
 | 
 | ||||||
|   showSuccessLabel = false; |  | ||||||
| 
 |  | ||||||
|   user: User = {_id: '0'}; |   user: User = {_id: '0'}; | ||||||
| 
 | 
 | ||||||
|   decoration: Decoration = {_id: '0'}; |   decoration: Decoration = {_id: '0'}; | ||||||
|  | @ -39,12 +39,13 @@ export class RequestAwardComponent implements OnInit { | ||||||
|               private userService: UserService, |               private userService: UserService, | ||||||
|               private awardingService: AwardingService, |               private awardingService: AwardingService, | ||||||
|               private decorationService: DecorationService, |               private decorationService: DecorationService, | ||||||
|               private loginService: LoginService) { |               private loginService: LoginService, | ||||||
|  |               private snackBarService: SnackBarService) { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   ngOnInit() { |   ngOnInit() { | ||||||
|     const currentUser = this.loginService.getCurrentUser(); |     const currentUser = this.loginService.getCurrentUser(); | ||||||
|     this.userService.findUsers('', undefined, currentUser.squad._id).subscribe(users => { |     this.userService.findUsers({squadId: currentUser.squad._id}).subscribe(users => { | ||||||
|       this.users = users; |       this.users = users; | ||||||
|     }); |     }); | ||||||
|     this.decorationService.findDecorations('', currentUser.squad.fraction).subscribe(decorations => { |     this.decorationService.findDecorations('', currentUser.squad.fraction).subscribe(decorations => { | ||||||
|  | @ -93,10 +94,7 @@ export class RequestAwardComponent implements OnInit { | ||||||
|               this.decoration = {_id: '0'}; |               this.decoration = {_id: '0'}; | ||||||
|               this.reason = previewImage.src = descriptionField.innerHTML = ''; |               this.reason = previewImage.src = descriptionField.innerHTML = ''; | ||||||
|               this.decoPreviewDisplay = 'none'; |               this.decoPreviewDisplay = 'none'; | ||||||
|               this.showSuccessLabel = true; |               this.snackBarService.showSuccess(Message.SUCCESS_SAVE); | ||||||
|               setTimeout(() => { |  | ||||||
|                 this.showSuccessLabel = false; |  | ||||||
|               }, 2000); |  | ||||||
|             }); |             }); | ||||||
|       }); |       }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -1,11 +1,6 @@ | ||||||
| <form #form="ngForm" class="overview"> | <form #form="ngForm" class="overview"> | ||||||
|   <h3>Offene Anträge - Auszeichnungen</h3> |   <h3>Offene Anträge - Auszeichnungen</h3> | ||||||
| 
 | 
 | ||||||
|   <span *ngIf="showSuccessLabel" |  | ||||||
|         class="absolute-label label label-success label-small"> |  | ||||||
|   Erfolgreich gespeichert |  | ||||||
|   </span> |  | ||||||
| 
 |  | ||||||
|   <div class="table-container"> |   <div class="table-container"> | ||||||
|     <table class="table table-hover"> |     <table class="table table-hover"> | ||||||
|       <thead> |       <thead> | ||||||
|  | @ -37,7 +32,6 @@ | ||||||
|         <td> |         <td> | ||||||
|           <textarea style="width:100%;" |           <textarea style="width:100%;" | ||||||
|                     rows="3" |                     rows="3" | ||||||
|                     title="reason" |  | ||||||
|                     #reason>{{award.reason}}</textarea> |                     #reason>{{award.reason}}</textarea> | ||||||
|         </td> |         </td> | ||||||
|         <td> |         <td> | ||||||
|  | @ -49,7 +43,6 @@ | ||||||
|         <td> |         <td> | ||||||
|           <textarea style="width: 100%;" |           <textarea style="width: 100%;" | ||||||
|                     rows="3" |                     rows="3" | ||||||
|                     title="rejectReason" |  | ||||||
|                     placeholder="Begründung für Ablehnung (optional)" |                     placeholder="Begründung für Ablehnung (optional)" | ||||||
|                     #rejectReason></textarea> |                     #rejectReason></textarea> | ||||||
|         </td> |         </td> | ||||||
|  |  | ||||||
|  | @ -2,6 +2,8 @@ import {Component, OnInit} from '@angular/core'; | ||||||
| import {Award} from '../../models/model-interfaces'; | import {Award} from '../../models/model-interfaces'; | ||||||
| import {AwardingService} from '../../services/army-management/awarding.service'; | import {AwardingService} from '../../services/army-management/awarding.service'; | ||||||
| import {LoginService} from '../../services/app-user-service/login-service'; | import {LoginService} from '../../services/app-user-service/login-service'; | ||||||
|  | import {SnackBarService} from '../../services/user-interface/snack-bar/snack-bar.service'; | ||||||
|  | import {Message} from '../../i18n/de.messages'; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @Component({ | @Component({ | ||||||
|  | @ -12,10 +14,9 @@ export class ConfirmAwardComponent implements OnInit { | ||||||
| 
 | 
 | ||||||
|   awards: Award[]; |   awards: Award[]; | ||||||
| 
 | 
 | ||||||
|   showSuccessLabel = false; |  | ||||||
| 
 |  | ||||||
|   constructor(private awardingService: AwardingService, |   constructor(private awardingService: AwardingService, | ||||||
|               private loginService: LoginService) { |               private loginService: LoginService, | ||||||
|  |               private snackBarService: SnackBarService) { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   ngOnInit() { |   ngOnInit() { | ||||||
|  | @ -46,13 +47,8 @@ export class ConfirmAwardComponent implements OnInit { | ||||||
|         if (awards.length < 1) { |         if (awards.length < 1) { | ||||||
|           this.awardingService.hasUnprocessedAwards = false; |           this.awardingService.hasUnprocessedAwards = false; | ||||||
|         } |         } | ||||||
|         this.showSuccessLabel = true; |         this.snackBarService.showSuccess(Message.SUCCESS_SAVE); | ||||||
|         setTimeout(() => { |  | ||||||
|           this.showSuccessLabel = false; |  | ||||||
|         }, 2000); |  | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,11 +1,6 @@ | ||||||
| <form #form="ngForm" class="overview"> | <form #form="ngForm" class="overview"> | ||||||
|   <h3>Offene Anträge - Beförderung</h3> |   <h3>Offene Anträge - Beförderung</h3> | ||||||
| 
 | 
 | ||||||
|   <span *ngIf="showSuccessLabel" |  | ||||||
|         class="absolute-label label label-success label-small"> |  | ||||||
|   Erfolgreich gespeichert |  | ||||||
|   </span> |  | ||||||
| 
 |  | ||||||
|   <div class="table-container"> |   <div class="table-container"> | ||||||
|     <table class="table table-hover"> |     <table class="table table-hover"> | ||||||
|       <thead> |       <thead> | ||||||
|  | @ -43,7 +38,6 @@ | ||||||
|         <td> |         <td> | ||||||
|           <textarea style="width: 100%;" |           <textarea style="width: 100%;" | ||||||
|                     rows="3" |                     rows="3" | ||||||
|                     title="rejectReason" |  | ||||||
|                     placeholder="Begründung für Ablehnung (optional)" |                     placeholder="Begründung für Ablehnung (optional)" | ||||||
|                     #rejectReason></textarea> |                     #rejectReason></textarea> | ||||||
|         </td> |         </td> | ||||||
|  | @ -55,6 +49,4 @@ | ||||||
|       </tbody> |       </tbody> | ||||||
|     </table> |     </table> | ||||||
|   </div> |   </div> | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| </form> | </form> | ||||||
|  |  | ||||||
|  | @ -3,6 +3,8 @@ import {Promotion, Rank} from '../../models/model-interfaces'; | ||||||
| import {RankService} from '../../services/army-management/rank.service'; | import {RankService} from '../../services/army-management/rank.service'; | ||||||
| import {PromotionService} from '../../services/army-management/promotion.service'; | import {PromotionService} from '../../services/army-management/promotion.service'; | ||||||
| import {LoginService} from '../../services/app-user-service/login-service'; | import {LoginService} from '../../services/app-user-service/login-service'; | ||||||
|  | import {SnackBarService} from '../../services/user-interface/snack-bar/snack-bar.service'; | ||||||
|  | import {Message} from '../../i18n/de.messages'; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @Component({ | @Component({ | ||||||
|  | @ -11,15 +13,14 @@ import {LoginService} from '../../services/app-user-service/login-service'; | ||||||
| }) | }) | ||||||
| export class ConfirmPromotionComponent implements OnInit { | export class ConfirmPromotionComponent implements OnInit { | ||||||
| 
 | 
 | ||||||
|   showSuccessLabel = false; |  | ||||||
| 
 |  | ||||||
|   ranks: Rank[]; |   ranks: Rank[]; | ||||||
| 
 | 
 | ||||||
|   promotions: Promotion[]; |   promotions: Promotion[]; | ||||||
| 
 | 
 | ||||||
|   constructor(private rankService: RankService, |   constructor(private rankService: RankService, | ||||||
|               private promotionService: PromotionService, |               private promotionService: PromotionService, | ||||||
|               private loginService: LoginService) { |               private loginService: LoginService, | ||||||
|  |               private snackBarService: SnackBarService) { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   ngOnInit() { |   ngOnInit() { | ||||||
|  | @ -50,12 +51,8 @@ export class ConfirmPromotionComponent implements OnInit { | ||||||
|         if (promotions.length < 1) { |         if (promotions.length < 1) { | ||||||
|           this.promotionService.hasUnprocessedPromotion = false; |           this.promotionService.hasUnprocessedPromotion = false; | ||||||
|         } |         } | ||||||
|         this.showSuccessLabel = true; |         this.snackBarService.showSuccess(Message.SUCCESS_SAVE); | ||||||
|         setTimeout(() => { |  | ||||||
|           this.showSuccessLabel = false; |  | ||||||
|         }, 2000); |  | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -57,12 +57,6 @@ | ||||||
|     Bestätigen |     Bestätigen | ||||||
|   </button> |   </button> | ||||||
| 
 | 
 | ||||||
|   <span *ngIf="showSuccessLabel" |  | ||||||
|         class="absolute-label label label-success label-small"> |  | ||||||
|   Erfolgreich gespeichert |  | ||||||
|   </span> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|   <div class="table-container"> |   <div class="table-container"> | ||||||
|     <label>Beförderungsanträge</label> |     <label>Beförderungsanträge</label> | ||||||
|     <table class="table table-hover"> |     <table class="table table-hover"> | ||||||
|  |  | ||||||
|  | @ -6,6 +6,8 @@ import {UserService} from '../../services/army-management/user.service'; | ||||||
| import {RankService} from '../../services/army-management/rank.service'; | import {RankService} from '../../services/army-management/rank.service'; | ||||||
| import {PromotionService} from '../../services/army-management/promotion.service'; | import {PromotionService} from '../../services/army-management/promotion.service'; | ||||||
| import {LoginService} from '../../services/app-user-service/login-service'; | import {LoginService} from '../../services/app-user-service/login-service'; | ||||||
|  | import {Message} from '../../i18n/de.messages'; | ||||||
|  | import {SnackBarService} from '../../services/user-interface/snack-bar/snack-bar.service'; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @Component({ | @Component({ | ||||||
|  | @ -18,8 +20,6 @@ export class RequestPromotionComponent implements OnInit { | ||||||
| 
 | 
 | ||||||
|   showForm = false; |   showForm = false; | ||||||
| 
 | 
 | ||||||
|   showSuccessLabel = false; |  | ||||||
| 
 |  | ||||||
|   user: User = {_id: '0'}; |   user: User = {_id: '0'}; | ||||||
| 
 | 
 | ||||||
|   newLevel: number; |   newLevel: number; | ||||||
|  | @ -37,13 +37,14 @@ export class RequestPromotionComponent implements OnInit { | ||||||
|               private userService: UserService, |               private userService: UserService, | ||||||
|               private rankService: RankService, |               private rankService: RankService, | ||||||
|               private promotionService: PromotionService, |               private promotionService: PromotionService, | ||||||
|               private loginService: LoginService) { |               private loginService: LoginService, | ||||||
|  |               private snackBarService: SnackBarService) { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   ngOnInit() { |   ngOnInit() { | ||||||
|     const currentUser = this.loginService.getCurrentUser(); |     const currentUser = this.loginService.getCurrentUser(); | ||||||
|     // show only current users squad members
 |     // show only current users squad members
 | ||||||
|     this.userService.findUsers('', undefined, currentUser.squad._id).subscribe(users => { |     this.userService.findUsers({squadId: currentUser.squad._id}).subscribe(users => { | ||||||
|       this.users = users; |       this.users = users; | ||||||
|     }); |     }); | ||||||
|     this.rankService.findRanks('', currentUser.squad.fraction).subscribe(ranks => { |     this.rankService.findRanks('', currentUser.squad.fraction).subscribe(ranks => { | ||||||
|  | @ -79,10 +80,7 @@ export class RequestPromotionComponent implements OnInit { | ||||||
|         this.uncheckedPromotions = promotions; |         this.uncheckedPromotions = promotions; | ||||||
|         this.showForm = false; |         this.showForm = false; | ||||||
|         this.user = {_id: '0'}; |         this.user = {_id: '0'}; | ||||||
|         this.showSuccessLabel = true; |         this.snackBarService.showSuccess(Message.SUCCESS_SAVE); | ||||||
|         setTimeout(() => { |  | ||||||
|           this.showSuccessLabel = false; |  | ||||||
|         }, 2000); |  | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -12,30 +12,13 @@ export class AwardingService { | ||||||
|               private config: AppConfig) { |               private config: AppConfig) { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   getUnconfirmedAwards(fraction?: string) { |   getAwardings(fraction = '' , userId = '', inProgress = false, squadId = '') { | ||||||
|     return this.http.get(this.config.apiAwardPath + '?inProgress=true&fractFilter=' + fraction) |     const getUrl = this.config.apiAwardPath | ||||||
|                .map(res => res.json()); |                        .concat('?inProgress=').concat(inProgress.toString()) | ||||||
|   } |                        .concat('&fractFilter=').concat(fraction) | ||||||
| 
 |                        .concat('&userId=').concat(userId) | ||||||
|   checkUnprocessedAwards(fraction?: string) { |                        .concat('&squadId=').concat(squadId); | ||||||
|     this.getUnconfirmedAwards(fraction).subscribe((items) => { |     return this.http.get(getUrl).map(res => res.json()); | ||||||
|       if (items.length > 0) { |  | ||||||
|         this.hasUnprocessedAwards = true; |  | ||||||
|       } |  | ||||||
|     }); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   getUnprocessedSquadAwards(squadId?: string) { |  | ||||||
|     return this.http.get(this.config.apiAwardSquadPath.concat('/').concat(squadId)) |  | ||||||
|                .map(res => res.json()); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   /** |  | ||||||
|    * get awards array with populated decorations |  | ||||||
|    */ |  | ||||||
|   getUserAwardings(userId: string) { |  | ||||||
|     return this.http.get(this.config.apiAwardPath + '?userId=' + userId) |  | ||||||
|                .map(res => res.json()); |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   addAwarding(award: Award) { |   addAwarding(award: Award) { | ||||||
|  | @ -55,5 +38,27 @@ export class AwardingService { | ||||||
|     return this.http.delete(this.config.apiAwardPath + '/' + awardingId); |     return this.http.delete(this.config.apiAwardPath + '/' + awardingId); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   getUnconfirmedAwards(fraction?: string) { | ||||||
|  |     return this.getAwardings(fraction, '', true); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   checkUnprocessedAwards(fraction?: string) { | ||||||
|  |     this.getUnconfirmedAwards(fraction).subscribe((items) => { | ||||||
|  |       if (items.length > 0) { | ||||||
|  |         this.hasUnprocessedAwards = true; | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   getUnprocessedSquadAwards(squadId?: string) { | ||||||
|  |     return this.getAwardings('', '', true, squadId); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** | ||||||
|  |    * get awards array with populated decorations | ||||||
|  |    */ | ||||||
|  |   getUserAwardings(userId: string) { | ||||||
|  |     return this.getAwardings('', userId); | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -37,7 +37,7 @@ export class RankService { | ||||||
|     return this.ranks$; |     return this.ranks$; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   getRank(id: number | string): Observable<Decoration> { |   getRank(id: number | string): Observable<Rank> { | ||||||
|     return this.http.get(this.config.apiRankPath + id) |     return this.http.get(this.config.apiRankPath + id) | ||||||
|                .map(res => res.json()); |                .map(res => res.json()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -19,15 +19,23 @@ export class UserService { | ||||||
|     this.users$ = userStore.items$; |     this.users$ = userStore.items$; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   findUsers(query = '', fractionFilter?, squadFilter?, limit?, offset?, action = LOAD) { |   findUsers(filter, limit?, offset?, action = LOAD) { | ||||||
|     const searchParams = new URLSearchParams(); |     const searchParams = new URLSearchParams(); | ||||||
|     searchParams.append('q', query); | 
 | ||||||
|     if (fractionFilter) { |     searchParams.append('q', (filter && filter.query) ? filter.query : ''); | ||||||
|       searchParams.append('fractFilter', fractionFilter); | 
 | ||||||
|  |     if (filter && filter.fraction) { | ||||||
|  |       searchParams.append('fractFilter', filter.fraction); | ||||||
|     } |     } | ||||||
|     if (squadFilter) { | 
 | ||||||
|       searchParams.append('squadId', squadFilter); |     if (filter && filter.squadId) { | ||||||
|  |       searchParams.append('squadId', filter.squadId); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     if (filter && filter.decorationId) { | ||||||
|  |       searchParams.append('decorationId', filter.decorationId); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     searchParams.append('limit', limit); |     searchParams.append('limit', limit); | ||||||
|     searchParams.append('offset', offset); |     searchParams.append('offset', offset); | ||||||
|     this.http.get(this.config.apiUserPath, searchParams) |     this.http.get(this.config.apiUserPath, searchParams) | ||||||
|  |  | ||||||
|  | @ -16,4 +16,3 @@ export class ArmyService { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -13,6 +13,11 @@ export class CampaignService { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   getAllCampaigns() { |   getAllCampaigns() { | ||||||
|  |     return this.http.get(this.config.apiCampaignPath) | ||||||
|  |                .map(res => res.json()); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   getAllCampaignsWithWars() { | ||||||
|     return this.http.get(this.config.apiWarPath) |     return this.http.get(this.config.apiWarPath) | ||||||
|                .map(res => res.json()); |                .map(res => res.json()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,37 @@ | ||||||
|  | import {Injectable} from '@angular/core'; | ||||||
|  | import {MatSnackBar, MatSnackBarRef} from '@angular/material/snack-bar'; | ||||||
|  | 
 | ||||||
|  | @Injectable() | ||||||
|  | export class SnackBarService { | ||||||
|  |   constructor(private snackbar: MatSnackBar) { | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   private show(message: string, action?: string, duration?: number, panelClasses?: string[]): MatSnackBarRef<any> { | ||||||
|  |     const config = {}; | ||||||
|  |     if (duration) { | ||||||
|  |       config['duration'] = duration; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (action) { | ||||||
|  |       if (panelClasses) { | ||||||
|  |         panelClasses.push('snack-bar-button'); | ||||||
|  |       } else { | ||||||
|  |         panelClasses = ['snack-bar-button']; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (panelClasses) { | ||||||
|  |       config['panelClass'] = panelClasses; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return this.snackbar.open(message, action, config); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   showSuccess(message: string) { | ||||||
|  |     return this.show(message, undefined, 2500, ['custom-snack-bar', 'label-success']); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   showError(message: string, duration?: number) { | ||||||
|  |     return this.show(message, 'OK', duration, ['custom-snack-bar', 'label-danger']); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,19 @@ | ||||||
|  | import {EventEmitter, Injectable} from '@angular/core'; | ||||||
|  | 
 | ||||||
|  | @Injectable() | ||||||
|  | export class SpinnerService { | ||||||
|  | 
 | ||||||
|  |   public spinnerActive: EventEmitter<Boolean>; | ||||||
|  | 
 | ||||||
|  |   constructor() { | ||||||
|  |     this.spinnerActive = new EventEmitter(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   activate() { | ||||||
|  |     this.spinnerActive.emit(true) | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   deactivate() { | ||||||
|  |     this.spinnerActive.emit(false) | ||||||
|  |   } | ||||||
|  | } | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue