Initial commit. Modified the Meteor todos app to create the Petit Teton data tracking app. Has working data for sales. Requires a Mongo database.
This commit is contained in:
178
imports/ui/UserManagement.js
Normal file
178
imports/ui/UserManagement.js
Normal file
@@ -0,0 +1,178 @@
|
||||
|
||||
import './UserManagement.html';
|
||||
import '/imports/util/selectize/selectize.js'
|
||||
|
||||
Tracker.autorun(function() {
|
||||
Meteor.subscribe("users", Session.get('searchQuery'));
|
||||
Meteor.subscribe("roles");
|
||||
});
|
||||
|
||||
Template.UserManagement.helpers({
|
||||
users: function() {
|
||||
return Meteor.collections.Users.find({}, {sort: {username: 1}});
|
||||
}
|
||||
});
|
||||
|
||||
Template.User.onCreated(function() {
|
||||
this.edited = new ReactiveVar();
|
||||
});
|
||||
Template.User.events({
|
||||
"click .userEdit": function(event, template) {
|
||||
template.edited.set(this);
|
||||
},
|
||||
"click .userRemove": function(event, template) {
|
||||
let _this = this;
|
||||
bootbox.confirm({
|
||||
message: "Delete the user?",
|
||||
buttons: {confirm: {label: "Yes", className: 'btn-success'}, cancel: {label: "No", className: "btn-danger"}},
|
||||
callback: function(result) {
|
||||
if(result) {
|
||||
Meteor.call('deleteUser', _this._id, function(error, result) {
|
||||
if(error) {
|
||||
sAlert.error(error);
|
||||
}
|
||||
else {
|
||||
sAlert.success("User removed.");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
"click .editorCancel": function(event, template) {
|
||||
template.edited.set(undefined);
|
||||
},
|
||||
"click .editorApply": function(event, template) {
|
||||
let username = template.$("input[name='username']").val().trim();
|
||||
let email = template.$("input[name='email']").val().trim();
|
||||
let roleSpans = template.$(".roles > span");
|
||||
let roles = [];
|
||||
|
||||
for(let i = 0; i < roleSpans.length; i++) {
|
||||
if($(roleSpans[i]).hasClass("selected")) {
|
||||
roles.push($(roleSpans[i]).text());
|
||||
}
|
||||
}
|
||||
|
||||
//Basic validation.
|
||||
if(username && username.length > 0 && email && email.length > 0) {
|
||||
let emails = _.clone(this.emails);
|
||||
|
||||
if(!emails || emails.length == 0) {
|
||||
emails = [{address: email, verified: true}];
|
||||
}
|
||||
else {
|
||||
emails[0].address = email;
|
||||
emails[0].verified = true;
|
||||
}
|
||||
|
||||
Meteor.call("updateUser", {_id: this._id, username: username, emails: emails, roles: roles}, function(error, result) {
|
||||
if(error) {
|
||||
sAlert.error(error);
|
||||
}
|
||||
else {
|
||||
sAlert.success("User updated.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
template.edited.set(undefined);
|
||||
},
|
||||
"click .role": function(event, template) {
|
||||
$(event.target).toggleClass("selected");
|
||||
}
|
||||
});
|
||||
Template.User.helpers({
|
||||
email: function() {
|
||||
return this.emails && this.emails.length > 0 ? this.emails[0].address : "";
|
||||
},
|
||||
editing: function() {
|
||||
return Template.instance().edited.get() == this;
|
||||
},
|
||||
allRoles: function() {
|
||||
return Meteor.collections.UserRoles.find();
|
||||
},
|
||||
getRoleState: function(role) {
|
||||
let user = Template.parentData(1);
|
||||
|
||||
return user.roles.includes(role.name) ? "selected" : "";
|
||||
}
|
||||
});
|
||||
|
||||
Template.UserSearch.events({
|
||||
"keyup .searchInput": _.throttle(function(event, template) {
|
||||
let searchQuery = Session.get('searchQuery') || {};
|
||||
let searchFields = Session.get('searchFields') || {};
|
||||
let searchValue = template.$('.searchInput').val();
|
||||
|
||||
if(searchValue) {
|
||||
if(this.number) searchValue = parseFloat(searchValue);
|
||||
|
||||
if(this.collection) {
|
||||
let ids = Meteor.collections[this.collection].find({[this.collectionQueryColumnName]: {$regex: searchValue, $options: 'i'}}, {fields: {[this.collectionResultColumnName]: 1}}).fetch();
|
||||
|
||||
//Convert the ids to an array of ids instead of an array of objects containing an id.
|
||||
for(let i = 0; i < ids.length; i++) {ids[i] = ids[i]._id;}
|
||||
searchQuery[this.columnName] = {$in: ids};
|
||||
searchFields[this.columnName] = searchValue;
|
||||
}
|
||||
else {
|
||||
searchFields[this.columnName] = searchQuery[this.columnName] = searchValue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//Remove columns from the search query whose values are empty so we don't bother the database with them.
|
||||
delete searchQuery[this.columnName];
|
||||
delete searchFields[this.columnName];
|
||||
}
|
||||
|
||||
Session.set('searchQuery', searchQuery);
|
||||
}, 500)
|
||||
});
|
||||
Template.UserSearch.helpers({
|
||||
searchValue: function() {
|
||||
let searchFields = Session.get('searchFields');
|
||||
|
||||
return (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : '';
|
||||
}
|
||||
});
|
||||
|
||||
Template.UserInsert.onRendered(function() {
|
||||
this.$('form[name="insert"]').validator();
|
||||
});
|
||||
Template.UserInsert.events({
|
||||
'click input[type="submit"]': function(event, template) {
|
||||
event.preventDefault();
|
||||
template.$('form[name="insert"]').data('bs.validator').validate(function(isValid) {
|
||||
if(isValid) {
|
||||
let user = {};
|
||||
let roles = [];
|
||||
|
||||
user.username = template.$('input[name="username"]').val();
|
||||
user.email = template.$('input[name="email"]').val();
|
||||
|
||||
let roleSpans = template.$('.role.selected');
|
||||
for(let i = 0; i < roleSpans.length; i++) {
|
||||
roles.push($(roleSpans[i]).text());
|
||||
}
|
||||
|
||||
Meteor.call('insertUser', user, roles, function(error, result) {
|
||||
if(error) {
|
||||
sAlert.error(error);
|
||||
}
|
||||
else {
|
||||
sAlert.success("User created.");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
"click .role": function(event, template) {
|
||||
$(event.target).toggleClass("selected");
|
||||
}
|
||||
});
|
||||
Template.UserInsert.helpers({
|
||||
allRoles: function() {
|
||||
return Meteor.collections.UserRoles.find();
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user