From 898a8e44f02b38d8013bec24c05332e2b6f15646 Mon Sep 17 00:00:00 2001 From: Asaf Azulay Date: Sun, 21 May 2017 04:02:25 +0300 Subject: [PATCH 1/6] Fixing adding new member bug Importing new data to production --- bin/import_camps_data.js | 56 ++++++++++--------- locales/en/camps.json | 1 + locales/he/camps.json | 1 + models/camp.js | 17 ++++-- models/user.js | 12 ++-- public/scripts/controllers/camp_edit.js | 5 +- routes/api_camps_routes.js | 5 +- routes/main_routes.js | 14 +++-- views/pages/camps/partials/members_table.jade | 10 ++-- 9 files changed, 73 insertions(+), 48 deletions(-) diff --git a/bin/import_camps_data.js b/bin/import_camps_data.js index 9b26a5056..0189d3f8d 100755 --- a/bin/import_camps_data.js +++ b/bin/import_camps_data.js @@ -43,34 +43,36 @@ function main(argv) { // console.log('updating default prototypes: ' + constants.CAMP_PROTOTYPE); // }), knex.schema.raw("ALTER TABLE `camps` CHANGE `__prototype` `__prototype` ENUM( 'theme_camp', 'art_installation', 'prod_dep') CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL"), - knex("users_groups_membership", table => { - table.enu('status', constants.CAMP_MEMBER_STATUS); - }).then( - knex.raw( - "CREATE TRIGGER `camp_members_groups_after_ins` AFTER INSERT ON `camp_members` FOR EACH ROW INSERT INTO users_groups_membership (group_id, user_id, status) VALUES (new.camp_id, new.user_id,new.status)" - // "CREATE TRIGGER camp_members_groups_after_ins AFTER INSERT ON camp_members " + - // "FOR EACH ROW " + - // "BEGIN " + - // "INSERT INTO users_groups_membership (group_id, user_id, status) VALUES (new.camp_id, new.user_id, new.status); " + - // "END" - ).then( + // knex("users_groups_membership", table => { + // table.enu('status', constants.CAMP_MEMBER_STATUS); + // }).then( + // knex.raw( + // "CREATE TRIGGER `camp_members_groups_after_ins` AFTER INSERT ON `camp_members` FOR EACH ROW INSERT INTO users_groups_membership (group_id, user_id, status) VALUES (new.camp_id, new.user_id,new.status)" + // // "CREATE TRIGGER camp_members_groups_after_ins AFTER INSERT ON camp_members " + + // // "FOR EACH ROW " + + // // "BEGIN " + + // // "INSERT INTO users_groups_membership (group_id, user_id, status) VALUES (new.camp_id, new.user_id, new.status); " + + // // "END" + // ).then( - knex.raw( - "CREATE TRIGGER `camp_members_groups_after_upd` AFTER UPDATE ON `camp_members` FOR EACH ROW UPDATE users_groups_membership SET status = new.status WHERE group_id = new.camp_id AND user_id = new.user_id " - // "CREATE TRIGGER camp_members_groups_after_upd AFTER UPDATE ON camp_members " + - // "FOR EACH ROW " + - // "BEGIN " + - // "UPDATE users_groups_membership SET status = new.status WHERE group_id = new.camp_id AND user_id = new.user_id; " + - // "END" - ).then( - knex.raw("insert into users_groups_membership(user_id, group_id, status) " + - "select cm.user_id, cm.camp_id, cm.status " + - "from users u " + - "inner join camp_members cm on u.user_id = cm.user_id " + - "ON DUPLICATE KEY UPDATE status = cm.status;") - ) - ) - ) + // knex.raw( + // // "CREATE TRIGGER `camp_members_groups_after_upd` AFTER UPDATE ON `camp_members` FOR EACH ROW UPDATE users_groups_membership SET status = new.status WHERE group_id = new.camp_id AND user_id = new.user_id " + // "CREATE TRIGGER `camp_members_groups_after_upd` AFTER UPDATE ON `camp_members` FOR EACH ROW INSERT INTO users_groups_membership (group_id, user_id, status) VALUES (new.camp_id, new.user_id,new.status) ON DUPLICATE KEY UPDATE SET status = new.status " + + // // "CREATE TRIGGER camp_members_groups_after_upd AFTER UPDATE ON camp_members " + + // // "FOR EACH ROW " + + // // "BEGIN " + + // // "UPDATE users_groups_membership SET status = new.status WHERE group_id = new.camp_id AND user_id = new.user_id; " + + // // "END" + // ).then( + // knex.raw("insert into users_groups_membership(user_id, group_id, status) " + + // "select cm.user_id, cm.camp_id, cm.status " + + // "from users u " + + // "inner join camp_members cm on u.user_id = cm.user_id " + + // "ON DUPLICATE KEY UPDATE status = cm.status;") + // ) + // ) + // ) ] ); console.log('*** Working on Users ***'); diff --git a/locales/en/camps.json b/locales/en/camps.json index 0e66bbbad..f7bd24791 100644 --- a/locales/en/camps.json +++ b/locales/en/camps.json @@ -163,6 +163,7 @@ "status_approved": "Approved", "status_rejected": "Camp manager did not approve request", "status_pending_mgr": "Waiting for member acceptance", + "inside_event": "Inside Event", "status_approved_mgr": "Approved as Manager", "status_supplier": "Supplier" }, diff --git a/locales/he/camps.json b/locales/he/camps.json index a01bae6ba..cdfc4cabb 100644 --- a/locales/he/camps.json +++ b/locales/he/camps.json @@ -163,6 +163,7 @@ "status_rejected": "נדחה על ידי מנהלת המחנה", "status_pending_mgr": "ממתין לאישור החברה המצטרפת", "status_approved_mgr": "מנהלת מחנה מאושרת", + "inside_event": "בתוך האירוע", "status_supplier": "מאושר כספק" }, "camps": { diff --git a/models/camp.js b/models/camp.js index fd0eefd20..04c2235a6 100644 --- a/models/camp.js +++ b/models/camp.js @@ -34,15 +34,22 @@ var Camp = bookshelf.Model.extend({ let _camps_members = constants.CAMP_MEMBERS_TABLE_NAME; let _users = constants.USERS_TABLE_NAME; - return knex(_users) - .select(_users + '.*', _camps_members + '.status AS member_status'/*,'tickets.ticket_id'*/) - .innerJoin(_camps_members, _users + '.user_id', _camps_members + '.user_id') +//,SUM(tickets.inside_event) AS inside_event + let query="SELECT users.*,camp_members.status AS member_status,SUM(IF(tickets.ticket_id>0,1,0)) AS ticket_count,SUM(tickets.inside_event) AS inside_event FROM users inner join camp_members on users.user_id=camp_members.user_id left join tickets on tickets.holder_id=users.user_id and tickets.event_id='MIDBURN2017' where camp_members.camp_id="+this.attributes.id+" group by users.user_id"; + return knex //(_users) + .raw(query) + // .select(_users + '.*', _camps_members + '.status AS member_status'/*,'tickets.ticket_id'*/) + // .innerJoin(_camps_members, _users + '.user_id', _camps_members + '.user_id') // .leftJoin('tickets', () => { this.on('tickets.holder_id', '=', 'users.user_id').andON('tickets.event_id', '=', 'MIDBURN2017') }) // .leftjoin('tickets','tickets.holder_id','users.user_id') - .where({ 'camp_members.camp_id': this.attributes.id }) - .then((users) => { + // .where({ 'camp_members.camp_id': this.attributes.id }) + .then((users_raw_data) => { + let users=users_raw_data[0]; + // console.log(users); let managers = []; + // let emails for (let i in users) { + // console.log(i); users[i].isManager = false; if (['open', 'closed'].indexOf(_this.attributes.status) === -1) { users[i].member_status = 'deleted'; diff --git a/models/user.js b/models/user.js index c4a99c491..a254aaf07 100644 --- a/models/user.js +++ b/models/user.js @@ -112,15 +112,17 @@ var User = bookshelf.Model.extend({ var _camps = constants.CAMPS_TABLE_NAME; var _this_user = this; if (!prototype) prototype = constants.prototype_camps.THEME_CAMP.id; + let _where = { + user_id: this.attributes.user_id, + 'camps.event_id': constants.CURRENT_EVENT_ID, + }; + if (prototype!=='all') _where['__prototype']=prototype; + console.log(_where); knex(_camps) .select(_camps + '.*', _camps_members + '.status AS member_status', 'users_groups.entrance_quota') .innerJoin(_camps_members, _camps + '.id', _camps_members + '.camp_id') .innerJoin('users_groups', _camps + '.id', 'users_groups.group_id') - .where({ - user_id: this.attributes.user_id, - 'camps.event_id': constants.CURRENT_EVENT_ID, - __prototype: prototype, - }) + .where(_where) .then((camps) => { let first_camp = null; let is_manager = false; diff --git a/public/scripts/controllers/camp_edit.js b/public/scripts/controllers/camp_edit.js index d3ff75a65..99f4dedd3 100644 --- a/public/scripts/controllers/camp_edit.js +++ b/public/scripts/controllers/camp_edit.js @@ -10,6 +10,7 @@ var angular_getMembers = function ($http, $scope, camp_id) { var _members = []; var approved_members = []; var total_camp_tickets = 0; + var total_in_event = 0; for (var i in members) { if (['approved', 'pending', 'pending_mgr', 'approved_mgr', 'rejected'].indexOf(members[i].member_status) > -1) { _members.push(members[i]); @@ -17,12 +18,14 @@ var angular_getMembers = function ($http, $scope, camp_id) { if (['approved', 'approved_mgr'].indexOf(members[i].member_status) > -1) { approved_members.push(members[i]); } - total_camp_tickets+=parseInt(members[i].current_event_id_ticket_count) || 0; + total_in_event+=parseInt(members[i].inside_event); + total_camp_tickets+=parseInt(members[i].ticket_count) || 0; } $scope.members = _members; $scope.approved_members = approved_members; $scope.all_approved_members = approved_members.length; $scope.total_camp_tickets = total_camp_tickets; + $scope.total_in_event = total_in_event; }); } } diff --git a/routes/api_camps_routes.js b/routes/api_camps_routes.js index cdf37d5e8..668884323 100644 --- a/routes/api_camps_routes.js +++ b/routes/api_camps_routes.js @@ -913,9 +913,10 @@ module.exports = (app, passport) => { return; } req.user.getUserCamps((camps) => { - if (req.user.isManagerOfCamp(camp_id) || camp.__parsePrototype(camp.attributes.__prototype, req.user)) { + let group_props=camp.__parsePrototype(camp.attributes.__prototype, req.user); + if (req.user.isManagerOfCamp(camp_id) || group_props.isAdmin) { User.forge({ email: user_email }).fetch().then((user) => { - if (user !== null && user.attributes.validated) { + if (user !== null ) { // check that user is only at one camp! user.getUserCamps((camps) => { if (camps.length === 0 || !user.attributes.camp) { diff --git a/routes/main_routes.js b/routes/main_routes.js index 50408dec2..f35f05d38 100644 --- a/routes/main_routes.js +++ b/routes/main_routes.js @@ -49,10 +49,16 @@ module.exports = function (app, passport) { name: 'breadcrumbs.home', url: '/' + req.params.lng + '/home' }); - res.render('pages/home', { - user: req.user, - breadcrumbs: req.breadcrumbs() - }); + req.user.getUserCamps((camps)=>{ + // console.log(camps); + for (let i in camps) { + + } + res.render('pages/home', { + user: req.user, + breadcrumbs: req.breadcrumbs() + }); + },req,'all'); }); // ===================================== diff --git a/views/pages/camps/partials/members_table.jade b/views/pages/camps/partials/members_table.jade index 6900e1cf9..ee95df5c6 100644 --- a/views/pages/camps/partials/members_table.jade +++ b/views/pages/camps/partials/members_table.jade @@ -4,9 +4,10 @@ table.table.table-striped.table-hover th(ng-click='changeOrderBy("id")') # th(ng-click='changeOrderBy("name")')=t('camps:members.name') th(ng-click='changeOrderBy("email")')=t('camps:members.email') - th(ng-click='changeOrderBy("phone")')=t('camps:members.phone') - th(ng-click='changeOrderBy("status")')=t('camps:members.status') - th(ng-click='changeOrderBy("hasTicket")')=t('camps:members.ticket_count') + th(ng-click='changeOrderBy("cell_phone")')=t('camps:members.phone') + th(ng-click='changeOrderBy("member_status_i18n")')=t('camps:members.status') + th(ng-click='changeOrderBy("ticket_count")')=t('camps:members.ticket_count') + th(ng-click='changeOrderBy("inside_event")')=t('camps:members.inside_event') //- th(ng-click='changeOrderBy("earlyArrival")')=t('camps:members.early_arrival') th()=t('camps:members.actions') tbody @@ -16,7 +17,8 @@ table.table.table-striped.table-hover td {{member.email}} td {{member.cell_phone}} td {{member.member_status_i18n}} - td {{member.current_event_id_ticket_count}} + td {{member.ticket_count}} + td {{member.inside_event}} //- td {{member.earlyArrival ? 'yes':'no'}} td a.cursor-p(ng-click='updateUser(member.name, member.user_id, "reject")', ng-if="member.can_reject")   From 24bb02f4f8a506da7e1fbf462ed170d83a5b6f20 Mon Sep 17 00:00:00 2001 From: Asaf Azulay Date: Sun, 21 May 2017 04:16:53 +0300 Subject: [PATCH 2/6] making the code look nicer because of fucking lint --- models/camp.js | 4 +- routes/api_camps_routes.js | 6 +- routes/main_routes.js | 230 ++++++++++++++++++------------------- 3 files changed, 120 insertions(+), 120 deletions(-) diff --git a/models/camp.js b/models/camp.js index 04c2235a6..f92799a9e 100644 --- a/models/camp.js +++ b/models/camp.js @@ -32,8 +32,8 @@ var Camp = bookshelf.Model.extend({ } } - let _camps_members = constants.CAMP_MEMBERS_TABLE_NAME; - let _users = constants.USERS_TABLE_NAME; + // let _camps_members = constants.CAMP_MEMBERS_TABLE_NAME; + // let _users = constants.USERS_TABLE_NAME; //,SUM(tickets.inside_event) AS inside_event let query="SELECT users.*,camp_members.status AS member_status,SUM(IF(tickets.ticket_id>0,1,0)) AS ticket_count,SUM(tickets.inside_event) AS inside_event FROM users inner join camp_members on users.user_id=camp_members.user_id left join tickets on tickets.holder_id=users.user_id and tickets.event_id='MIDBURN2017' where camp_members.camp_id="+this.attributes.id+" group by users.user_id"; return knex //(_users) diff --git a/routes/api_camps_routes.js b/routes/api_camps_routes.js index 668884323..31bafe3c1 100644 --- a/routes/api_camps_routes.js +++ b/routes/api_camps_routes.js @@ -883,7 +883,7 @@ module.exports = (app, passport) => { } }, req) // .then(() => { - // console.log('knex') + // console.log('knex') // }); }).catch((e) => { @@ -913,10 +913,10 @@ module.exports = (app, passport) => { return; } req.user.getUserCamps((camps) => { - let group_props=camp.__parsePrototype(camp.attributes.__prototype, req.user); + let group_props = camp.__parsePrototype(camp.attributes.__prototype, req.user); if (req.user.isManagerOfCamp(camp_id) || group_props.isAdmin) { User.forge({ email: user_email }).fetch().then((user) => { - if (user !== null ) { + if (user !== null) { // check that user is only at one camp! user.getUserCamps((camps) => { if (camps.length === 0 || !user.attributes.camp) { diff --git a/routes/main_routes.js b/routes/main_routes.js index f35f05d38..26c24683d 100644 --- a/routes/main_routes.js +++ b/routes/main_routes.js @@ -49,16 +49,16 @@ module.exports = function (app, passport) { name: 'breadcrumbs.home', url: '/' + req.params.lng + '/home' }); - req.user.getUserCamps((camps)=>{ + req.user.getUserCamps((camps) => { // console.log(camps); - for (let i in camps) { - - } + // for (let i in camps) { + // + // } res.render('pages/home', { user: req.user, breadcrumbs: req.breadcrumbs() }); - },req,'all'); + }, req, 'all'); }); // ===================================== @@ -91,7 +91,7 @@ module.exports = function (app, passport) { errorMessage: req.flash('error') }); } else { - res.cookie('authToken', passportLib.generateJwtToken(req.body.email), {httpOnly: true, domain:'.midburn.org'}); + res.cookie('authToken', passportLib.generateJwtToken(req.body.email), { httpOnly: true, domain: '.midburn.org' }); var r = req.body['r']; if (r) { return res.redirect(r); @@ -146,10 +146,10 @@ module.exports = function (app, passport) { passportLib.login(req.body.email, req.body.password, function (result, user, error) { if (result && user) { var token = passportLib.generateJwtToken(req.body.email); - res.json({message: "ok", token: token}); + res.json({ message: "ok", token: token }); } else { - res.status(401).json({message: error}); + res.status(401).json({ message: error }); } }); }); @@ -242,10 +242,10 @@ module.exports = function (app, passport) { name: 'breadcrumbs.home', url: '/' + req.params.lng + '/home' }, - { - name: 'breadcrumbs.whoami', - url: '/' + req.params.lng + '/whoami' - }]); + { + name: 'breadcrumbs.whoami', + url: '/' + req.params.lng + '/whoami' + }]); /* TODO - camp fetching here is incorrect. * We don't have only one event with one camp! @@ -292,65 +292,65 @@ module.exports = function (app, passport) { var resetPasswordPost = function (req, res, next) { async.waterfall([ - function (done) { - new User({ - email: req.body.email + function (done) { + new User({ + email: req.body.email + }) + .fetch() + .then(function (model) { + if (model === null) { + return done(i18next.t('email_doesnt_exist_message')); + } + return done(null, model); + }); + }, + function (model, done) { + console.log("entering crypto"); + //TODO reuse or move logic into user.js + crypto.randomBytes(20, function (err, buf) { + var token = buf + .toString('base64') + .replace(/\+/g, '0') + .replace(/\//g, '0'); + console.log(token); + done(err, model, token); + }); + }, + function (model, token, done) { + model + .save({ + reset_password_token: token, + reset_password_expires: generateExpirationString() + }, { + patch: true }) - .fetch() - .then(function (model) { - if (model === null) { - return done(i18next.t('email_doesnt_exist_message')); - } - return done(null, model); - }); - }, - function (model, done) { - console.log("entering crypto"); - //TODO reuse or move logic into user.js - crypto.randomBytes(20, function (err, buf) { - var token = buf - .toString('base64') - .replace(/\+/g, '0') - .replace(/\//g, '0'); - console.log(token); - done(err, model, token); + .then(function (model) { + return done(null, model); }); - }, - function (model, token, done) { - model - .save({ - reset_password_token: token, - reset_password_expires: generateExpirationString() - }, { - patch: true - }) - .then(function (model) { - return done(null, model); - }); - //TODO catch Bookshelf exception here - }, - function (model, done) { - var link = - serverConfig.url + '/' + - req.params.lng + - "/confirm_password_reset/" + - model.attributes.reset_password_token; - - mail.send( - model.attributes.email, - mailConfig.from, - i18next.t('reset_password_email_subject'), - 'emails/reset_password', { //TODO - not exists! - name: model.fullName, - link: link - }); - - // return done(mailsent ? null : 'Error sending mail'); - //TODO motenko: mail.send ins't implemented for returning errors - //Fix mail.send to have idiomatic Node.js callback with error - return done(null); - } - ], + //TODO catch Bookshelf exception here + }, + function (model, done) { + var link = + serverConfig.url + '/' + + req.params.lng + + "/confirm_password_reset/" + + model.attributes.reset_password_token; + + mail.send( + model.attributes.email, + mailConfig.from, + i18next.t('reset_password_email_subject'), + 'emails/reset_password', { //TODO - not exists! + name: model.fullName, + link: link + }); + + // return done(mailsent ? null : 'Error sending mail'); + //TODO motenko: mail.send ins't implemented for returning errors + //Fix mail.send to have idiomatic Node.js callback with error + return done(null); + } + ], function (err) { if (err) { res.render('pages/reset_password', { @@ -374,7 +374,7 @@ module.exports = function (app, passport) { .fetch() .then(function (model) { if (model === null || - //no such token or token expired + //no such token or token expired (new Date(model.attributes.reset_password_expires)) .getTime() < Date.now()) { return res.render('pages/confirm_password_reset', { @@ -398,44 +398,44 @@ module.exports = function (app, passport) { } async.waterfall([ - function (done) { - new User({ - reset_password_token: req.params.token - }) - .fetch() - .then(function (model) { - if (model === null || - //no such token or token expired - (new Date(model.attributes.reset_password_expires)) - .getTime() < Date.now()) { - return done(i18next.t('bad_or_expired_token')); - } - return done(null, model); - }); - }, - function (model, done) { - //create new pasasword hash - model.generateHash(req.body.password); - - //invalidate token and expiration - model.attributes.reset_password_expires = null; - model.attributes.reset_password_token = null; - - model.save().then(function (model) { + function (done) { + new User({ + reset_password_token: req.params.token + }) + .fetch() + .then(function (model) { + if (model === null || + //no such token or token expired + (new Date(model.attributes.reset_password_expires)) + .getTime() < Date.now()) { + return done(i18next.t('bad_or_expired_token')); + } return done(null, model); }); - }, - function (model, done) { - mail.send( - model.attributes.email, - mailConfig.from, - i18next.t('password_changed_email_subject'), - 'emails/password_changed', { - name: model.fullName - }); - return done(null); - } - ], + }, + function (model, done) { + //create new pasasword hash + model.generateHash(req.body.password); + + //invalidate token and expiration + model.attributes.reset_password_expires = null; + model.attributes.reset_password_token = null; + + model.save().then(function (model) { + return done(null, model); + }); + }, + function (model, done) { + mail.send( + model.attributes.email, + mailConfig.from, + i18next.t('password_changed_email_subject'), + 'emails/password_changed', { + name: model.fullName + }); + return done(null); + } + ], function (err) { if (err) { res.render('pages/confirm_password_reset', { @@ -456,15 +456,15 @@ module.exports = function (app, passport) { new User({ email_validation_token: token }).fetch().then(function (user) { - if (user.validate()) { - user.save().then(function () { - res.render('pages/login', { - successMessage: i18next.t('email_verified') - }); + if (user.validate()) { + user.save().then(function () { + res.render('pages/login', { + successMessage: i18next.t('email_verified') }); - } else { - res.sendStatus(400); - } - }); + }); + } else { + res.sendStatus(400); + } + }); }); }; From e9805583b0b4f60c6dae15b6697c1a8ee2b197a2 Mon Sep 17 00:00:00 2001 From: Asaf Azulay Date: Sun, 21 May 2017 13:27:35 +0300 Subject: [PATCH 3/6] option to edit from home menu --- libs/common.js | 2 +- models/camp.js | 26 ++++++----- models/user.js | 6 +-- public/scripts/controllers/camp_edit.js | 41 ++++++++++------- routes/api_camps_routes.js | 44 ++++++++++++++---- routes/camps_routes.js | 15 ++++--- routes/main_routes.js | 6 --- views/pages/camps/index_admin.jade | 10 +++-- views/pages/home.jade | 60 +++++++++++++++++++++++++ 9 files changed, 152 insertions(+), 58 deletions(-) diff --git a/libs/common.js b/libs/common.js index 17c6359de..2edb5dacd 100644 --- a/libs/common.js +++ b/libs/common.js @@ -49,7 +49,7 @@ var functions = { if (filter.test(user_email)) { return user_email; } - } + }, } // Create the model and expose it diff --git a/models/camp.js b/models/camp.js index f92799a9e..249988b2b 100644 --- a/models/camp.js +++ b/models/camp.js @@ -6,6 +6,7 @@ var User = models.User; var UsersGroup = models.UsersGroup; const knex = require('../libs/db').knex; + var Camp = bookshelf.Model.extend({ tableName: constants.CAMPS_TABLE_NAME, idAttribute: 'id', @@ -34,8 +35,7 @@ var Camp = bookshelf.Model.extend({ // let _camps_members = constants.CAMP_MEMBERS_TABLE_NAME; // let _users = constants.USERS_TABLE_NAME; -//,SUM(tickets.inside_event) AS inside_event - let query="SELECT users.*,camp_members.status AS member_status,SUM(IF(tickets.ticket_id>0,1,0)) AS ticket_count,SUM(tickets.inside_event) AS inside_event FROM users inner join camp_members on users.user_id=camp_members.user_id left join tickets on tickets.holder_id=users.user_id and tickets.event_id='MIDBURN2017' where camp_members.camp_id="+this.attributes.id+" group by users.user_id"; + let query = "SELECT users.*,camp_members.status AS member_status,SUM(IF(tickets.ticket_id>0,1,0)) AS ticket_count,SUM(tickets.inside_event) AS inside_event FROM users inner join camp_members on users.user_id=camp_members.user_id left join tickets on tickets.holder_id=users.user_id and tickets.event_id='MIDBURN2017' where camp_members.camp_id=" + this.attributes.id + " group by users.user_id"; return knex //(_users) .raw(query) // .select(_users + '.*', _camps_members + '.status AS member_status'/*,'tickets.ticket_id'*/) @@ -44,12 +44,10 @@ var Camp = bookshelf.Model.extend({ // .leftjoin('tickets','tickets.holder_id','users.user_id') // .where({ 'camp_members.camp_id': this.attributes.id }) .then((users_raw_data) => { - let users=users_raw_data[0]; - // console.log(users); + let users = users_raw_data[0]; let managers = []; // let emails for (let i in users) { - // console.log(i); users[i].isManager = false; if (['open', 'closed'].indexOf(_this.attributes.status) === -1) { users[i].member_status = 'deleted'; @@ -116,21 +114,21 @@ var Camp = bookshelf.Model.extend({ this.attributes.camp_desc_en_linkify = common.linkify(this.attributes.camp_desc_en); } }, - __parsePrototype: function (prototype, user) { + __parsePrototype: function(prototype, user) { let result = constants.prototype_camps.by_prototype(prototype); if (!result) return false; let isAdmin = false; let t_prefix = ''; if (user instanceof User) { isAdmin = user.isAdmin; - if (this.attributes.__prototype === constants.prototype_camps.THEME_CAMP.id) { - isAdmin = isAdmin || req.user.isCampsAdmin; + if (prototype === constants.prototype_camps.THEME_CAMP.id) { + isAdmin = isAdmin || user.isCampsAdmin; t_prefix = 'camps:'; - } else if (this.attributes.__prototype === constants.prototype_camps.ART_INSTALLATION.id) { - isAdmin = isAdmin || req.user.isArtInstallationsAdmin; + } else if (prototype === constants.prototype_camps.ART_INSTALLATION.id) { + isAdmin = isAdmin || user.isArtInstallationsAdmin; t_prefix = 'camps:art_installation.'; - } else if (this.attributes.__prototype === constants.prototype_camps.PROD_DEP.id) { - isAdmin = isAdmin || req.user.isProdDepsAdmin; + } else if (prototype === constants.prototype_camps.PROD_DEP.id) { + isAdmin = isAdmin || user.isProdDepsAdmin; t_prefix = 'camps:prod_dep.'; } } @@ -138,6 +136,10 @@ var Camp = bookshelf.Model.extend({ result.t_prefix = t_prefix; return result; }, + + parsePrototype: function (user) { + return this.__parsePrototype(this.attributes.__prototype, user); + }, virtuals: { managers: function () { return this.attributes.managers; diff --git a/models/user.js b/models/user.js index 7e0abd6c5..ef40f40db 100644 --- a/models/user.js +++ b/models/user.js @@ -104,9 +104,6 @@ var User = bookshelf.Model.extend({ } if (req && typeof (req) === 'object' && typeof (req['t']) === 'function') { t = req.t; - // if (req['user']) { - // _current_user = req.user; - // } } var _camps_members = constants.CAMP_MEMBERS_TABLE_NAME; var _camps = constants.CAMPS_TABLE_NAME; @@ -117,7 +114,6 @@ var User = bookshelf.Model.extend({ 'camps.event_id': constants.CURRENT_EVENT_ID, }; if (prototype!=='all') _where['__prototype']=prototype; - console.log(_where); knex(_camps) .select(_camps + '.*', _camps_members + '.status AS member_status', 'users_groups.entrance_quota') .innerJoin(_camps_members, _camps + '.id', _camps_members + '.camp_id') @@ -140,7 +136,7 @@ var User = bookshelf.Model.extend({ || (camps[i].member_status === 'approved_mgr'))) { first_camp = camps[i]; is_manager = true; - break; + // break; } } _this_user.attributes.camps = camps; diff --git a/public/scripts/controllers/camp_edit.js b/public/scripts/controllers/camp_edit.js index 99f4dedd3..7bae822c6 100644 --- a/public/scripts/controllers/camp_edit.js +++ b/public/scripts/controllers/camp_edit.js @@ -18,8 +18,8 @@ var angular_getMembers = function ($http, $scope, camp_id) { if (['approved', 'approved_mgr'].indexOf(members[i].member_status) > -1) { approved_members.push(members[i]); } - total_in_event+=parseInt(members[i].inside_event); - total_camp_tickets+=parseInt(members[i].ticket_count) || 0; + total_in_event += parseInt(members[i].inside_event); + total_camp_tickets += parseInt(members[i].ticket_count) || 0; } $scope.members = _members; $scope.approved_members = approved_members; @@ -37,7 +37,7 @@ var angular_updateUser = function ($http, $scope, action_type, user_rec) { if (lang === undefined) { lang = 'he'; } - var tpl,action_tpl; + var tpl, action_tpl; if (lang === "he") { // debugger; @@ -100,23 +100,23 @@ app.controller("campEditController", ($scope, $http, $filter) => { } if (lang === "he") { $scope.status_options = [ - {id:'open',value:'מחנה פתוח למצטרפים חדשים'}, - {id:'closed',value:'סגור למצטרפים חדשים'}]; + { id: 'open', value: 'מחנה פתוח למצטרפים חדשים' }, + { id: 'closed', value: 'סגור למצטרפים חדשים' }]; $scope.noise_level_options = [ - {id:'quiet',value:'שקט'}, - {id:'medium',value:'בינוני'}, - {id:'noisy',value:'רועש'}, - {id:'very noisy',value:'מאוד רועש'} ]; + { id: 'quiet', value: 'שקט' }, + { id: 'medium', value: 'בינוני' }, + { id: 'noisy', value: 'רועש' }, + { id: 'very noisy', value: 'מאוד רועש' }]; } else { $scope.status_options = ['Opened to new member', 'Closed to new members']; $scope.status_options = [ - {id:'open',value:'Opened to new member'}, - {id:'closed',value:'Closed to new members'}]; + { id: 'open', value: 'Opened to new member' }, + { id: 'closed', value: 'Closed to new members' }]; $scope.noise_level_options = [ - {id:'quiet',value:'Quiet'}, - {id:'medium',value:'Medium'}, - {id:'noisy',value:'Noisy'}, - {id:'very noisy',value:'Very Noisy'} ]; + { id: 'quiet', value: 'Quiet' }, + { id: 'medium', value: 'Medium' }, + { id: 'noisy', value: 'Noisy' }, + { id: 'very noisy', value: 'Very Noisy' }]; } $scope.getMembers = () => { @@ -144,7 +144,7 @@ app.controller("campEditController", ($scope, $http, $filter) => { $http.post(`/camps/${camp_id}/members/add`, data).then(function (res) { // update table with new data $scope.getMembers(); - $scope.camps_members_add_member=''; + $scope.camps_members_add_member = ''; }).catch((err) => { sweetAlert("Error!", "Add new member error: " + err.data.data.message, "error"); }); @@ -158,5 +158,14 @@ app.controller("campEditController", ($scope, $http, $filter) => { } angular_updateUser($http, $scope, action_type, user_rec); } +}); +app.controller("homeController", ($scope, $http, $filter) => { + $scope.angular_getMyGroups = function ($http, $scope) { + $http.get(`/my_groups`).then((res) => { + // debugger; + $scope.groups = res.data.groups; + }); + } + $scope.angular_getMyGroups($http, $scope); }); diff --git a/routes/api_camps_routes.js b/routes/api_camps_routes.js index 31bafe3c1..e288b43c8 100644 --- a/routes/api_camps_routes.js +++ b/routes/api_camps_routes.js @@ -35,8 +35,7 @@ var __camps_update_status = (camp_id, user_id, action, camp_mgr, res) => { } else { camp_mgr_id = parseInt(camp_mgr); } - group_options = camp.__parsePrototype(camp.attributes.__prototype, camp_mgr); - console.log(group_options); + group_options = camp.parsePrototype(camp_mgr); let isAdmin = group_options.isAdmin; console.log(action + " from camp " + camp_id + " of user " + user_id + " / mgr id: " + camp_mgr_id); @@ -224,10 +223,7 @@ module.exports = (app, passport) => { } else if (typeof (camp) === 'string' && camp !== '') { prototype = camp; } else prototype = constants.prototype_camps.THEME_CAMP.id; - - group_props = Camp.forge().__parsePrototype(prototype, req.user); - - // group_props=camp.__parsePrototype(camp.attribu)} + group_props = Camp.prototype.__parsePrototype(prototype, req.user); var data = { event_id: constants.CURRENT_EVENT_ID, // for update or insert, need to merge with create to be the same call @@ -424,7 +420,7 @@ module.exports = (app, passport) => { .fetch({ withRelated: ['users_groups'] }) .then((camp) => { camp.getCampUsers((users) => { - group_props = camp.__parsePrototype(camp.attributes.__prototype, req.user); + group_props = camp.parsePrototype(req.user); if (camp.isCampManager(req.user.attributes.user_id) || group_props.isAdmin) { __camps_save(req, false, camp) // Camp.forge({ id: req.params.id }).fetch().then((camp) => { @@ -874,7 +870,7 @@ module.exports = (app, passport) => { return member; }); } - result = camp.__parsePrototype(camp.attributes.__prototype, req.user); + result = camp.parsePrototype(req.user); if (isCampManager || (result && result.isAdmin)) { res.status(200).json({ members: members }); @@ -896,6 +892,36 @@ module.exports = (app, passport) => { }); }); + app.get('/my_groups',userRole.isLoggedIn(), (req, res) => { + req.user.getUserCamps((camps) => { + let groups=[]; + let group={}; + let group_props; + // console.log(camps); + for (let i in camps) { + group_props=Camp.prototype.__parsePrototype(camps[i].__prototype,req.user); + if (['approved','pending','pending_mgr','approved_mgr'].indexOf(camps[i].member_status)>-1) { + group={ + // group_type:'מחנה נושא', + group_id: camps[i].id, + group_type: req.t(group_props.t_prefix+'edit.camp'), + member_status: camps[i].member_status, + member_status_i18n: camps[i].member_status_i18n, + camp_desc_i18n: camps[i].camp_name_he, + camp_desc_he: camps[i].camp_name_he, + camp_name_en: camps[i].camp_name_en, + can_view: ['theme_camp'].indexOf(camps[i].__prototype)>-1, + can_edit: camps[i].isManager, + is_manager_i18n: camps[i].isManager?req.t('camps:yes'):req.t('camps:no'), + }; + groups.push(group); + } + } + // console.log(groups); + res.status(200).json({ groups: groups }); + }, req, 'all'); + }); + /** * API: (POST) camp manager send member join request * request => /camps/1/members/add @@ -913,7 +939,7 @@ module.exports = (app, passport) => { return; } req.user.getUserCamps((camps) => { - let group_props = camp.__parsePrototype(camp.attributes.__prototype, req.user); + let group_props = camp.parsePrototype(req.user); if (req.user.isManagerOfCamp(camp_id) || group_props.isAdmin) { User.forge({ email: user_email }).fetch().then((user) => { if (user !== null) { diff --git a/routes/camps_routes.js b/routes/camps_routes.js index 28e31eb1a..7ddb74425 100644 --- a/routes/camps_routes.js +++ b/routes/camps_routes.js @@ -1,3 +1,4 @@ +const common = require('../libs/common').common; const userRole = require('../libs/user_role'); const constants = require('../models/constants.js'); var Camp = require('../models/camp').Camp; @@ -120,7 +121,7 @@ module.exports = function (app, passport) { }]); let prototype = constants.prototype_camps.THEME_CAMP.id; - let result = Camp.__parsePrototype(prototype, req.user); + let result = Camp.prototype.__parsePrototype(prototype, req.user); res.render('pages/camps/edit', { user: req.user, camp_name_en: req.query.c, @@ -158,7 +159,7 @@ module.exports = function (app, passport) { }).then((camp) => { req.user.getUserCamps((camps) => { // let __groups_prototype=''; - let result = camp.__parsePrototype(camp.attributes.__prototype, req.user); + let result = camp.parsePrototype(req.user); if (req.user.isManagerOfCamp(req.params.id) || result.isAdmin) { let camp_data = __camp_data_to_json(camp); if (camp_data.addinfo_json !== null) { @@ -262,7 +263,8 @@ module.exports = function (app, passport) { user: req.user, breadcrumbs: req.breadcrumbs(), __groups_prototype: 'theme_camps', - t_prefix: 'camps:' + t_prefix: 'camps:', + isCamp: true, }); } else { // user not admin @@ -288,7 +290,8 @@ module.exports = function (app, passport) { user: req.user, breadcrumbs: req.breadcrumbs(), __groups_prototype: 'art_installation', - t_prefix: 'camps:art_installation.' + t_prefix: 'camps:art_installation.', + isArt: true, }); } else { // user not admin @@ -313,7 +316,9 @@ module.exports = function (app, passport) { user: req.user, breadcrumbs: req.breadcrumbs(), __groups_prototype: 'prod_dep', - t_prefix: 'camps:prod_dep.' + t_prefix: 'camps:prod_dep.', + isProd: true, + }); } else { // user not admin diff --git a/routes/main_routes.js b/routes/main_routes.js index 26c24683d..eb30ecc08 100644 --- a/routes/main_routes.js +++ b/routes/main_routes.js @@ -49,16 +49,10 @@ module.exports = function (app, passport) { name: 'breadcrumbs.home', url: '/' + req.params.lng + '/home' }); - req.user.getUserCamps((camps) => { - // console.log(camps); - // for (let i in camps) { - // - // } res.render('pages/home', { user: req.user, breadcrumbs: req.breadcrumbs() }); - }, req, 'all'); }); // ===================================== diff --git a/views/pages/camps/index_admin.jade b/views/pages/camps/index_admin.jade index e55ab33b4..f47348edb 100644 --- a/views/pages/camps/index_admin.jade +++ b/views/pages/camps/index_admin.jade @@ -12,10 +12,12 @@ block content div.input-group a.Btn.Btn__default.card-switcher#1(href=`/${language}/camps-admin/manage`, role='button')=t(t_prefix+'admin_index.all_camps') a.Btn.Btn__transparent.card-switcher#2(href=`/${language}/camps-admin/members`, role='button')=t(t_prefix+'admin_index.all_members') - a.Btn.Btn__transparent.card-switcher#3(href=`/${language}/camps-admin/docs`, role='button')=t(t_prefix+'admin_index.docs') - a.Btn.Btn__green.card-switcher#4(href=`/${language}/camps-admin/new`, role='button') - span.glyphicon.glyphicon-plus(aria-hidden="true") - span=t(t_prefix+'admin_index.new') + if isCamp + a.Btn.Btn__transparent.card-switcher#3(href=`/${language}/camps-admin/docs`, role='button')=t(t_prefix+'admin_index.docs') + if isCamp + a.Btn.Btn__green.card-switcher#4(href=`/${language}/camps-admin/new`, role='button') + span.glyphicon.glyphicon-plus(aria-hidden="true") + span=t(t_prefix+'admin_index.new') .cards--wrapper.card__shad //- Card 1 diff --git a/views/pages/home.jade b/views/pages/home.jade index 3d3ae59d4..3d45bcd51 100644 --- a/views/pages/home.jade +++ b/views/pages/home.jade @@ -1,3 +1,63 @@ extends ../includes/page block content h1=t('welcome_home', {user: user.attributes.first_name, context: user.attributes.gender}) + .camps.camp_edit(ng-app="ngCamps", ng-controller="homeController") + br + h4 המידברן שלי + table.table.table-striped.table-hover + thead + tr + th(ng-click='changeOrderBy("id")') # + th(ng-click='changeOrderBy("name")') סוג הקבוצה + th(ng-click='changeOrderBy("email")') שם הקבוצה + th(ng-click='changeOrderBy("cell_phone")') סטאטוס + th() מנהל + th()=t('camps:members.actions') + //- th(ng-click='changeOrderBy("member_status_i18n")') פעולות + //- th(ng-click='changeOrderBy("ticket_count")') + //- th(ng-click='changeOrderBy("inside_event")') + tbody + tr(ng-repeat="group in groups ") + td {{group.user_id}} + td {{group.group_type}} + td {{group.camp_desc_i18n}} + td {{group.member_status_i18n}} + td {{group.is_manager}} + //- td {{group.earlyArrival ? 'yes':'no'}} + td + a.cursor-p(ng-href=`/${language}/camps/{{group.group_id}}` + '/edit' ng-if="group.can_edit")  + button.btn.btn-xs + span(class='glyphicon glyphicon-pencil') + =t('camps:stats.edit') + a.cursor-p(ng-href=`/${language}/camps/{{group.group_id}}` ng-if="group.can_view")  + button.btn.btn-xs + span(class='glyphicon glyphicon-pencil') + =t('camps:edit.view') + + //- a.cursor-p(ng-click='updateUser(group.name, group.user_id, "reject")', ng-if="group.can_reject")   + //- button.btn.btn-xs + //- span(class='glyphicon glyphicon-remove') + //- =t('camps:groups.reject') + //- a.cursor-p(ng-click='updateUser(group.name, group.user_id, "approve")', ng-if="group.can_approve")   + //- button.btn.btn-xs + //- span(class='glyphicon glyphicon-ok') + //- =t('camps:groups.approve') + //- a.cursor-p(ng-click='updateUser(group.name, group.user_id, "approve_mgr")', ng-if="group.can_approve_mgr")   + //- button.btn.btn-xs + //- span(class='glyphicon glyphicon-king') + //- =t('camps:groups.approve_as_manager') + //- a.cursor-p(ng-click='updateUser(group.name, group.user_id, "remove_mgr")', ng-if="group.can_remove_mgr")   + //- button.btn.btn-xs + //- span(class='glyphicon glyphicon-king') + //- =t('camps:groups.remove_manager') + //- a.cursor-p(ng-click='updateUser(group.name, group.user_id, "remove")', ng-if="group.can_remove")   + //- button.btn.btn-xs + //- span(class='glyphicon glyphicon-remove') + //- =t('camps:groups.remove') + //- .col-xs-6 + h4=t('camps:admin_index.total_approved_groups') + span.badge {{all_approved_members}} + //- .col-xs-6 + h4=t('camps:admin_index.total_camp_tickets') + span.badge {{total_camp_tickets}} + From 8fe4709682d02e22acbb0c4cf915dde7163c5fcd Mon Sep 17 00:00:00 2001 From: Asaf Azulay Date: Sun, 21 May 2017 15:16:49 +0300 Subject: [PATCH 4/6] lint --- models/camp.js | 10 ---------- routes/camps_routes.js | 1 - 2 files changed, 11 deletions(-) diff --git a/models/camp.js b/models/camp.js index 1d2061de8..b07716673 100644 --- a/models/camp.js +++ b/models/camp.js @@ -35,12 +35,7 @@ var Camp = bookshelf.Model.extend({ // let _camps_members = constants.CAMP_MEMBERS_TABLE_NAME; // let _users = constants.USERS_TABLE_NAME; -<<<<<<< HEAD let query = "SELECT users.*,camp_members.status AS member_status,SUM(IF(tickets.ticket_id>0,1,0)) AS ticket_count,SUM(tickets.inside_event) AS inside_event FROM users inner join camp_members on users.user_id=camp_members.user_id left join tickets on tickets.holder_id=users.user_id and tickets.event_id='MIDBURN2017' where camp_members.camp_id=" + this.attributes.id + " group by users.user_id"; -======= -//,SUM(tickets.inside_event) AS inside_event - let query="SELECT users.*,camp_members.status AS member_status,SUM(IF(tickets.ticket_id>0,1,0)) AS ticket_count,SUM(tickets.inside_event) AS inside_event FROM users inner join camp_members on users.user_id=camp_members.user_id left join tickets on tickets.holder_id=users.user_id and tickets.event_id='MIDBURN2017' where camp_members.camp_id="+this.attributes.id+" group by users.user_id"; ->>>>>>> 46a4aa6869a92cbda068e8fe5755a4c1eab38705 return knex //(_users) .raw(query) // .select(_users + '.*', _camps_members + '.status AS member_status'/*,'tickets.ticket_id'*/) @@ -49,12 +44,7 @@ var Camp = bookshelf.Model.extend({ // .leftjoin('tickets','tickets.holder_id','users.user_id') // .where({ 'camp_members.camp_id': this.attributes.id }) .then((users_raw_data) => { -<<<<<<< HEAD let users = users_raw_data[0]; -======= - let users=users_raw_data[0]; - // console.log(users); ->>>>>>> 46a4aa6869a92cbda068e8fe5755a4c1eab38705 let managers = []; // let emails for (let i in users) { diff --git a/routes/camps_routes.js b/routes/camps_routes.js index 7ddb74425..7bfbc8069 100644 --- a/routes/camps_routes.js +++ b/routes/camps_routes.js @@ -1,4 +1,3 @@ -const common = require('../libs/common').common; const userRole = require('../libs/user_role'); const constants = require('../models/constants.js'); var Camp = require('../models/camp').Camp; From bd05c51bd9d576ba351943ec7a2bec9628a5e1d4 Mon Sep 17 00:00:00 2001 From: Asaf Azulay Date: Sun, 21 May 2017 15:29:38 +0300 Subject: [PATCH 5/6] lint --- models/camp.js | 1 - 1 file changed, 1 deletion(-) diff --git a/models/camp.js b/models/camp.js index b07716673..a55bd7cc2 100644 --- a/models/camp.js +++ b/models/camp.js @@ -6,7 +6,6 @@ var User = models.User; var UsersGroup = models.UsersGroup; const knex = require('../libs/db').knex; - var Camp = bookshelf.Model.extend({ tableName: constants.CAMPS_TABLE_NAME, idAttribute: 'id', From fb477c5e23d298a81919480ba4b03f038637f408 Mon Sep 17 00:00:00 2001 From: Leon Fedotov Date: Sun, 21 May 2017 15:35:26 +0300 Subject: [PATCH 6/6] version v2.6.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a72ef3dc6..c4a281bf6 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "this is part of the deployment proess, so it is important to update the version number", "version name corresponds to the github release name / tag name - https://github.com/Midburn/Spark/releases" ], - "version": "2.6.0", + "version": "2.6.1", "private": true, "scripts": { "postinstall": "bower install",