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